데이터 이전

데이터 전송은 다음 간에 발생할 수 있습니다.

  1. 영구 볼륨 클레임 (PVC) 및 객체 스토리지
  2. 객체 스토리지 및 객체 스토리지 (GDC 내)

GDC의 객체 스토리지는 S3과 호환되며 Kubernetes YAML에서 s3 유형이라고 합니다.

데이터 소스 및 대상 유형

  1. 객체 스토리지('s3'이라고 함): GDC에 있는 객체 스토리지
  2. 로컬 스토리지('로컬'이라고 함): 연결된 PVC의 스토리지

객체 스토리지에서 객체 스토리지로 복사

다음과 같은 사전 요구사항이 있는지 확인합니다.

  • 소스에 대한 읽기 권한이 있는 S3 엔드포인트와 대상에 대한 쓰기 권한이 있는 S3 엔드포인트
  • 사용자 인증 정보에 버킷 생성 권한이 없는 경우 대상 버킷이 없으면 전송이 실패합니다. 이 경우 대상 버킷이 있는지 확인합니다.
  • 클러스터 또는 네임스페이스 내에서 작업을 만들고 보안 비밀을 만들거나 읽을 수 있는 권한 권한은 다음 예를 참고하세요.

데이터 전송 설정

데이터 전송을 설정하려면 다음 단계를 완료하세요.

전송 네임스페이스 만들기

전송 작업이 실행될 네임스페이스를 만듭니다.

apiVersion: v1
kind: Namespace
metadata:
  name: NAMESPACE

사용자 인증 정보 구성

전송을 위한 사용자 인증 정보를 준비합니다. 전송 시나리오에 가장 적합한 옵션을 따르세요.

GDC 간 전송

동일한 GDC 유니버스 내에서 완전히 발생하는 전송의 경우 보안 비밀이 이미 존재합니다. 이 메서드는 여러 유니버스 간의 전송이 아니라 단일 유니버스 내의 전송에만 적용됩니다.

  1. S3 사용자 인증 정보 보안 비밀을 가져오려면 버킷 액세스 권한 부여 안내를 따르세요.

  2. 전송 작업의 대상 네임스페이스에서 서비스 계정 (SA)을 만듭니다. 그런 다음 교차 네임스페이스 RoleBinding을 사용하여 소스 및 대상 네임스페이스 모두에서 보안 비밀을 읽을 수 있도록 이 계정에 권한을 추가합니다.

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: SOURCE_NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-source-secrets-rolebinding
      namespace: SOURCE_NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: DESTINATION_NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-dest-secrets-rolebinding
      namespace: DESTINATION_NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: DESTINATION_NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    

GDC에서 비GDC로 전송

외부 시스템과 관련된 전송의 경우 액세스 사용자 인증 정보를 명시적으로 지정해야 합니다.

  1. 대상 네임스페이스에서 사용자 인증 정보를 만듭니다.

    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-secret
      namespace: NAMESPACE
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: dst-secret
      namespace: NAMESPACE
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    
  2. 전송에서 사용하는 서비스 계정 (SA)을 만든 다음 역할 및 역할 결합을 사용하여 보안 비밀을 읽고 쓸 수 있는 권한을 계정에 추가합니다. 기본 네임스페이스 SA 또는 커스텀 SA에 이미 이러한 권한이 있는 경우 권한을 추가할 필요가 없습니다.

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: NAMESPACE
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: NAMESPACE
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-secrets-rolebinding
      namespace: NAMESPACE
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: NAMESPACE
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    ---
    

CA 인증서 가져오기

객체 스토리지 시스템의 CA 인증서를 가져옵니다. 신뢰 번들을 가져오는 안내에 따라 AO 또는 PA에서 동일한 인증서를 가져올 수 있습니다.

---

