העברת נתונים

העברות נתונים יכולות להתבצע בין המקורות הבאים:

  1. דרישת נפח אחסון מתמיד (PVC) ואחסון אובייקטים
  2. אחסון אובייקטים ואחסון אובייקטים (ב-GDC)

אחסון האובייקטים ב-GDC תואם ל-S3 ומכונה סוג s3 בקובצי YAML של Kubernetes.

סוגים של מקורות או יעדים של נתונים

  1. אחסון אובייקטים (נקרא 's3'): אחסון אובייקטים שקיים ב-GDC
  2. אחסון מקומי (נקרא 'מקומי'): אחסון ב-PVC מצורפים

העתקה מאחסון אובייקטים לאחסון אובייקטים

חשוב לוודא שמתקיימות דרישות הסף הבאות:

  • נקודת קצה של S3 עם הרשאות קריאה למקור, ונקודת קצה של S3 עם הרשאות כתיבה ליעד.
  • אם לפרטי הכניסה אין הרשאה ליצור קטגוריה, ההעברה תיכשל אם קטגוריית היעד לא קיימת. אם זה המצב, צריך לוודא שקטגוריית היעד קיימת.
  • הרשאות ליצירת משימות וליצירה או לקריאה של סודות בתוך האשכול או מרחב השמות. בדוגמה הבאה מפורטות הרשאות.

יצירת משרה

כדי ליצור משרה, פועלים לפי השלבים הבאים:

  1. יוצרים מרחב שמות:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: transfer-ns
    
  2. יוצרים פרטי כניסה:

    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-secret
      namespace: transfer-ns
    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: transfer-ns
    data:
      access-key-id: NkFDTUg3WDBCVDlQMVpZMU5MWjU= # base 64 encoded version of key
      access-key: VkRkeWJsbFgzb2FZanMvOVpnSi83SU5YUjk3Y0Q2TUdxZ2d4Q3dpdw== # base 64 encoded version of secret key
    ---
    

    פרטי הכניסה האלה זהים לפרטי הכניסה שקיבלתם בקטע בנושא אחסון אובייקטים.

  3. יוצרים חשבון שירות (SA) שמשמש להעברה, ואז מוסיפים לחשבון הרשאות לקריאה ולכתיבה של סודות באמצעות תפקידים והקצאות תפקידים. אין צורך להוסיף הרשאות אם לחשבון שירות ברירת המחדל או לחשבון שירות מותאם אישית במרחב השמות שלכם כבר יש את ההרשאות האלה.

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: transfer-service-account
      namespace: transfer-ns
    ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: read-secrets-role
      namespace: transfer-ns
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    
    ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-secrets-rolebinding
      namespace: transfer-ns
    subjects:
    - kind: ServiceAccount
      name: transfer-service-account
      namespace: transfer-ns
    roleRef:
      kind: Role
      name: read-secrets-role
      apiGroup: rbac.authorization.k8s.io
    
    ---
    
  4. מקבלים את אישורי ה-CA של מערכות האחסון של האובייקטים. תוכלו לקבל את אותם אישורים מה-AO/PA שלכם.

    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: src-cert
      namespace: transfer-ns
    data:
      ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUpHM2psOFZhTU85a1FteGdXUFl3N3d3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF5TVRVd01USXlNakZhRncweQpNekExTVRZd01USXlNakZhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWI== # base 64 encoded version of certificate
    
    ---
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: dst-cert
      namespace: transfer-ns
    data:
      ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBekNDQWV1Z0F3SUJBZ0lSQUtoaEJXWWo3VGZlUUZWUWo0U0RpckV3RFFZSktvWklodmNOQVFFTEJRQXcKR3pFWk1CY0dBMVVFQXhNUVltOXZkSE4wY21Gd0xYZGxZaTFqWVRBZUZ3MHlNekF6TURZeU16TTROVEJhRncweQpNekEyTURReU16TTROVEJhTUJzeEdUQVhCZ05WQkFNVEVHSnZiM1J6ZEhKaGNDMTNaV0l0WTJFd2dnRWlNQTBHCkNTcUdTSWIzRFFF== # base 64 encoded version of certificate. Can be same OR different than source certificate.
    
    ---
    
    
  5. אופציונלי: יוצרים LoggingTarget כדי לראות את היומנים של transfer-service ב-Loki.

    apiVersion: logging.gdc.goog/v1
    kind: LoggingTarget
    metadata:
      namespace: transfer-ns # 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
    
  6. יוצרים את המשרה:

    ---
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: transfer-job
      namespace: transfer-ns
    spec:
      template:
        spec:
          serviceAccountName: transfer-service-account #service account created earlier
          containers:
            - name: storage-transfer-pod #
              image: gcr.io/private-cloud-staging/storage-transfer:latest
              imagePullPolicy: Always #will always pull the latest image
              command:
                - /storage-transfer
              args:
                - '--src_endpoint=objectstorage.zone1.google.gdch.test' #Your endpoint here
                - '--dst_endpoint=objectstorage.zone1.google.gdch.test' #Your endpoint here
                - '--src_path=aecvd-bucket1' #Please use Fully Qualified Name
                - '--dst_path=aklow-bucket2' #Please use Fully Qualified Name
                - '--src_credentials=transfer-ns/src-secret' #Created earlier
                - '--dst_credentials=transfer-ns/dst-secret' #Created earlier
                - '--dst_ca_certificate_reference=transfer-ns/dst-cert' #Created earlier
                - '--src_ca_certificate_reference=transfer-ns/src-cert' #Created earlier
                - '--src_type=s3'
                - '--dst_type=s3'
                - '--bandwidth_limit=10M' #Optional of the form '10K', '100M', '1G' bytes per second
          restartPolicy: OnFailure #Will restart on failure.
    ---
    

