Object Storage(sdt-migration)

Object Storage(sdt-migration)

개요

이 페이지는 Object Storage의 Live Migration에서 제공하는 API 또는 CLI를 사용하여 Live Migration을 수행하는 방법에 대한 가이드 입니다. Live Migration이란 소스 스토리지에서 타겟 스토리지로의 기존 데이터의 전송 뿐만 아니라 실시간으로 추가되는 데이터의 변화를 전송함으로써 데이터의 무결성 및 정합성을 확보하는 기술입니다.

Live Migration 프로세스

Live Migration 프로세스
Live Migration의 수행 흐름은 기존 데이터를 전송하는 Full Migration과 마이그레이션 요청 이후 발생한 변경 사항을 전송하는 Incremental 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에 표기되는 내용은 다음과 같습니다.

StateDescription
WAITING마이그레이션 요청이 되었으나 대기 중인 상태
FULL-INPROGRESSFull Migration이 진행 중인 상태
INCR-INPROGRESSIncremental Migration이 진행 중인 상태
FINISHEDIncremental Migration이 종료된 상태
DELETED마이그레이션이 삭제된 상태
FAILED마이그레이션 도중 에러가 발생하여 실패된 상태
표. Migration 상태표

마이그레이션 정보 조회 API를 실행하면 더 자세한 정보를 얻을 수 있습니다. 이 때, 표기되는 targets.state에 표기되는 내용은 다음과 같습니다.

StateDescription
WAITING마이그레이션 요청이 되었으나 대기 중인 상태
COLLECTING소스 버킷으로부터 데이터의 정보를 조회 중인 상태
ANALYZING소스 버킷에서 조회한 정보를 바탕으로 데이터를 분석 중인 상태
ANALYZED소스 버킷에서 조회한 정보를 바탕으로 데이터 분석이 완료 된 상태
TRANSFERRING기존 데이터를 전송 중인 상태
TRANSFERREDFull Migration이 완료된 상태
INCR-INPROGRESSIncremental Migration이 진행 중인 상태
FINISHEDIncremental Migration이 종료된 상태
DELETED마이그레이션이 삭제된 상태
FAILED마이그레이션 도중 에러가 발생하여 실패된 상태
표. Targets 상태표

Migration state와 targest state의 관계는 다음과 같습니다.

Live Migration State Chart

제약 사항

마이그레이션을 수행하기 위한 제약 사항들에 대한 설명입니다. 마이그레이션 수행 사전에 반드시 숙지하시길 바랍니다.

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 모듈 설치

mig_arch_01
그림. Object Storage Migration 환경

Requirement

K8s

Node 대수Node Spec
최소3v4m12
권장3v8m32

PostgreSQL

ReplicaResource
최소1v2m4
권장2v2m4

사전 준비 사항

  • 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 .
수정 사항
아래 Table 정보를 참조하여 설치 환경에 맞게 수정합니다.
Variables예시비고
imagepull_secretnamescr-migrationSCR에서 image pull을 위해 생성할 secret name
registry_endpointmigration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.comsdt-migration의 container image가 있는 SCR private endpoint
registry_usernameusernameusername(access key)
registry_passwordpasswordpassword(secret key)
registry_emailscp@samsung.comemail
repository""v1에 설치할 경우 “”, v2에 설치할 경우 repository
표. values.yaml
# ------------------------------------------------------------------------------
# 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과 공유해서 사용합니다

수정 사항
postgresql은 official helm chart를 사용하여 설치합니다. 설치에 필요한 chart 파일과 Container 이미지는 사전에 등록되어 있어야 합니다.