apiVersion: v1
kind: Secret
metadata:
  name: src-cert
  namespace: NAMESPACE
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUpHM2psOFZhTU85a1FteGdXUFl3N3d3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF5TVRVd01USXlNakZhRncweQpNekExTVRZd01USXlNakZhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWI== # base 64 encoded version of certificate

---

apiVersion: v1
kind: Secret
metadata:
  name: dst-cert
  namespace: NAMESPACE
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUtoaEJXWWo3VGZlUUZWUWo0U0RpckV3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF6TURZeU16TTROVEJhRncweQpNekEyTURReU16TTROVEJhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWIzRFFF== # base 64 encoded version of certificate. Can be same OR different than source certificate.

---

(선택사항) LoggingTarget 만들기

Loki에서 전송 서비스 로그를 보려면 LoggingTarget을 만듭니다.

apiVersion: logging.gdc.goog/v1
kind: LoggingTarget
metadata:
  namespace: NAMESPACE # Same namespace as your transfer job
  name: logtarg1
spec:
  # Choose matching pattern that identifies pods for this job
  # Optional
  # Relationship between different selectors: AND
  selector:

    # Choose pod name prefix(es) to consider for this job
    # Observability platform will scrape all pods
    # where names start with specified prefix(es)
    # Should contain [a-z0-9-] characters only
    # Relationship between different list elements: OR
    matchPodNames:
      - transfer-job # Choose the prefix here that matches your transfer job name
  serviceName: transfer-service

전송 워크로드 만들기

Job을 사용하여 일회성 작업으로 전송을 실행하거나 CronJob을 사용하여 반복적으로 실행되도록 예약할 수 있습니다.

사용 사례에 가장 적합한 방법을 선택하세요.

일회성 작업 만들기

단일 수동 데이터 전송에 이 구성을 사용합니다.

---
apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: NAMESPACE
spec:
  template:
    spec:
      serviceAccountName: transfer-service-account # The service account created in the previous step
      containers:
        - name: storage-transfer-pod
          image: gcr.io/private-cloud-staging/storage-transfer:latest
          imagePullPolicy: Always
          command:
            - /storage-transfer
          args:
            # The S3 endpoints for your source and destination
            - '--src_endpoint=SRC_ENDPOINT'
            - '--dst_endpoint=DST_ENDPOINT'
            # The Fully Qualified Names (FQN) of the buckets
            - '--src_path=SRC_BUCKET_FQN/'
            - '--dst_path=DST_BUCKET_FQN/'
            # Cross-namespace mapping: point directly to the live credentials using NAMESPACE/SECRET_NAME
            - '--src_credentials=NAMESPACE/SRC_SECRET_NAME'
            - '--dst_credentials=NAMESPACE/DST_SECRET_NAME'
            # Point to the CA certificate Secret created in the destination namespace
            - '--src_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
            - '--dst_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
            - '--src_type=s3'
            - '--dst_type=s3'
            - '--bandwidth_limit=BANDWIDTH_LIMIT' # Optional. Examples: '10K', '100M', '1G'
      restartPolicy: OnFailure
---

예약된 CronJob 만들기

이 구성을 사용하여 대상 버킷을 고정된 일정에 따라 소스 버킷과 지속적으로 동기화합니다.

---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: transfer-cronjob
  namespace: NAMESPACE
