将 Cloud Storage 存储分区作为 CSI 临时卷装载


本指南介绍了如何使用由 Cloud Storage 存储分区支持的 CSI 临时卷,在 Google Kubernetes Engine (GKE) 上自动管理 Kubernetes PodJob 的存储资源。CSI 临时卷与 Pod 或作业生命周期相关联,您无需手动处理 PersistentVolume 和 PersistentVolumeClaim 对象。

本指南适用于希望简化 GKE 应用存储空间管理的平台管理员和运维人员。

在阅读本页内容之前,请确保您熟悉 CSI 临时卷、Kubernetes Pod 和作业以及 Cloud Storage 存储分区。

如果您已经熟悉 PersistentVolume,并且希望与依赖于此资源类型的现有部署保持一致,请参阅将 Cloud Storage 存储分区挂载为永久性卷

准备工作

请确保您已满足以下前提条件:

Cloud Storage 存储分区的 CSI 临时存储空间的运作方式

CSI 临时卷可简化 GKE 上应用的存储管理。您可以直接在 Pod 或作业规范中定义 CSI 临时卷。使用 CSI 临时卷可消除对单独的 PersistentVolume 和 PersistentVolumeClaim 对象的需求。

使用 CSI 临时卷涉及以下操作:

  1. 存储空间定义:您可以在 Pod 或作业的 YAML 文件中指定存储空间,包括要使用的 CSI 驱动程序和所有必需的参数。对于 Cloud Storage FUSE CSI 驱动程序,您需要指定存储桶名称和其他相关详细信息。

    (可选)您可以使用文件缓存功能来微调 CSI 驱动程序的性能。文件缓存可通过在速度更快的磁盘上缓存经常访问的 Cloud Storage 文件来提升 GKE 应用性能。

    此外,您还可以使用并行下载功能加速从 Cloud Storage 读取大文件,以进行多线程下载。您可以使用此功能来缩短模型加载时间,尤其是对于大小超过 1 GB 的读取操作。

  2. 驱动程序调用:当您创建 Pod 或作业时,GKE 会检测临时卷请求并调用 Cloud Storage FUSE CSI 驱动程序。

  3. 卷挂载和附加:CSI 驱动程序会挂载 CSI 临时卷(指向底层 Cloud Storage 存储桶),并将其提供给 Pod 或作业,以便应用可以访问该卷。如需微调存储分区在文件系统中的装载方式,您可以使用装载选项。您还可以使用卷属性来配置 Cloud Storage FUSE CSI 驱动程序的特定行为。

  4. 生命周期管理:临时卷在 Pod 或作业的生命周期内存在。当 Pod 被删除或作业完成时,CSI 驱动程序会自动处理清理并卸载卷。

挂接 CSI 临时卷

请按照以下说明操作,具体取决于您是希望将 CSI 临时卷附加到 Pod 还是作业。

Pod