Variables예시비고
registry_endpointmigration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.compostgresql container image가 있는 SCR private endpoint
repositorymigrationsdt-postgresql container image가 있는 SCR repository
database_usersdtmpostgresql database username
database_namesdtmpostgresql database name
database_passwordpasswordpostgresql database password
표. postgresql설치시 참조

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 .
수정 사항
아래 Table 정보를 참조하여 설치 환경에 맞게 수정합니다.
Variables예시비고
imagepull_secretnamescr-migrationSCR에서 image pull을 위해 생성할 secret name
registry_endpointmigration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.comsdt-migration의 container image가 있는 SCR private endpoint
registry_usernameusernameusername(access key)
registry_passwordpasswordpassword(secret key)
registry_emailscp@samsung.comemail
repository""v1에 설치할 경우 “”, v2에 설치할 경우 repository
database_hostdb-postgresqlPostgresql host 주소. 같은 namspsace에 설치했을 경우 postgresql service명을 사용한다
database_port5432Postgresql port
database_namesdtm위 Postgresql 설치시 사용한 database
database_usersdtm위 Postgresql 설치시 사용한 database_user
database_passwordpassword위 Postgresql 설치시 사용한 database password
msgq_persistence_storageClassNamenfs-subdir-external-scSKE에서 제공하는 storage class name을 입력
msgq_replicas1HA 구성을 원하면 2
msgq_persistence_storage5Gi저장소 크기
scp-load-balancer-service-ip70.222.53.140sdtctl cli가 접속시 사용할 Service IP
표. sdtm설치시 참조
# ------------------------------------------------------------------------------
# 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 .
수정 사항
아래 Table 정보를 참조하여 설치 환경에 맞게 수정합니다.
Variables예시비고
imagepull_secretnamescr-migrationSCR에서 image pull을 위해 생성할 secret name
registry_endpointmigration-yqvcfsxh.scr.private.kr-west1.s.samsungsdscloud.comsdt-migration의 container image가 있는 SCR private endpoint
registry_usernameusernameusername(access key)
registry_passwordpasswordpassword(secret key)
registry_emailscp@samsung.comemail
repository""v1에 설치할 경우 “”, v2에 설치할 경우 repository
database_hostdb-postgresqlPostgresql host 주소. 같은 namspsace에 설치했을 경우 postgresql service명을 사용한다
database_port5432Postgresql port
database_namesdtm위 Postgresql 설치시 사용한 database
database_usersdtm위 Postgresql 설치시 사용한 database_user
database_passwordpassword위 Postgresql 설치시 사용한 database password
msgq_persistence_storageClassNamenfs-subdir-external-scSKE에서 제공하는 storage class name을 입력
msgq_replicas1HA 구성을 원하면 2
msgq_persistence_storage5Gi저장소 크기
표. sdtr설치시 참조
# ------------------------------------------------------------------------------
# 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 목록은 다음 표와 같습니다.

BinaryCommandSub CommandArgsFlags설명
sdtctlmigcreatejsonargs마이그레이션 요청
ls(or search)name마이그레이션 목록 조회
progressid마이그레이션 진행 상태 조회
getid마이그레이션 정보 조회
deleteid마이그레이션 삭제
retryid마이그레이션 재시작
표. CLI Command List

2. 마이그레이션 실행

출발지 버킷으로부터 도착지 버킷으로 데이터 마이그레이션을 요청합니다.

다음 표를 참고하여 json 파일을 작성합니다.