spec:
  schedule: "0 * * * *"  # Runs at the top of every hour. Adjust the cron schedule as needed.
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: transfer-service-account # The service account created in the previous step
          containers:
            - name: storage-transfer-pod
              image: gcr.io/private-cloud-staging/storage-transfer:latest
              imagePullPolicy: Always
              command:
                - /storage-transfer
              args:
                # The S3 endpoints for your source and destination
                - '--src_endpoint=SRC_ENDPOINT'
                - '--dst_endpoint=DST_ENDPOINT'
                # The Fully Qualified Names (FQN) of the buckets
                - '--src_path=SRC_BUCKET_FQN/'
                - '--dst_path=DST_BUCKET_FQN/'
                # Cross-namespace mapping: point directly to the live credentials using NAMESPACE/SECRET_NAME
                - '--src_credentials=NAMESPACE/SRC_SECRET_NAME'
                - '--dst_credentials=NAMESPACE/DST_SECRET_NAME'
                # Point to the CA certificate Secret created in the destination namespace
                - '--src_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
                - '--dst_ca_certificate_reference=NAMESPACE/CA_CERT_SECRET'
                - '--src_type=s3'
                - '--dst_type=s3'
                - '--bandwidth_limit=BANDWIDTH_LIMIT' # Optional. Examples: '10K', '100M', '1G'
          restartPolicy: OnFailure
---

데이터 전송 모니터링

작업을 인스턴스화한 후 kubectl 명령어를 사용하여 상태를 모니터링할 수 있습니다. 예를 들면 kubectl describe입니다. 전송을 확인하려면 대상 버킷 내의 객체를 나열하여 데이터가 전송되었는지 확인합니다. 데이터 전송 도구는 전송과 관련된 엔드포인트의 위치와 무관합니다.

다음 명령어를 실행하여 워크로드의 상태를 확인합니다.

# If you created a one-time Job:
kubectl describe job transfer-job -n NAMESPACE

# If you created a scheduled CronJob:
kubectl describe cronjob transfer-cronjob -n NAMESPACE

위 명령어는 작업의 상태를 알려줍니다.

작업은 포드에 데이터를 전송하라는 메시지를 표시합니다. 포드의 이름을 가져오고 로그를 확인하여 전송 중에 오류가 있는지 확인할 수 있습니다.

포드 로그를 보려면 다음을 실행합니다.

# 1. First, find the exact pod name generated by your Job
kubectl get pods -n NAMESPACE | grep transfer

# 2. Then, view the logs for that specific pod
kubectl logs POD_NAME -n NAMESPACE

성공한 작업 로그:

DEBUG : Starting main for transfer
I0607 21:34:39.183106       1 transfer.go:103]  "msg"="Starting transfer "  "destination"="sample-bucket" "source"="/data"
2023/06/07 21:34:39 NOTICE: Bandwidth limit set to {100Mi 100Mi}
I0607 21:34:49.238901       1 transfer.go:305]  "msg"="Job finished polling "  "Finished"=true "Number of Attempts"=2 "Success"=true
I0607 21:34:49.239675       1 transfer.go:153]  "msg"="Transfer completed."  "AvgSpeed"="10 KB/s" "Bytes Moved"="10.0 kB" "Errors"=0 "Files Moved"=10 "FilesComparedAtSourceAndDest"=3 "Time since beginning of transfer"="1.0s"

로그를 보면 사용된 대역폭, 이동된 바이트, 오류가 발생한 파일 수, 이동된 파일 수와는 다른 데이터 전송 속도를 확인할 수 있습니다.

블록 스토리지를 객체 스토리지로 복사

다음과 같은 사전 요구사항을 충족하는지 확인합니다.

  • 데이터를 전송하려는 전용 버킷에 대한 쓰기 권한이 있는 S3 키 ID 및 보안 비밀 액세스 키가 있는 S3 엔드포인트
  • S3 엔드포인트에 연결된 작동 중인 클러스터
  • 클러스터 내에서 작업 및 보안 비밀을 만들 수 있는 권한
  • 블록 스토리지 복제의 경우 객체 스토리지에 백업하려는 연결된 PersistentVolumeClaim (PVC)이 있는 포드와 실행 중인 작업 및 PVC를 검사할 수 있는 권한
  • 블록 스토리지 복제의 경우 PersistentVolume (PV)에 쓰기가 발생하지 않는 기간
  • 객체 스토리지 엔드포인트에서 블록 스토리지를 복원하는 경우 충분한 용량으로 PV를 할당할 수 있는 권한

