将原有永久性磁盘用作 PersistentVolume


本页面介绍如何使用填充了数据的原有永久性磁盘创建 PersistentVolume,以及如何在 pod 中使用 PersistentVolume。

概览

有两种常见场景使用现有的永久性磁盘。

本页面中的示例使用现有的 Compute Engine 永久性磁盘

虽然 ext4 是默认文件系统类型,但只要节点映像支持永久性磁盘,您就可以将现有永久性磁盘用于 xfs 文件系统。如需使用 xfs 磁盘,请在 PersistentVolume 清单中将 spec.csi.fsType 更改为 xfs

Windows 不支持 ext4 文件系统类型。您必须为 Windows Server 节点池使用 NTFS 文件系统。如需使用 NTFS 磁盘,请在 PersistentVolume 清单中将 spec.csi.fsType 更改为 NTFS

须知事项

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

使用绑定到 PersistentVolume 的 PersistentVolumeClaim

要让容器访问现有的永久性磁盘,您需要执行以下操作:

  1. 将现有永久性磁盘预配为 PersistentVolume
  2. 将 PersistentVolume 绑定到 PersistentVolumeClaim。
  3. 向 pod 中的容器授予 PersistentVolume 访问权限。

创建 PersistentVolume 和 PersistentVolumeClaim

您可以通过多种方法将 PersistentVolumeClaim 绑定到特定 PersistentVolume。例如,以下 YAML 清单会创建新的 PersistentVolume 和 PersistentVolumeClaim,然后使用 claimRef 将声明绑定到卷,这可以确保此 PersistentVolume 只能绑定到该 PersistentVolumeClaim。

如需将 PersistentVolume 绑定到 PersistentVolumeClaim,两个资源的 storageClassName 以及 capacityaccessModesvolumeMode 必须匹配。您可以省略 storageClassName,但必须指定 "" 以防止 Kubernetes 使用默认的 StorageClass。

storageClassName 不需要引用现有 StorageClass 对象。如果您只需要将声明绑定到卷,则可以使用所需的任何名称。但是,如果您需要由 StorageClass 配置的额外功能(如卷大小调整),则 storageClassName 必须引用现有 StorageClass 对象。

如需了解详情,请参阅有关 PersistentVolume 的 Kubernetes 文档

  1. 保存以下 YAML 清单:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: PV_NAME
    spec:
      storageClassName: "STORAGE_CLASS_NAME"
      capacity:
        storage: DISK_SIZE
      accessModes:
        - ReadWriteOnce
      claimRef:
        namespace: default
        name: PV_CLAIM_NAME
      csi:
        driver: pd.csi.storage.gke.io
        volumeHandle: DISK_ID
        fsType: FS_TYPE
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      namespace: default
      name: PV_CLAIM_NAME
    spec:
      storageClassName: "STORAGE_CLASS_NAME"
      volumeName: PV_NAME
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: DISK_SIZE
    

    请替换以下内容:

    • PV_NAME:新 PersistentVolume 的名称。
    • STORAGE_CLASS_NAME:新 StorageClass 的名称。
    • DISK_SIZE:您的原有永久性磁盘的大小。例如 500G
    • PV_CLAIM_NAME:新 PersistentVolumeClaim 的名称。
    • DISK_ID:现有永久性磁盘的标识符。格式为 projects/{project_id}/zones/{zone_name}/disks/{disk_name}(对于区域永久性磁盘),或 projects/{project_id}/regions/{region_name}/disks/{disk_name}(对于区域永久性磁盘)。
    • FS_TYPE:文件系统类型。您可以保留默认值 (ext4),或使用 xfs。如果您的集群使用 Windows Server 节点池,则必须将其更改为 NTFS
  2. 要应用配置并创建 PersistentVolume 和 PersistentVolumeClaim 资源,请运行以下命令:

    kubectl apply -f FILE_PATH
    

    FILE_PATH 替换为 YAML 文件的路径。

在 pod 中使用 PersistentVolume

创建并绑定 PersistentVolume 和 PersistentVolumeClaim 后,您可以通过在 volumeMounts 字段中指定值来授予 Pod 的容器访问卷的权限。

以下 YAML 配置会创建一个新 Pod 和一个运行 nginx 映像的容器,然后在 Pod 上装载 PersistentVolume:

kind: Pod
apiVersion: v1
metadata:
  name: POD_NAME
spec:
  volumes:
    - name: VOLUME_NAME
      persistentVolumeClaim:
        claimName: PV_CLAIM_NAME
  containers:
    - name: CONTAINER_NAME
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: VOLUME_NAME

请替换以下内容:

  • POD_NAME:新 Pod 的名称。
  • VOLUME_NAME:卷的名称。
  • PV_CLAIM_NAME:您在上一步中创建的 PersistentVolumeClaim 的名称。
  • CONTAINER_NAME:新容器的名称。

应用配置:

kubectl apply -f FILE_PATH

FILE_PATH 替换为 YAML 文件的路径。

如需验证卷是否已装载,请运行以下命令:

kubectl describe pods POD_NAME

在输出中,检查此 PersistentVolumeClaim 是否已装载:

...
Volumes:
  VOLUME_NAME:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  PV_CLAIM_NAME
    ReadOnly:   false
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
  Normal  Scheduled               29s   default-scheduler        Successfully assigned default/POD_NAME to gke-cluster-1-default-pool-d5cde866-o4g4
  Normal  SuccessfulAttachVolume  21s   attachdetach-controller  AttachVolume.Attach succeeded for volume "PV_NAME"
  Normal  Pulling                 19s   kubelet                  Pulling image "nginx"
  Normal  Pulled                  19s   kubelet                  Successfully pulled image "nginx"
  Normal  Created                 18s   kubelet                  Created container CONTAINER_NAME
  Normal  Started                 18s   kubelet                  Started container CONTAINER_NAME

在 StatefulSet 中使用先前存在的磁盘

您可以通过 PersistentVolume,使用 StatefulSet 中已有的 Compute Engine 永久性磁盘。StatefulSet 会自动为每个副本生成 PersistentVolumeClaim。您可以使用 claimRef 预测生成的 PersistentVolumeClaim 的名称,并将其绑定到 PersistentVolume。

在以下示例中,您将采用两个已有的永久性磁盘,创建 PersistentVolume 以使用磁盘,然后将卷装载到默认命名空间中具有两个副本的 StatefulSet。

  1. 确定新 StatefulSet 的名称、PersistentVolumeClaim 模板的名称以及 StatefulSet 中的副本数。
  2. 确定自动生成的 PersistentVolumeClaim 名称。StatefulSet 为 PersistentVolumeClaim 名称使用以下格式:

    PVC_TEMPLATE_NAME-STATEFULSET_NAME-REPLICA_INDEX
    

    请替换以下内容:

    • PVC_TEMPLATE_NAME:新 PersistentVolumeClaim 模板的名称。
    • STATEFULSET_NAME:新 StatefulSet 的名称。
    • REPLICA_INDEX:StatefulSet 副本的索引。此示例使用的是 01
  3. 创建 PersistentVolume。您必须为 StatefulSet 中的每个副本各创建一个 PersistentVolume。

    1. 保存以下 YAML 清单:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-ss-demo-0
      spec:
        storageClassName: "STORAGE_CLASS_NAME"
        capacity:
          storage: DISK1_SIZE
        accessModes:
          - ReadWriteOnce
        claimRef:
          namespace: default
          name: PVC_TEMPLATE_NAME-STATEFULSET_NAME-0
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: DISK1_ID
          fsType: FS_TYPE
       ---
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-ss-demo-1
      spec:
        storageClassName: "STORAGE_CLASS_NAME"
        capacity:
          storage: DISK2_SIZE
        accessModes:
          - ReadWriteOnce
        claimRef:
          namespace: default
          name: PVC_TEMPLATE_NAME-STATEFULSET_NAME-1
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: DISK2_ID
          fsType: FS_TYPE
      

      替换以下内容:

      • DISK1_SIZE and DISK2_SIZE:您的现有永久性磁盘的大小。
      • DISK1_ID and DISK2_ID:现有永久性磁盘的标识符。
      • PVC_TEMPLATE_NAME-STATEFULSET_NAME-0 and PVC_TEMPLATE_NAME-STATEFULSET_NAME-1:自动生成的 PersistentVolumeClaim 的名称,采用上一步中定义的格式。
      • STORAGE_CLASS_NAME:StorageClass 的名称。
    2. 应用配置:

      kubectl apply -f FILE_PATH
      

      FILE_PATH 替换为 YAML 文件的路径。

  4. 使用您在第 1 步中选择的值创建 StatefulSet。确保您在 volumeClaimTemplates 中指定的存储空间小于或等于 PersistentVolume 的总容量。

    1. 保存以下 YAML 清单:

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: STATEFULSET_NAME
      spec:
        selector:
          matchLabels:
            app: nginx
        serviceName: "nginx"
        replicas: 2
        template:
          metadata:
            labels:
              app: nginx
          spec:
            terminationGracePeriodSeconds: 10
            containers:
            - name: nginx
              image: registry.k8s.io/nginx-slim:0.8
              ports:
              - containerPort: 80
                name: web
              volumeMounts:
              - name: PVC_TEMPLATE_NAME
                mountPath: /usr/share/nginx/html
        volumeClaimTemplates:
        - metadata:
            name: PVC_TEMPLATE_NAME
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "STORAGE_CLASS_NAME"
            resources:
              requests:
                storage: 100Gi
      

      请替换以下内容:

      • STATEFULSET_NAME:新 StatefulSet 的名称。
      • PVC_TEMPLATE_NAME:新 PersistentVolumeClaim 模板的名称。
      • STORAGE_CLASS_NAME:StorageClass 的名称。
    2. 应用配置:

      kubectl apply -f FILE_PATH
      

      FILE_PATH 替换为 YAML 文件的路径。

后续步骤