如需在 Pod 中附加 CSI 临时卷,请按以下步骤操作:

  1. 创建一个具有以下规范的 Pod YAML 清单:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-ephemeral 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true" 
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: busybox
        name: busybox
        command: ["sleep"]
        args: ["infinity"] 
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
          readOnly: true
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          readOnly: true
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs" 
    

    替换以下值:

    • NAMESPACE:您要部署 Pod 的 Kubernetes 命名空间。
    • KSA_NAME:您在配置对 Cloud Storage 存储分区的访问权限时指定的 Kubernetes ServiceAccount 的名称。
    • BUCKET_NAME:您在配置对 Cloud Storage 存储桶的访问权限时指定的 Cloud Storage 存储桶名称。您可以指定下划线 (_) 以装载 Kubernetes ServiceAccount 可以访问的所有存储分区。如需了解详情,请参阅 Cloud Storage FUSE 文档中的动态装载

    示例清单显示了以下必需设置:

    • metadata.annotations:注解 gke-gcsfuse/volumes: "true" 是必需的。如需了解可选注解,请参阅配置 Sidecar 容器
    • spec.volumes[n].csi.driver:使用 gcsfuse.csi.storage.gke.io 作为 CSI 驱动程序名称。

    (可选)您可以调整以下变量:

    • spec.terminationGracePeriodSeconds:默认情况下,该值设置为 30。如果您需要将大型文件写入 Cloud Storage 存储桶,请提高此值,以确保 Cloud Storage FUSE 有足够的时间在应用退出后清空数据。如需了解详情,请参阅 Kubernetes 最佳实践:安全终止
    • spec.volumes[n].csi.volumeAttributes.mountOptions:将挂载选项传递给 Cloud Storage FUSE。在一个字符串中指定标志,以英文逗号分隔,不带空格。
    • spec.volumes[n].csi.volumeAttributes:将其他卷属性传递给 Cloud Storage FUSE。
    • spec.volumes[n].csi.readOnly:如果所有卷装载都是只读的,请指定 true。
    • spec.containers[n].volumeMounts[m].readOnly:如果仅有特定的卷装载是只读的,请指定 true。
  2. 运行以下命令以将该清单应用于集群:

    kubectl apply -f FILE_PATH
    

    FILE_PATH 替换为 YAML 文件的路径。

Pod(文件缓存)

如需在 Pod 中附加具有文件缓存的 CSI 临时卷,请按以下步骤操作:

  1. 按照创建具有本地 SSD 支持的临时存储空间的集群或节点池中的步骤,创建具有本地 SSD 支持的临时存储空间的集群或节点池。

  2. 创建一个具有以下规范的 Pod YAML 清单:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-file-cache-example 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/ephemeral-storage-limit: "50Gi" 
    spec:
      nodeSelector:
        cloud.google.com/gke-ephemeral-storage-local-ssd: "true"
      restartPolicy: Never
      initContainers:
      - name: data-loader
        image: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 1Gi
        command:
          - "/bin/sh"
          - "-c"
          - |
            mkdir -p /test_files
            for i in $(seq 1 1000); do dd if=/dev/zero of=/test_files/file_$i.txt bs=1024 count=64; done
            gcloud storage cp /test_files gs://BUCKET_NAME --recursive
      containers:
      - name: data-validator
        image: busybox
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 500m
            memory: 512Mi
        command:
          - "/bin/sh"
          - "-c"
          - |
            echo "first read with cache miss"
            time cat /data/test_files/file_* > /dev/null
    
            echo "second read from local cache"
            time cat /data/test_files/file_* > /dev/null 
        volumeMounts:
        - name: gcs-fuse-csi-ephemeral
          mountPath: /data
      serviceAccountName: KSA_NAME
      volumes:
      - name: gcs-fuse-csi-ephemeral
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs,file-cache:max-size-mb:-1"
    

    替换以下值:

    • NAMESPACE:您要部署 Pod 的 Kubernetes 命名空间。
    • KSA_NAME:您在配置对 Cloud Storage 存储分区的访问权限时指定的 Kubernetes ServiceAccount 的名称。
    • BUCKET_NAME:您在配置对 Cloud Storage 存储桶的访问权限时指定的 Cloud Storage 存储桶名称。您可以指定下划线 (_) 以装载 Kubernetes ServiceAccount 可以访问的所有存储分区。如需了解详情,请参阅 Cloud Storage FUSE 文档中的动态装载

      在示例清单中,init 容器 data-loader 会生成 1,000 个大小为 64 KiB 的文件,并将这些文件上传到 Cloud Storage 存储桶。主容器 data-validator 会从存储桶读取所有文件两次,并记录时长。

  3. 运行以下命令以将该清单应用于集群:

    kubectl apply -f FILE_PATH
    

    FILE_PATH 替换为 YAML 文件的路径。

  4. 如需查看日志输出,请运行以下命令:

    kubectl logs -n NAMESPACE gcs-fuse-csi-file-cache-example -c data-validator
    

    NAMESPACE 替换为工作负载的命名空间。

    输出应类似如下所示:

    first read with cache miss
    real    0m 54.68s
    ...
    second read from local cache
    real    0m 0.38s
    ...
    

    输出结果显示,使用本地缓存的第二次读取比缓存未命中的第一次读取快得多。