Name
_
typeRequiredDefault valueBaundary valueDescription비고
nameStringY마이그레이션 명
descriptionString마이그레이션 설명
src.endpointStringY출발지 endpoint
src.accessKeyStringY출발지 access key
src.secretKeyStringY출발지 secret key
dst.endpointStringY목적지 endpoint
dst.access_keyStringY목적지 access key
dst.secret_keyStringY목적지 secret key
targetsArrayYMigration 대상 정보 목록
srcBucketStringY출발 Bucket 명
srcEnc.typeString출발 Bucket의 암호화 형태예: SSE-C
srcEnc.algorithmString출발 Bucket의 암호화 알고리즘예: AES256
srcEnc.keyString출발 Bucket의 암호화 키32bytes string
dstBucketStringY도착 Bucket 명
dstEnc.typeString도착 Bucket의 암호화 형태예: SSE-C
dstEnc.algorithmString도착 Bucket의 암호화 알고리즘예: AES256
dstEnc.keyString도착 Bucket의 암호화 키32bytes string
표. 요청 Command json filed

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
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 요청 Command Error Response
{
    "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에 표기되는 내용은 다음과 같습니다.

StateDescription
WAITING마이그레이션 요청이 되었으나 대기 중인 상태
FULL-INPROGRESSFull Migration이 진행 중인 상태
INCR-INPROGRESSIncremental Migration이 진행 중인 상태
FINISHEDIncremental Migration이 종료된 상태
DELETED마이그레이션이 삭제된 상태
FAILED마이그레이션 도중 에러가 발생하여 실패된 상태
표. Migration 상태표

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
typeDescription비고
idString마이그레이션 ID
stateString마이그레이션 상태
failedAtString실패 위치
fullMigration.completedCountnumberFull 마이그레이션 오브젝트 개수(완료)
fullMigration.totalCountnumberFull 마이그레이션 오브젝트 개수(전체)
fullMigration.completedSizenumberFull 마이그레이션 오브젝트 사이즈(완료)
fullMigration.totalSizenumberFull 마이그레이션 오브젝트 사이즈(전체)
incrementalMigration.completedCountnumberIncremental 마이그레이션 오브젝트 개수(완료)
incrementalMigration.totalCountnumberIncremental 마이그레이션 오브젝트 개수(전체)
incrementalMigration.completedSizenumberIncremental 마이그레이션 오브젝트 사이즈(완료)
incrementalMigration.totalSizenumberIncremental 마이그레이션 오브젝트 사이즈(전체)
표. 진행 상태 조회 Command Response filed

state에 표기되는 내용은 다음과 같습니다.

StateDescription
WAITING마이그레이션 요청이 되었으나 대기 중인 상태
FULL-INPROGRESSFull Migration이 진행 중인 상태
INCR-INPROGRESSIncremental Migration이 진행 중인 상태
FINISHEDIncremental Migration이 종료된 상태
DELETED마이그레이션이 삭제된 상태
FAILED마이그레이션 도중 에러가 발생하여 실패된 상태
표. Migration 상태표

Error

HTTP status code
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 진행 상태 조회 Command Error Response

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의 내용은 다음 표와 같습니다.

NametypeDescription비고
idString마이그레이션 Id
nameString마이그레이션 명
descriptionString마이그레이션 설명
targetsArray상세 목록
migrationIdString마이그레이션 Id
seqNumber순번
stateString상태
retryCountNumber재시도 횟수
retryPointString재시도 위치
srcBucketString출발지 버킷 이름
srcEnc.typeString출발지 암호화 타입
srcEnc.algorithmString출발지 암호화 알고리즘
srcEnc.keyString출발지 암호화 키
dstBucketString도착지 버킷 이름
dstEnc.typeString도착지 암호화 타입
dstEnc.algorithmString도착지 암호화 알고리즘
dstEnc.keyString도착지 암호화 키
src.endpointString출발지 endpoint
src.accessKeyString출발지 access key
src.secretKeyString출발지 secret key
dst.endpointString목적지 endpoint
dst.accessKeyString목적지 access key
dst.secretKeyString목적지 secret key
startDtString시작 일시
endDtString완료 일시
stateString상태
failedAtString실패 위치
createdDtString생성 일시
표. 정보 조회 Command Response filed

targets.state에 표기되는 내용은 다음과 같습니다.

StateDescription
WAITING마이그레이션 요청이 되었으나 대기 중인 상태
COLLECTING소스 버킷으로부터 데이터의 정보를 조회 중인 상태
ANALYZING소스 버킷에서 조회한 정보를 바탕으로 데이터를 분석 중인 상태
ANALYZED소스 버킷에서 조회한 정보를 바탕으로 데이터 분석이 완료 된 상태
TRANSFERRING기존 데이터를 전송 중인 상태
TRANSFERREDFull Migration이 완료된 상태
INCR-INPROGRESSIncremental Migration이 진행 중인 상태
FINISHEDIncremental Migration이 종료된 상태
DELETED마이그레이션이 삭제된 상태
FAILED마이그레이션 도중 에러가 발생하여 실패된 상태
표. Targets 상태표

Error

HTTP status code
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 정보 조회 Command Error Response

6. 마이그레이션 종료

마이그레이션 ID를 이용하여 마이그레이션의 종료 요청을 하는 Command입니다.

Command Example

sdtctl mig finish {마이그레이션 ID}

Response Example

{
    "id": "mig_XXX"
}

Error

HTTP status code
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 종료 요청 Command Error Response

7. 마이그레이션 삭제

마이그레이션 ID를 이용하여 마이그레이션 삭제 요청을 하는 Command입니다.

Command Example

sdtctl mig delete {마이그레이션 ID}

Response Example

{
    "id": "mig_XXX"
}

Error

HTTP status code
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 삭제 요청 Command Error Response

8. 마이그레이션 재시작

실패한 마이그레이션의 ID를 이용하여 마이그레이션 재시작을 요청하는 Command입니다.

마이그레이션의 state가 FAILED인 경우에만 실행 가능합니다.

Command Example

sdtctl mig retry {마이그레이션 ID}

Response Example

{
    "id": "mig_XXX",
}

Error

HTTP status code
ErrorCodeDescription
400Bad Request
403Forbidden
500Internal Server Error
표. 재시작 요청 Command Error Response