PV를 객체 스토리지에 복제하려면 기존 포드에 볼륨을 연결해야 합니다. 전송 기간 동안 포드는 쓰기를 수행해서는 안 됩니다. 마운트된 PV가 작업에서 분리되지 않도록 하기 위해 데이터 전송 프로세스는 포드와 동일한 머신에서 전송 작업을 실행하고 hostPath 마운트를 사용하여 디스크의 볼륨을 노출하는 방식으로 작동합니다. 전송을 준비하려면 먼저 포드가 실행 중인 노드와 노드의 적절한 경로를 참조하기 위한 포드 UID 및 PVC 유형과 같은 추가 메타데이터를 찾아야 합니다. 다음 섹션에 설명된 샘플 YAML 파일에 이 메타데이터를 대체해야 합니다.

메타데이터 수집

데이터 전송 작업을 만드는 데 필요한 메타데이터를 수집하려면 다음 단계를 따르세요.

  1. 예약된 포드가 있는 노드를 찾습니다.

    kubectl get pod POD_NAME -o jsonpath='{.spec.nodeName}'
    

    이 명령어의 출력을 데이터 전송 작업 YAML 파일에서 사용할 NODE_NAME to 으로 기록합니다.

  2. 포드 UID를 찾습니다.

    kubectl get pod POD_NAME -o 'jsonpath={.metadata.uid}'
    

    이 명령어의 출력을 데이터 전송 작업 YAML 파일에서 사용할 POD_UID to 로 기록합니다.

  3. PVC 이름을 찾습니다.

    kubectl get pvc www-web-0 -o 'jsonpath={.spec.volumeName}'
    

    이 명령어의 출력을 데이터 전송 작업 YAML 파일에서 사용할 PVC_NAME to 으로 기록합니다.

  4. PVC 스토리지 프로비저너를 찾습니다.

    kubectl get pvc www-web-0 -o jsonpath='{.metadata.annotations.volume\.v1\.kubernetes\.io\/storage-provisioner}'
    

    이 명령어의 출력을 데이터 전송 작업 YAML 파일에서 사용할 PROVISIONER_TYPE으로 기록합니다.

보안 비밀 만들기

클러스터 간에 파일을 객체 스토리지에 복제하려면 먼저 Kubernetes 클러스터 내에서 보안 비밀을 인스턴스화해야 합니다. 도구가 사용자 인증 정보를 가져오려면 보안 비밀 데이터에 일치하는 키를 사용해야 합니다.

기존 네임스페이스에서 전송을 수행하려면 transfer 네임스페이스에서 보안 비밀을 만드는 다음 예를 참고하세요.

apiVersion: v1
kind: Secret
metadata:
  name: src-secret
  namespace: transfer
data:
  access-key-id: c3JjLWtleQ== # echo -n src-key| base64 -w0
  access-key: c3JjLXNlY3JldA== # echo -n src-secret| base64 -w0
---
apiVersion: v1
kind: Secret
metadata:
  name: dst-secret
  namespace: transfer
data:
  access-key-id: ZHN0LWtleQ== # echo -n dst-key| base64 -w0
  access-key: ZHN0LXNlY3JldA== # echo -n dst-secret| base64 -w0

작업 만들기

이전 섹션에서 수집한 데이터를 사용하여 데이터 전송 도구로 작업을 만듭니다. 데이터 전송 작업에는 관심 있는 PV의 경로를 참조하는 hostPath 마운트와 관련 노드의 nodeSelector가 있습니다.

다음은 데이터 전송 작업의 예입니다.

apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: transfer
spec:
  template:
    spec:
      nodeSelector: NODE_NAME
      serviceAccountName: data-transfer-sa
      containers:
      - name: storage-transfer-pod
        image: storage-transfer
        command:
        - /storage-transfer
        args:
        - --dst_endpoint=https://your-dst-endpoint.com
        - --src_path=/pvc-data
        - --dst_path=transfer-dst-bucket
        - --dst_credentials=transfer/dst-secret
        - --src_type=local
        - --dst_type=s3
      volumeMounts:
      - mountPath: /pvc-data
        name: pvc-volume
      volumes:
      - name: pvc-volume
      hostPath:
        path: /var/lib/kubelet/pods/POD_UID/volumes/PROVISIONER_TYPE/PVC_NAME
      restartPolicy: Never

S3 데이터 전송과 마찬가지로 Kubernetes 클러스터에서 대상 엔드포인트의 액세스 키가 포함된 보안 비밀 을 만들어야 하며 데이터 전송 작업은 API 서버에서 보안 비밀을 읽을 수 있는 적절한 권한이 있는 서비스 계정으로 실행되어야 합니다. 작업에서 작동하는 표준 kubectl 명령어를 사용하여 전송 상태를 모니터링합니다.

블록 스토리지를 객체 스토리지로 전송할 때는 다음 세부정보를 고려하세요.

  • 기본적으로 심볼릭 링크는 객체 스토리지를 따르고 복제하지만 얕은 복사 대신 전체 복사가 수행됩니다. 복원 시 심볼릭 링크가 삭제됩니다.
  • 객체 스토리지 복제와 마찬가지로 버킷의 하위 디렉터리로 클로닝하면 파괴됩니다. 버킷이 볼륨에만 사용할 수 있는지 확인합니다.

객체 스토리지에서 블록 스토리지로 복원

PV 할당

객체 스토리지 엔드포인트에서 블록 스토리지를 복원하려면 다음 단계를 따르세요.

  1. 복원에서 대상으로 영구 볼륨을 할당합니다. 다음 예와 같이 PVC를 사용하여 볼륨을 할당합니다.

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: restore-pvc
      namespace: restore-ns
    spec:
      storageClassName: "default"
      accessModes:
    ReadWriteOnce
      resources:
        requests:
          storage: 1Gi # Need sufficient capacity for full restoration.
    
  2. PVC의 상태를 확인합니다.

    kubectl get pvc restore-pvc -n restore-ns
    

    PVC가 Bound 상태가 되면 다시 하이드레이션하는 포드 내에서 사용할 준비가 된 것입니다.

  3. StatefulSet이 결국 PV를 사용하는 경우 렌더링된 StatefulSet PVC와 일치해야 합니다. StatefulSet이 생성하는 포드는 하이드레이션된 볼륨을 사용합니다. 다음 예는 ss라는 StatefulSet의 볼륨 클레임 템플릿을 보여줍니다.

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. 결과 포드가 사전 할당된 볼륨을 사용하도록 ss-pvc-name-0ss-pvc-name-1과 같은 이름으로 PVC를 사전 할당합니다.

PV 하이드레이션

PVC가 PV에 결합된 후 작업을 시작하여 PV를 채웁니다.

apiVersion: batch/v1
kind: Job
metadata:
  name: transfer-job
  namespace: transfer
spec:
  template:
    spec:
      serviceAccountName: data-transfer-sa
      volumes:
      - name: data-transfer-restore-volume
        persistentVolumeClaim:
          claimName: restore-pvc
      containers:
      - name: storage-transfer-pod
        image: storage-transfer
        command:
        - /storage-transfer
        args:
        - --src_endpoint=https://your-src-endpoint.com
        - --src_path=/your-src-bucket
        - --src_credentials=transfer/src-secret
        - --dst_path=/restore-pv-mnt-path
        - --src_type=s3
        - --dst_type=local
      volumeMounts:
      - mountPath: /restore-pv-mnt-path
        name: data-transfer-restore-volume

작업이 완료되면 객체 스토리지 버킷의 데이터가 볼륨을 채웁니다. 별도의 포드는 볼륨을 마운트하는 동일한 표준 메커니즘을 사용하여 데이터를 사용할 수 있습니다.