מעקב אחרי העברת הנתונים

אחרי שיוצרים מופע של Job, אפשר לעקוב אחרי הסטטוס שלו באמצעות פקודות kubectl, כמו kubectl describe. כדי לאמת את ההעברה, מפרטים את האובייקטים בתוך דלי היעד כדי לוודא שהנתונים הועברו. כלי העברת הנתונים לא תלוי במיקום של נקודות הקצה שמעורבות בהעברה.

מריצים את הפקודה הבאה:

kubectl describe transfer-job -n transfer-ns

הפקודה הקודמת מציגה את סטטוס העבודה.

העבודה גורמת להעברת הנתונים אל ה-pod. אפשר לקבל את שם ה-Pod ולעיין ביומנים כדי לראות אם יש שגיאות במהלך ההעברה.

כדי לראות את היומנים של ה-pod, מריצים את הפקודה הבאה:

kubectl logs transfer-job-<pod_id_suffix_obtained_from_describe_operation_on_job> -n transfer-ns

יומני משימות שהסתיימו בהצלחה:

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 עם מזהה מפתח S3 ומפתח גישה סודי עם הרשאות WRITE לפחות לקטגוריה הייעודית שאליה רוצים להעביר את הנתונים.
  • אשכול פעיל עם קישוריות לנקודת הקצה של S3.
  • הרשאות ליצירת משימות וסודות בתוך האשכול.
  • לשכפול של אחסון בלוקים, נדרש Pod עם PersistentVolumeClaim (PVC) מצורף שרוצים לגבות לאחסון אובייקטים, והרשאות לבדיקת משימות (Jobs) ו-PVCs שפועלים.
  • לשכפול של אחסון הבלוקים, נדרש חלון שבו לא מתבצעות פעולות כתיבה ל-PersistentVolume (PV).
  • לשחזור של אחסון בלוקים מנקודת קצה של אחסון אובייקטים, צריך הרשאות להקצאת PV עם קיבולת מספקת.

