数据可以在以下位置之间转移:
- 永久性卷声明 (PVC) 和对象存储
- 对象存储和对象存储(在 GDC 内)
GDC 上的对象存储与 S3 兼容,在 Kubernetes YAML 中称为 s3 类型。
数据源/目标类型
- 对象存储(称为“s3”):GDC 上存在的对象存储
- 本地存储(称为“local”):挂接的 PVC 上的存储
从对象存储复制到对象存储
请确保您满足以下前提条件:
- 一个具有源读取权限的 S3 端点,以及一个具有目标写入权限的 s3 端点。
- 如果您没有使用凭据创建存储桶的权限,则如果目标存储桶不存在,转移会失败。如果出现这种情况,请确保目标存储桶存在。
- 在集群或命名空间内创建作业和创建或读取 Secret 的权限。如需查看权限,请参阅以下示例。
创建作业
如需创建作业,请完成以下步骤:
创建命名空间:
apiVersion: v1 kind: Namespace metadata: name: transfer-ns创建凭据:
--- 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 ---这些凭据与您在对象存储部分中获取的凭据相同。
创建一个供转移作业使用的服务帐号 (SA),然后使用角色和角色绑定向该账号添加权限,以读取和写入 Secret。如果您的默认命名空间 SA 或自定义 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 ---获取对象存储系统的 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. ---可选:创建一个 LoggingTarget,以便在 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创建作业:
--- 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. ---
监控数据转移
实例化作业后,您可以使用 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 密钥 ID 和私有访问密钥,并且至少具有对您要将数据转移到的专用存储桶的写入权限。
- 一个可正常运行的集群,并且可以连接到 S3 端点。
- 在集群内创建作业和 Secret 的权限。
- 如需复制块存储,请使用一个挂接了
PersistentVolumeClaim(PVC) 的 pod,该 PVC 是您要备份到对象存储的 PVC,并且具有检查正在运行的作业和 PVC 的权限。 - 如需复制块存储,请使用一个在其中不向
PersistentVolume(PV) 执行任何写入操作的时间窗口。 - 如需从对象存储端点恢复块存储,请使用分配具有足够容量的 PV 的权限。
如需将 PV 复制到对象存储,您必须将卷挂接到现有 pod。在转移时间窗口内,pod 不得执行任何写入操作。为避免从作业中分离已挂载的 PV,数据转移过程的工作方式是在与 pod 相同的机器上运行转移作业,并使用 hostPath 挂载来公开磁盘上的卷。在准备转移时,您必须先找到 pod 运行所在的节点,以及其他元数据(例如 pod UID 和 PVC 类型),以便引用节点上的相应路径。您必须将此元数据替换为下一部分中介绍的示例 YAML 文件。
收集元数据
如需收集创建数据转移作业所需的元数据,请完成以下步骤:
找到具有已安排的 pod 的节点:
kubectl get pod POD_NAME -o jsonpath='{.spec.nodeName}'将此命令的输出记录为 NODE_NAME,以便 在数据转移作业 YAML 文件中使用。
找到 pod UID:
kubectl get pod POD_NAME -o 'jsonpath={.metadata.uid}'将此命令的输出记录为 POD_UID,以便在数据转移作业 YAML 文件中 使用。
找到 PVC 名称:
kubectl get pvc www-web-0 -o 'jsonpath={.spec.volumeName}'将此命令的输出记录为 PVC_NAME,以便 在数据转移作业 YAML 文件中使用。
找到 PVC 存储预配器:
kubectl get pvc www-web-0 -o jsonpath='{.metadata.annotations.volume\.v1\.kubernetes\.io\/storage-provisioner}'将此命令的输出记录为 PROVISIONER_TYPE,以便在数据转移作业 YAML 文件中使用。
创建 Secret
如需跨集群将文件复制到对象存储,您必须先在 Kubernetes 集群内实例化 Secret。您必须为 Secret 数据使用匹配的密钥,以便该工具提取凭据。
如需在现有命名空间中执行转移,请参阅以下在 transfer 命名空间中创建 Secret 的示例:
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
集群中创建一个包含目标端点的访问密钥的 Secret
,并且数据转移作业必须使用具有足够权限从 API 服务器读取 Secret 的服务帐号运行。使用对作业运行的标准 kubectl 命令监控转移的状态。
将块存储转移到对象存储时,请考虑以下详细信息:
- 默认情况下,符号链接会遵循并复制到对象存储,但会执行深层复制而非浅层复制。恢复后,它会销毁符号链接。
- 与对象存储复制一样,克隆到存储桶的子目录具有破坏性。确保存储桶专供您的卷使用。
从对象存储恢复到块存储
分配 PV
如需从对象存储端点恢复块存储,请按以下步骤操作:
分配一个永久性卷以作为恢复的目标。使用 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.检查 PVC 的状态:
kubectl get pvc restore-pvc -n restore-nsPVC 处于
Bound状态后,即可在重新水合它的 pod 内使用。如果 Stateful 集最终使用 PV,您必须匹配渲染的 StatefulSet PVC。StatefulSet 生成的 pod 会使用水合的卷。以下示例展示了名为
ss的 StatefulSet 中的卷声明模板。volumeClaimTemplates: - metadata: name: pvc-name spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "default" resources: requests: storage: 1Gi预分配名称(例如
ss-pvc-name-0和ss-pvc-name-1)的 PVC,以确保生成的 pod 使用预分配的卷。
水合 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
作业运行完毕后,对象存储桶中的数据会填充卷。单独的 pod 可以使用相同的标准机制来挂载卷,从而使用数据。