Pod(并行下载)

如需在 Pod 中附加具有并行下载功能的 CSI 临时卷,请按以下步骤操作:

  1. 创建一个具有以下规范的 Pod YAML 清单:

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-ephemeral 
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/ephemeral-storage-limit: "50Gi" 
    spec:
      containers:
      ...
      volumes:
      - name: gcs-fuse-csi-ephemeral 
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: BUCKET_NAME
            mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:max-size-mb:-1"
            fileCacheCapacity: "-1"
    

    替换以下值:

    • NAMESPACE:您要部署 Pod 的 Kubernetes 命名空间。
    • BUCKET_NAME:您在配置对 Cloud Storage 存储桶的访问权限时指定的 Cloud Storage 存储桶名称。您可以指定下划线 (_) 以装载 Kubernetes ServiceAccount 可以访问的所有存储分区。如需了解详情,请参阅 Cloud Storage FUSE 文档中的动态装载
  2. 运行以下命令以将该清单应用于集群:

    kubectl apply -f FILE_PATH
    

    FILE_PATH 替换为 YAML 文件的路径。

作业

如需在作业中附加 CSI 临时卷,请按以下步骤操作:

  1. 使用以下规范创建作业 YAML 清单:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gcs-fuse-csi-job-example 
      namespace: NAMESPACE 
    spec:
      template:
        metadata: 
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          serviceAccountName: KSA_NAME 
          containers:
          - name: writer
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - touch /data/test && echo $(date) >> /data/test && sleep 10
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
          - name: reader
            image: busybox
            command:
              - "/bin/sh"
              - "-c"
              - sleep 10 && cat /data/test 
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
              readOnly: true
          volumes:
          - name: gcs-fuse-csi-ephemeral
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: BUCKET_NAME
          restartPolicy: Never 
      backoffLimit: 1
    

    替换以下值:

    • NAMESPACE:您部署 Pod 的 Kubernetes 命名空间。
    • KSA_NAME:您在配置对 Cloud Storage 存储分区的访问权限时指定的 Kubernetes ServiceAccount 的名称。
    • BUCKET_NAME:您在配置对 Cloud Storage 存储桶的访问权限时指定的 Cloud Storage 存储桶名称。您可以指定下划线 (_) 以装载 Kubernetes ServiceAccount 可以访问的所有存储分区。如需了解详情,请参阅 Cloud Storage FUSE 文档中的动态装载

    示例清单显示了以下必需设置:

    • metadata.annotations:注解 gke-gcsfuse/volumes: "true" 是必需的。如需了解可选注解,请参阅配置 Sidecar 容器
    • spec.volumes[n].csi.driver:使用 gcsfuse.csi.storage.gke.io 作为 CSI 驱动程序名称。

    (可选)您可以调整以下变量:

    • spec.volumes[n].csi.volumeAttributes.mountOptions:将挂载选项传递给 Cloud Storage FUSE。在一个字符串中指定标志,以英文逗号分隔,不带空格。
    • spec.volumes[n].csi.volumeAttributes:将其他卷属性传递给 Cloud Storage FUSE。
    • spec.volumes[n].csi.readOnly:如果所有卷装载都是只读的,请指定 true。
    • spec.containers[n].volumeMounts[m].readOnly:如果仅有特定的卷装载是只读的,请指定 true。
  2. 运行以下命令以将该清单应用于集群:

    kubectl apply -f FILE_PATH
    

    FILE_PATH 替换为 YAML 文件的路径。

问题排查

如需排查 Cloud Storage FUSE 问题,您可以将 log-severity 标志设置为 TRACE。您可以在部署 YAML 中驱动程序容器规范的 args 部分设置此标志。这会导致 gcsfuseLoggingSeverity 卷属性自动设置为“trace”。

如需查看其他问题排查提示,请参阅 GitHub 项目文档中的问题排查指南

后续步骤