כדי לשכפל PV לאחסון אובייקטים, צריך לצרף נפח ל-Pod קיים. במהלך חלון ההעברה, אסור לבצע פעולות כתיבה ב-Pod. כדי למנוע את ניתוק ה-PV המצורף מהמשימה, תהליך העברת הנתונים פועל על ידי הרצת משימת ההעברה באותה מכונה שבה פועל ה-Pod, ושימוש ב-hostPath mount כדי לחשוף את הנפח בדיסק. כדי להתכונן להעברה, צריך קודם למצוא את הצומת שבו פועל ה-Pod, ומטא-נתונים נוספים כמו ה-UID של ה-Pod וסוג ה-PVC, כדי להפנות לנתיב המתאים בצומת. צריך להחליף את המטא-נתונים האלה בקובץ ה-YAML לדוגמה שמפורט בקטע הבא.

איסוף מטא-נתונים

כדי לאסוף את המטא-נתונים שנדרשים ליצירת משימת העברת הנתונים, צריך לפעול לפי השלבים הבאים:

  1. מוצאים את הצומת עם ה-Pod המתוזמן:

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

    מתעדים את הפלט של הפקודה הזו כ-NODE_NAME לשימוש בקובץ ה-YAML של משימת העברת הנתונים.

  2. מציאת ה-UID של ה-Pod:

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

    מתעדים את הפלט של הפקודה הזו כ-POD_UID לשימוש בקובץ ה-YAML של משימת העברת הנתונים.

  3. מאתרים את השם של ה-PVC:

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

    מתעדים את הפלט של הפקודה הזו כ-PVC_NAME לשימוש בקובץ ה-YAML של משימת העברת הנתונים.

  4. מחפשים את ספק האחסון של ה-PVC:

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

    צריך לתעד את הפלט של הפקודה הזו כ-PROVISIONER_TYPE כדי להשתמש בו בקובץ ה-YAML של משימת העברת הנתונים.

יצירת סודות

כדי לשכפל קובץ לאחסון אובייקטים בין אשכולות, צריך קודם ליצור מופע של הסודות באשכול 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

יצירת המשרה

בעזרת הנתונים שאספתם בקטע הקודם, יוצרים משימה באמצעות הכלי להעברת נתונים. למשימת העברת הנתונים יש hostPath mount שמפנה לנתיב של ה-PV הרלוונטי, ו-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, צריך ליצור Secret שמכיל את מפתחות הגישה לנקודת הקצה של היעד באשכול Kubernetes, ועבודת העברת הנתונים צריכה לפעול עם חשבון שירות שיש לו הרשאות מתאימות לקריאת ה-Secret משרת ה-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, הוא מוכן לשימוש בתוך ה-Pod שמבצע בו rehydration.

  3. אם בסופו של דבר קבוצת StatefulSet צורכת את ה-PV, צריך להתאים את ה-PVCs של StatefulSet שעברו עיבוד. קבוצות ה-Pod שנוצרות על ידי StatefulSet צורכות את הנפחים המאוחסנים. בדוגמה הבאה מוצגים תבניות של תביעות לשימוש בנפח אחסון ב-StatefulSet בשם ss.

      volumeClaimTemplates:
      - metadata:
          name: pvc-name
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "default"
          resources:
            requests:
              storage: 1Gi
    
  4. כדי לוודא שה-Pods שיתקבלו יצרכו את נפחי האחסון שהוקצו מראש, צריך להקצות מראש PVC עם שמות כמו ss-pvc-name-0 ו-ss-pvc-name-1.

הוספת נוזלים לתא הפוטו-וולטאי

אחרי ש-PVC נקשר ל-PV, מפעילים את ה-Job כדי לאכלס את ה-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

אחרי שהעבודה מסתיימת, הנתונים מדלי האחסון של האובייקטים מאכלסים את נפח האחסון. אפשר להשתמש באותם מנגנונים סטנדרטיים להוספת נפח אחסון כדי ש-Pod נפרד יוכל לצרוך את הנתונים.