Object Storage(sdt-migration)
Object Storage(sdt-migration)
개요
이 페이지는 Object Storage의 Live Migration에서 제공하는 API 또는 CLI를 사용하여 Live Migration을 수행하는 방법에 대한 가이드 입니다. Live Migration이란 소스 스토리지에서 타겟 스토리지로의 기존 데이터의 전송 뿐만 아니라 실시간으로 추가되는 데이터의 변화를 전송함으로써 데이터의 무결성 및 정합성을 확보하는 기술입니다.
Live Migration 프로세스
Full Migration
Full Migration은 마이그레이션을 요청하게 되면 먼저 기존 데이터를 전송하는 과정으로 다음과 같은 네가지 세부 과정으로 나뉘어 집니다.
- Data Crawling: 출발지 버킷으로부터 데이터의 정보를 조회하는 과정입니다.
- Data Analysis: 출발지 버킷에서 조회한 정보를 바탕으로 데이터를 분석하는 과정입니다.
- Migration Scheduling: 데이터 분석을 바탕으로 버킷의 하위 디렉토리 단위로 데이터 전송의 스케쥴링을 하는 과정입니다.
- Execute Migration: 스케쥴 순서에 따라 디렉토리 단위로 실제로 데이터가 전송되는 과정입니다.
Incremental Migration
Incremental Migration은 Full Migration으로 기존 데이터의 전송이 완료된 후 실행되는 과정으로 마이그레이션 도중 발생하는 데이터의 변경 사항을 전송하는 과정입니다. Live Migration에서 제공하는 종료 API로 마이그레이션을 종료하기 전까지 이 과정은 지속됩니다.
Migration State
Live Migration에서 제공하는 마이그레이션 진행 상태 정보 조회 API를 실행하였을 때 state에 표기되는 내용은 다음과 같습니다.
| State | Description |
|---|---|
| WAITING | 마이그레이션 요청이 되었으나 대기 중인 상태 |
| FULL-INPROGRESS | Full Migration이 진행 중인 상태 |
| INCR-INPROGRESS | Incremental Migration이 진행 중인 상태 |
| FINISHED | Incremental Migration이 종료된 상태 |
| DELETED | 마이그레이션이 삭제된 상태 |
| FAILED | 마이그레이션 도중 에러가 발생하여 실패된 상태 |
마이그레이션 정보 조회 API를 실행하면 더 자세한 정보를 얻을 수 있습니다. 이 때, 표기되는 targets.state에 표기되는 내용은 다음과 같습니다.
| State | Description |
|---|---|
| WAITING | 마이그레이션 요청이 되었으나 대기 중인 상태 |
| COLLECTING | 소스 버킷으로부터 데이터의 정보를 조회 중인 상태 |
| ANALYZING | 소스 버킷에서 조회한 정보를 바탕으로 데이터를 분석 중인 상태 |
| ANALYZED | 소스 버킷에서 조회한 정보를 바탕으로 데이터 분석이 완료 된 상태 |
| TRANSFERRING | 기존 데이터를 전송 중인 상태 |
| TRANSFERRED | Full Migration이 완료된 상태 |
| INCR-INPROGRESS | Incremental Migration이 진행 중인 상태 |
| FINISHED | Incremental Migration이 종료된 상태 |
| DELETED | 마이그레이션이 삭제된 상태 |
| FAILED | 마이그레이션 도중 에러가 발생하여 실패된 상태 |
Migration state와 targest state의 관계는 다음과 같습니다.
제약 사항
마이그레이션을 수행하기 위한 제약 사항들에 대한 설명입니다. 마이그레이션 수행 사전에 반드시 숙지하시길 바랍니다.
1. 타겟 버킷 생성 및 전송 제한
타겟 버킷의 경우 미리 생성되어 있어야 하며 소스 버킷의 버저닝 또는 암호화 옵션과 동일하게 적용하도록 합니다.
또한, 타겟 버킷에는 마이그레이션 실행 이전에 어떠한 데이터도 존재하면 안되며 Live Migration을 제외한 다른 경로에 의한 데이터 변경이 이루어져서는 안됩니다. 이는 마이그레이션의 데이터 정합성에 문제를 유발할 수 있습니다.
2. Delete Marker의 전송 제한
Delete Marker의 삭제는 전송이 되지 않습니다. 따라서 마이그레이션 도중에 소스 버킷의 Delete Marker의 삭제는 제한되어야 합니다.
스토리지의 버저닝 버킷의 오브젝트의 첫 버전이 Delete Marker 일 수 있습니다. 이 경우, 타겟 버킷에는 해당 Delete Marker는 전송되지 않습니다. Delete Marker보다 앞 버전들 중에 Delete Marker가 아닌 버전이 하나 이상 존재하는 경우에만 전송이 가능합니다.
3. 암호화 데이터의 전송
마이그레이션 요청 시 입력하는 암호화 키는 버킷 단위로 입력이 가능합니다. 입력한 암호화 키와 동일한 키를 사용하는 데이터만 전송이 가능합니다. 따라서 해당 버킷의 데이터들은 모두 동일한 키를 사용하여 암호화되어 있어야만 합니다. 암호화되어 있지 않은 데이터의 경우에도 전송이 되지 않을 수 있습니다.
만약 입력한 암호화 키와 다른 키를 사용(또는 암호화 되어 있지 않은) 오브젝트가 버킷에 있는 경우 마이그레이션은 실패할 수 있습니다.
소스 버킷이 암호화되어 있는 경우 소스 암호화 정보는 필수로 입력해야 하지만 타겟 버킷의 암호화 정보는 입력하지 않아도 됩니다. 타겟 버킷의 암호화 정보를 입력하지 않을 경우, 암호화되지 않은 상태로 타겟 버킷으로 저장됩니다.
4. 동일 소스 동시 수행 불가
동일 소스 버킷에 대한 마이그레이션은 동시에 하나만 가능합니다. 같은 소스 버킷에 대한 마이그레이션이 이미 실행 중인 경우에 “Migration’s registered already. Check ‘mig_xxx’!“의 에러 메시지가 송출됩니다. 이 경우, 해당 마이그레이션을 삭제 후에 실행 가능합니다.
5. 버전 삭제
버저닝 버킷의 오브젝트의 특정 버전의 삭제는 전송되지 않습니다. 마이그레이션 도중의 버전 삭제는 제한되어야 합니다.
사전작업
SDT Migration 모듈 설치
Requirement
사전 준비 사항
- K8s Cluster
- bastion 서버에 kubectl, helm이 사전 설치되어 있어야 합니다.
- bastion 서버에서 K8s cluster 접속 확인. 필요시 security group 설정을 추가해야 합니다.
- sdt-migration 설치 위치에 따라 Object storage에 접속하기 위한 VPC endpoint 배포 및 사전 설정이 필요합니다. (본 가이드는 v2 설치를 기준으로 합니다)
- std-migration 에서 사용하는 Container image는 설치하려는 K8s Clsuter가 접속 가능한 SCR에 등록되어 있어야 합니다.
- sdt-migration(sdt-migration.tar.gz) 설치 파일이 있어야 합니다.
- 인터넷 접속이 차단된 Private network에서 설치를 수행합니다.
- sdt-migration 설치 파일을 압축을 해제 합니다.
tar xvf sdt-migration.tar.gz
rabbitmq operator
values.yaml 파일 준비
rabbitmq의 values.yaml파일을 복사하여 수정합니다.
cp ./sdt-migration/environments/standalone/tools/rabbitmq-cluster-operator-values.yaml .
| Variables | 예시 | 비고 |
|---|---|---|
| imagepull_secretname | scr-migration | SCR에서 image pull을 위해 생성할 secret name |
| registry_endpoint | migration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.com | sdt-migration의 container image가 있는 SCR private endpoint |
| registry_username | username | username(access key) |
| registry_password | password | password(secret key) |
| registry_email | scp@samsung.com | |
| repository | "" | v1에 설치할 경우 “”, v2에 설치할 경우 repository |
# ------------------------------------------------------------------------------
# ENABLED COMPONENTS (tags)
# ------------------------------------------------------------------------------
tags:
rabbitmq-cluster-operator: true
# ------------------------------------------------------------------------------
# SCR CREDENTIALS
# ------------------------------------------------------------------------------
imageCredentials:
secretName: <<imagepull_secretname>>
registry: <<registry_endpoint>>
username: <<registry_username>>
password: <<registry_password>>
email: <<registry_email>>
# ------------------------------------------------------------------------------
# GLOBAL
# ------------------------------------------------------------------------------
global:
image: <<registry_endpoint>>/<<repository>>
imagePullSecrets:
- <<imagepull_secretname>>
security:
allowInsecureImages: true
# ------------------------------------------------------------------------------
# RABBITMQ-CLUSTER-OPERATOR CHART
# ------------------------------------------------------------------------------
rabbitmq-cluster-operator:
rabbitmqImage:
repository: rabbitmq
tag: 4.1.2-debian-12-r1
credentialUpdaterImage:
repository: rmq-default-credential-updater
tag: 1.0.7-debian-12-r1
clusterOperator:
image:
repository: rabbitmq-cluster-operator
tag: 2.16.0-debian-12-r0
msgTopologyOperator:
enabled: true
image:
repository: rmq-messaging-topology-operator
tag: 1.17.3-debian-12-r0
install
kubectl create ns rabbitmq-system
helm install -n rabbitmq-system rmq ./sdt-migration/tools/ -f ./rabbitmq-cluster-operator-values.yaml
배포 확인
kubectl -n rabbitmq-system get po
NAME READY STATUS RESTARTS AGE
rmq-rabbitmq-cluster-operator-777f7b5f89-grrk4 1/1 Running 0 3h21m
rmq-rabbitmq-messaging-topology-operator-5b45d755fc-8cj2d 1/1 Running 0 3h21m
postgresql
sdt-migration에서 사용하는 Database를 설치합니다. sdtm-system namespace에 설치하며 sdtr과 공유해서 사용합니다
| Variables | 예시 | 비고 |
|---|---|---|
| registry_endpoint | migration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.com | postgresql container image가 있는 SCR private endpoint |
| repository | migration | sdt-postgresql container image가 있는 SCR repository |
| database_user | sdtm | postgresql database username |
| database_name | sdtm | postgresql database name |
| database_password | password | postgresql database password |
create namspace
kubectl create ns sdtm-system
database credentials(secret)생성
postgresql database에서 사용할 credentials을 생성합니다. psql-sdtm-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: psql-sdtm-secret
namespace: sdtm-system
type: Opaque
stringData:
postgres-password: <<database_password>>
user-password: <<database_password>>
kubectl apply -f psql-sdtm-secret.yaml
imagePullSecret 생성
docker가 설치되어 있는 환경
docker login config 파일 확인. image 가 저장되어 있는 registry로 먼저 로그인을 수행합니다.
kubectl -n sdtm-system create secret generic regcred \
--from-file=.dockerconfigjson=$HOME/.docker/config.json> \
--type=kubernetes.io/dockerconfigjson
docker config.json을 사용하여 secret을 생성합니다.
docker가 설치되어 있지 않은 환경
kubectl create secret docker-registry regcred -n sdtm-system \
--docker-username={accountId} \
--docker-password={accountPw} \
--docker-server=<<registry_endpoint>>
values.yaml 파일 준비
postgresql_values.yaml 파일을 생성합니다.
global:
imageRegistry: <<registry_endpoint>>/<<repository>>
security:
allowInsecureImages: true
auth:
username: <<database_user>>
database: <<database_name>>
existingSecret: "psql-sdtm-secret"
architecture: standalone
secretKeys:
adminPasswordKey: "postgres-password"
userPasswordKey: "user-password"
image:
repository: bitnami/postgresql
pullSecrets:
- regcred
primary:
resourcesPreset: "medium"
persistence:
size: 10Gi
install
postgresql helm chart를 SCR에 사전 등록한 경우(예시)
helm install -n sdtm-system db oci://migrationtarget-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.com/migration/helm_chart/postgresql --version 18.1.9 -f./postgresql_values.yaml
postgresql helm chart가 로컬에 있는 경우(예시)
helm install -n sdtm-system db ./postgresql -f./postgresql_values.yaml
배포 확인
kubectl -n sdtm-system get po
NAME READY STATUS RESTARTS AGE
sdtm-postgresql-0 1/1 Running 0 3h53m
sdtm
values.yaml 파일 준비
sdtm의 values.yaml파일을 복사하여 수정합니다.
cp ./sdt-migration/environments/standalone/apps/sdtm-values.yaml .
| Variables | 예시 | 비고 |
|---|---|---|
| imagepull_secretname | scr-migration | SCR에서 image pull을 위해 생성할 secret name |
| registry_endpoint | migration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.com | sdt-migration의 container image가 있는 SCR private endpoint |
| registry_username | username | username(access key) |
| registry_password | password | password(secret key) |
| registry_email | scp@samsung.com | |
| repository | "" | v1에 설치할 경우 “”, v2에 설치할 경우 repository |
| database_host | db-postgresql | Postgresql host 주소. 같은 namspsace에 설치했을 경우 postgresql service명을 사용한다 |
| database_port | 5432 | Postgresql port |
| database_name | sdtm | 위 Postgresql 설치시 사용한 database |
| database_user | sdtm | 위 Postgresql 설치시 사용한 database_user |
| database_password | password | 위 Postgresql 설치시 사용한 database password |
| msgq_persistence_storageClassName | nfs-subdir-external-sc | SKE에서 제공하는 storage class name을 입력 |
| msgq_replicas | 1 | HA 구성을 원하면 2 |
| msgq_persistence_storage | 5Gi | 저장소 크기 |
| scp-load-balancer-service-ip | 70.222.53.140 | sdtctl cli가 접속시 사용할 Service IP |
# ------------------------------------------------------------------------------
# ENABLED COMPONENTS (tags)
# ------------------------------------------------------------------------------
tags:
sdtm: true
# ------------------------------------------------------------------------------
# APPLICATION NAME
# ------------------------------------------------------------------------------
# The application name is derived from the chart name and release name by default.
# The application name is defined in the root helper as `apps.fullname` and can be reused in sub charts when needed.
# It is also used as the name of the Ingress resource.
# To override this, set the `fullnameOverride` value.
#fullnameOverride:
# ------------------------------------------------------------------------------
# SCR CREDENTIALS
# ------------------------------------------------------------------------------
imageCredentials:
secretName: <<imagepull_secretname>>
registry: <<registry_endpoint>>
username: <<registry_username>>
password: <<registry_password>>
email: <<registry_email>>
# ------------------------------------------------------------------------------
# GLOBAL
# ------------------------------------------------------------------------------
global:
image: <<registry_endpoint>>/<<repository>>
imagePullSecrets:
- name: <<imagepull_secretname>>
msgq:
host: msgq
port: 5672
user: admin
password: ENC(I4Ck4liRNBjWUktinQbJJ1WDmX9Ojd6l5fOG2CSO4J2wsb0=)
database:
host: <<database_host>>
port: <<database_port>>
name: <<database_name>>
user: <<database_user>>
password: <<database_password>>
sidecar:
busybox:
image:
repository: busybox
tag: latest
# ------------------------------------------------------------------------------
# INGRESS
# ------------------------------------------------------------------------------
ingress:
enabled: false
# ------------------------------------------------------------------------------
# MSGQ CHART (Rabbitmq Cluster)
# ------------------------------------------------------------------------------
msgq:
enabled: true
image:
repository: rabbitmq
tag: 4.1.2-debian-12-r1
replicas: <<msgq_replicas>>
service:
type: NodePort
nodePort:
amqp: 30088
management: 30089
persistence:
storageClassName: <<msgq_persistence_storageClassName>>
storage: <<msgq_persistence_storage>>
nodeAffinity:
enabled: false
key: sdt-node-role
value: here
# ------------------------------------------------------------------------------
# QUEEN CHART
# ------------------------------------------------------------------------------
queen:
enabled: true
namespaceOverride: sdtm-system
replicas: 1
image:
repository: sdt/sdt-queen
tag: 1.0.1
service:
type: NodePort
port: 8080
nodePort: 30091
job:
scoutbee:
image:
repository: sdt/sdt-scoutbee
tag: 1.0.1
piping:
image:
repository: sdt/sdt-piping
tag: 1.0.1
waggleUrl: waggle.sdtr-system:80
nodeSelector:
enabled: false
key: sdt-node-role
value: here
# ------------------------------------------------------------------------------
# SCOUTBEE CHART
# ------------------------------------------------------------------------------
scoutbee:
enabled: true
filesize_criteria:
medium: 5
large: 10
threadCount: 2
# ------------------------------------------------------------------------------
# PIPING CHART
# ------------------------------------------------------------------------------
piping:
namespaceOverride: sdtm-system
enabled: true
job:
bee:
image:
repository: sdt/sdt-bee
tag: 1.0.4
nodeSelector:
enabled: false
key: sdt-node-role
value: here
bee:
enabled: true
install
helm install -n sdtm-system sdtm ./sdt-migration/apps/ -f ./sdtm-values.yaml
배포 확인
kubectl -n sdtm-system get po
NAME READY STATUS RESTARTS AGE
db-postgresql-0 1/1 Running 0 43m
sdtm-msgq-server-0 1/1 Running 0 6m32s
sdtm-msgq-server-1 1/1 Running 0 6m32s
sdtm-queen-64fc4f9446-hp8qp 1/1 Running 0 7s
cli 접속용 service생성
sdtctl cli를 LoadBalance를 통해 접속하기 위한 service를 별도로 생성합니다.
queen-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: queen-lb
namespace: sdtm-system
labels:
app.kubernetes.io/instance: sdtm
app.kubernetes.io/name: queen-lb
app.kubernetes.io/version: 1.0.0
annotations:
service.beta.kubernetes.io/scp-load-balancer-service-ip: <<scp-load-balancer-service-ip>>
spec:
ports:
- appProtocol: tcp
port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer
selector:
app.kubernetes.io/instance: sdtm
app.kubernetes.io/name: queen
$ kubectl -n sdtm-system apply -f queen-lb.yaml
$ kubectl -n sdtm-system get service queen-lb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
queen-lb LoadBalancer 172.20.79.81 70.222.53.140 80:32075/TCP 29s
external-ip가 정상적으로 할당되었는지 확인합니다. 이 IP를 sdtctl cli 설정시 사용합니다.
sdtr
values.yaml 파일 준비
sdtr의 values.yaml파일을 복사하여 수정합니다.
cp ./sdt-migration/environments/standalone/apps/sdtr-values.yaml .
| Variables | 예시 | 비고 |
|---|---|---|
| imagepull_secretname | scr-migration | SCR에서 image pull을 위해 생성할 secret name |
| registry_endpoint | migration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.com | sdt-migration의 container image가 있는 SCR private endpoint |
| registry_username | username | username(access key) |
| registry_password | password | password(secret key) |
| registry_email | scp@samsung.com | |
| repository | "" | v1에 설치할 경우 “”, v2에 설치할 경우 repository |
| database_host | db-postgresql | Postgresql host 주소. 같은 namspsace에 설치했을 경우 postgresql service명을 사용한다 |
| database_port | 5432 | Postgresql port |
| database_name | sdtm | 위 Postgresql 설치시 사용한 database |
| database_user | sdtm | 위 Postgresql 설치시 사용한 database_user |
| database_password | password | 위 Postgresql 설치시 사용한 database password |
| msgq_persistence_storageClassName | nfs-subdir-external-sc | SKE에서 제공하는 storage class name을 입력 |
| msgq_replicas | 1 | HA 구성을 원하면 2 |
| msgq_persistence_storage | 5Gi | 저장소 크기 |
# ------------------------------------------------------------------------------
# ENABLED COMPONENTS (tags)
# ------------------------------------------------------------------------------
tags:
sdtr: true
# ------------------------------------------------------------------------------
# APPLICATION NAME
# ------------------------------------------------------------------------------
# The application name is derived from the chart name and release name by default.
# The application name is defined in the root helper as `apps.fullname` and can be reused in sub charts when needed.
# It is also used as the name of the Ingress resource.
# To override this, set the `fullnameOverride` value.
#fullnameOverride:
# ------------------------------------------------------------------------------
# SCR CREDENTIALS
# ------------------------------------------------------------------------------
imageCredentials:
secretName: <<imagepull_secretname>>
registry: <<registry_endpoint>>
username: <<registry_username>>
password: <<registry_password>>
email: <<registry_email>>
namespaceOverride: sdtr-system
# ------------------------------------------------------------------------------
# GLOBAL
# ------------------------------------------------------------------------------
global:
image: <<registry_endpoint>>/<<repository>>
imagePullSecrets:
- name: <<imagepull_secretname>>
msgq:
host: msgq
port: 5672
user: admin
password: ENC(I4Ck4liRNBjWUktinQbJJ1WDmX9Ojd6l5fOG2CSO4J2wsb0=)
database:
host: <<database_host>>
port: <<database_port>>
name: <<database_name>>
user: <<database_user>>
password: <<database_password>>
sidecar:
busybox:
image:
repository: busybox
tag: latest
# ------------------------------------------------------------------------------
# MSGQ CHART (Rabbitmq Cluster)
# ------------------------------------------------------------------------------
msgq:
enabled: true
image:
repository: rabbitmq
tag: 4.1.2-debian-12-r1
replicas: <<msgq_persistence_replicas>>
service:
type: NodePort
nodePort:
amqp: 30098
management: 30099
persistence:
storageClassName: <<msgq_persistence_storageClassName>>
storage: <<msgq_persistence_storage>>
nodeAffinity:
enabled: false
key: sdt-node-role
value: here
# ------------------------------------------------------------------------------
# WAGGLE CHART
# ------------------------------------------------------------------------------
waggle:
enabled: true
image:
repository: sdt/sdt-waggle
tag: 1.2.8
replicas: 1
event:
topicPushProtocol: amqp
topicPushEndpoint: sdtr-msgq:5672
notificationRetryLimit: 10
replication:
onlyVersioning: false
requiredNamespace: false
podAffinity:
enabled: false
# ------------------------------------------------------------------------------
# WEBHOOK CHART
# ------------------------------------------------------------------------------
webhook:
enabled: true
image:
repository: sdt/sdt-webhook
tag: 1.0.0
replicas: 1
podAffinity:
enabled: false
# ------------------------------------------------------------------------------
# BEE CHART
# ------------------------------------------------------------------------------
bee:
enabled: true
image:
repository: sdt/sdt-bee
tag: 1.2.2
replicas: 1
podAffinity:
enabled: false
extraArgs:
- "--bee-mode=daemon"
consume:
request:
exchange_name: bucket.replication.request.direct
exchange_key: bucket.replication.request.key
queue_name: bucket_replication_request_queue
remove:
exchange_name: bucket.replication.remove.direct
exchange_key: bucket.replication.remove.key
queue_name: bucket_replication_remove_queue
publish:
exchange_name: bucket.replication.response.direct
exchange_key: bucket.replication.response.key
retry_count: 1
install
kubectl create ns sdtr-system
helm install -n sdtr-system sdtr ./sdt-migration/apps/ -f ./sdtr-values.yaml
배포 확인
kubectl -n sdtr-system get po
NAME READY STATUS RESTARTS AGE
sdtr-bee-748bbc8455-hxnbj 1/1 Running 0 5h14m
sdtr-msgq-server-0 1/1 Running 0 5h14m
sdtr-waggle-7c6478854c-ktqls 1/1 Running 0 5h14m
sdtr-webhook-d97b58898-xzn22 1/1 Running 0 5h14m
sdtctl cli설치
절달 받은 sdtctl 파일을 /usr/local/bin 디렉토리에 복사합니다.
sudo cp ./sdtctl /usr/local/bin/.
sudo chmod 755 /usr/local/bin/sdtctl
마이그레이션 절차
1. CLI Configuration
sdtctl cli를 사용하기 위해서는 설치한 sdt-migration 서버와 연결하기 위한 설정 파일을 생성해야 합니다. 설정 파일은 “{user home directory}/.config/sdtctl/config.yaml” 위치에 저장합니다.
config.yaml
queen:
endpoint: {ip:port}
CLI에서 설정하는 endpoint의 ip:port 는 모듈 설치시에 설정한 queen 의 NodePort 혹은 Loadbalancer로 연결된 ip:port 입니다. [cli 접속용 service 생성](### cli 접속용 service생성)시 배포한 서비스에 할당된 external ip, port 를 사용합니다.
CLI의 command 목록은 다음 표와 같습니다.
| Binary | Command | Sub Command | Args | Flags | 설명 |
|---|---|---|---|---|---|
| sdtctl | mig | create | jsonargs | 마이그레이션 요청 | |
| ls(or search) | name | 마이그레이션 목록 조회 | |||
| progress | id | 마이그레이션 진행 상태 조회 | |||
| get | id | 마이그레이션 정보 조회 | |||
| delete | id | 마이그레이션 삭제 | |||
| retry | id | 마이그레이션 재시작 |
2. 마이그레이션 실행
출발지 버킷으로부터 도착지 버킷으로 데이터 마이그레이션을 요청합니다.
다음 표를 참고하여 json 파일을 작성합니다.
Name _ | type | Required | Default value | Baundary value | Description | 비고 |
|---|---|---|---|---|---|---|
| name | String | Y | 마이그레이션 명 | |||
| description | String | 마이그레이션 설명 | ||||
| src.endpoint | String | Y | 출발지 endpoint | |||
| src.accessKey | String | Y | 출발지 access key | |||
| src.secretKey | String | Y | 출발지 secret key | |||
| dst.endpoint | String | Y | 목적지 endpoint | |||
| dst.access_key | String | Y | 목적지 access key | |||
| dst.secret_key | String | Y | 목적지 secret key | |||
| targets | Array | Y | Migration 대상 정보 목록 | |||
| srcBucket | String | Y | 출발 Bucket 명 | |||
| srcEnc.type | String | 출발 Bucket의 암호화 형태 | 예: SSE-C | |||
| srcEnc.algorithm | String | 출발 Bucket의 암호화 알고리즘 | 예: AES256 | |||
| srcEnc.key | String | 출발 Bucket의 암호화 키 | 32bytes string | |||
| dstBucket | String | Y | 도착 Bucket 명 | |||
| dstEnc.type | String | 도착 Bucket의 암호화 형태 | 예: SSE-C | |||
| dstEnc.algorithm | String | 도착 Bucket의 암호화 알고리즘 | 예: AES256 | |||
| dstEnc.key | String | 도착 Bucket의 암호화 키 | 32bytes string |
Json Example
{
"name": "마이그레이션 명",
"description": "마이그레이션 설명",
"src":{
"endpoint": "https://127.0.0.1:443",
"accessKey": "access key string",
"secretKey": "secret key string",
},
"dst":{
"endpoint": "https://127.0.0.1:443",
"accesskey": "access key string",
"secretkey": "secret key string",
},
"targets":[{
"srcBucket": "source bucket name",
"srcEnc": { "type": "SSE-C", "algorithm": "AES256", "key": "key string"},
"dstBucket": "target bucket name",
"dstEnc": { "type": "SSE-C", "algorithm": "AES256", "key": "key string"}
}]
}
Command Example
sdtctl mig create --jsonargs={json file path}
*Response Example
{
"id": "mig_xxx"
}
위와 같은 결과가 나온 경우, 해당 마이그레이션 ID로 정상적으로 마이그레이션이 등록된 상태입니다.
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |
{
"Code": 500,
"Message": "Migration's registered already. Check 'mig_xxx'!"
}
위와 같은 에러가 발생하는 경우, 동일한 소스 버킷이 마이그레이션에 등록되어 있는 상태입니다. 따라서 필요시 해당 마이그레이션을 삭제 후 다시 생성하도록 합니다.
3. 마이그레이션 목록 조회
마이그레이션 명을 사용하여 마이그레이션 목록을 조회하는 Command입니다.
Command Example
sdtctl mig ls --name={마이그레이션 명}
Response Example
ID NAME STATE START_DT END_DT
mig_xxx 마이그레이션 명 WAITING 2025-06-24T16:15:24.423432+09:00 2025-06-24T16:15:24.423432+09:00
- ID: 마이그레이션 ID
- NAME: 마이그레이션 명
- STATE: 마이그레이션 상태
- START_DT: 마이그레이션 시작 시간
- END_DT: 마이그레이션 종료 시간
state에 표기되는 내용은 다음과 같습니다.
| State | Description |
|---|---|
| WAITING | 마이그레이션 요청이 되었으나 대기 중인 상태 |
| FULL-INPROGRESS | Full Migration이 진행 중인 상태 |
| INCR-INPROGRESS | Incremental Migration이 진행 중인 상태 |
| FINISHED | Incremental Migration이 종료된 상태 |
| DELETED | 마이그레이션이 삭제된 상태 |
| FAILED | 마이그레이션 도중 에러가 발생하여 실패된 상태 |
4. 마이그레이션 진행 상태 조회
마이그레이션 ID를 이용하여 마이그레이션의 진행 상태 정보를 조회하는 Command입니다.
Command Example
sdtctl mig progress {마이그레이션 ID}
Response Example
아래와 같은 json 형태의 결과가 보여집니다.
{
"id": "mig_xxx",
"state": "COMPLETE",
"failedAt": "scoutbee",
"fullMigration": {
"completedCount": 18,
"totalCount": 18
"completedSize": 50735188,
"totalSize": 50735188
},
"incrementalMigration": {
"completedCount": 0,
"totalCount": 0
"completedSize": 50735188,
"totalSize": 50735188
}
}
위 json의 filed의 내용은 다음 표와 같습니다.
Name | type | Description | 비고 |
|---|---|---|---|
| id | String | 마이그레이션 ID | |
| state | String | 마이그레이션 상태 | |
| failedAt | String | 실패 위치 | |
| fullMigration.completedCount | number | Full 마이그레이션 오브젝트 개수(완료) | |
| fullMigration.totalCount | number | Full 마이그레이션 오브젝트 개수(전체) | |
| fullMigration.completedSize | number | Full 마이그레이션 오브젝트 사이즈(완료) | |
| fullMigration.totalSize | number | Full 마이그레이션 오브젝트 사이즈(전체) | |
| incrementalMigration.completedCount | number | Incremental 마이그레이션 오브젝트 개수(완료) | |
| incrementalMigration.totalCount | number | Incremental 마이그레이션 오브젝트 개수(전체) | |
| incrementalMigration.completedSize | number | Incremental 마이그레이션 오브젝트 사이즈(완료) | |
| incrementalMigration.totalSize | number | Incremental 마이그레이션 오브젝트 사이즈(전체) |
state에 표기되는 내용은 다음과 같습니다.
| State | Description |
|---|---|
| WAITING | 마이그레이션 요청이 되었으나 대기 중인 상태 |
| FULL-INPROGRESS | Full Migration이 진행 중인 상태 |
| INCR-INPROGRESS | Incremental Migration이 진행 중인 상태 |
| FINISHED | Incremental Migration이 종료된 상태 |
| DELETED | 마이그레이션이 삭제된 상태 |
| FAILED | 마이그레이션 도중 에러가 발생하여 실패된 상태 |
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |
5. 마이그레이션 정보 조회
마이그레이션 ID를 이용하여 마이그레이션 정보를 조회하는 Command입니다.
Command Example
sdtclt mig get {마이그레이션 ID}
Response Example
아래와 같은 json 형태의 결과가 보여집니다.
{
"id": "mig_xxx",
"name": "DJ-Mig0423-001",
"description": "Test",
"targets": [
{
"migrationId": "mig_189",
"seq": 1,
"state": "FAILED",
"retryCount": 4,
"retryPoint": "scoutbee",
"srcBucket": "sejun-test14",
"srcEnc": {},
"dstBucket": "sejun-test",
"dstEnc": {}
}
],
"src": {
"endpoint": "http://192.168.110.60:9000",
"accessKey": "sejun",
"secretKey": "rlatpwns"
},
"dst": {
"endpoint": "http://192.168.110.60:9000",
"accessKey": "sejun",
"secretKey": "rlatpwns"
},
"startDt": "2025-05-13T10:04:37.265231+09:00",
"endDt": "0001-01-01T08:27:52+08:27",
"state": "FAILED",
"failedAt": "scoutbee",
"createdDt": "2025-05-13T10:04:37.267658+09:00"
}
위 json의 filed의 내용은 다음 표와 같습니다.
| Name | type | Description | 비고 |
|---|---|---|---|
| id | String | 마이그레이션 Id | |
| name | String | 마이그레이션 명 | |
| description | String | 마이그레이션 설명 | |
| targets | Array | 상세 목록 | |
| migrationId | String | 마이그레이션 Id | |
| seq | Number | 순번 | |
| state | String | 상태 | |
| retryCount | Number | 재시도 횟수 | |
| retryPoint | String | 재시도 위치 | |
| srcBucket | String | 출발지 버킷 이름 | |
| srcEnc.type | String | 출발지 암호화 타입 | |
| srcEnc.algorithm | String | 출발지 암호화 알고리즘 | |
| srcEnc.key | String | 출발지 암호화 키 | |
| dstBucket | String | 도착지 버킷 이름 | |
| dstEnc.type | String | 도착지 암호화 타입 | |
| dstEnc.algorithm | String | 도착지 암호화 알고리즘 | |
| dstEnc.key | String | 도착지 암호화 키 | |
| src.endpoint | String | 출발지 endpoint | |
| src.accessKey | String | 출발지 access key | |
| src.secretKey | String | 출발지 secret key | |
| dst.endpoint | String | 목적지 endpoint | |
| dst.accessKey | String | 목적지 access key | |
| dst.secretKey | String | 목적지 secret key | |
| startDt | String | 시작 일시 | |
| endDt | String | 완료 일시 | |
| state | String | 상태 | |
| failedAt | String | 실패 위치 | |
| createdDt | String | 생성 일시 |
targets.state에 표기되는 내용은 다음과 같습니다.
| State | Description |
|---|---|
| WAITING | 마이그레이션 요청이 되었으나 대기 중인 상태 |
| COLLECTING | 소스 버킷으로부터 데이터의 정보를 조회 중인 상태 |
| ANALYZING | 소스 버킷에서 조회한 정보를 바탕으로 데이터를 분석 중인 상태 |
| ANALYZED | 소스 버킷에서 조회한 정보를 바탕으로 데이터 분석이 완료 된 상태 |
| TRANSFERRING | 기존 데이터를 전송 중인 상태 |
| TRANSFERRED | Full Migration이 완료된 상태 |
| INCR-INPROGRESS | Incremental Migration이 진행 중인 상태 |
| FINISHED | Incremental Migration이 종료된 상태 |
| DELETED | 마이그레이션이 삭제된 상태 |
| FAILED | 마이그레이션 도중 에러가 발생하여 실패된 상태 |
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |
6. 마이그레이션 종료
마이그레이션 ID를 이용하여 마이그레이션의 종료 요청을 하는 Command입니다.
Command Example
sdtctl mig finish {마이그레이션 ID}
Response Example
{
"id": "mig_XXX"
}
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |
7. 마이그레이션 삭제
마이그레이션 ID를 이용하여 마이그레이션 삭제 요청을 하는 Command입니다.
Command Example
sdtctl mig delete {마이그레이션 ID}
Response Example
{
"id": "mig_XXX"
}
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |
8. 마이그레이션 재시작
실패한 마이그레이션의 ID를 이용하여 마이그레이션 재시작을 요청하는 Command입니다.
마이그레이션의 state가 FAILED인 경우에만 실행 가능합니다.
Command Example
sdtctl mig retry {마이그레이션 ID}
Response Example
{
"id": "mig_XXX",
}
Error
HTTP status code | ErrorCode | Description |
|---|---|---|
| 400 | Bad Request | |
| 403 | Forbidden | |
| 500 | Internal Server Error |


