动态存储

本主题介绍了如何使用持久卷和存储类为 Tanzu Kubernetes Grid (TKG) 工作负载集群实施动态存储。

概览:PersistentVolume、PersistentVolumeClaim 和 StorageClass

在 Kubernetes 集群中,PersistentVolume (PV) 对象为不受 Pod 生命周期影响的集群 Pod 提供共享存储。存储通过 PersistentVolumeClaim (PVC) 对象置备到 PV,该对象定义 Pod 访问底层存储的量和方式。有关信息,请参见 Kubernetes 文档中的持久卷

集群管理员可以定义 StorageClass 对象,使集群用户能够使用不同的存储类型和规则动态创建 PVC 和 PV 对象。Tanzu Kubernetes Grid 还提供默认 StorageClass 对象,允许用户在交钥匙环境中置备持久存储。

StorageClass 对象包括一个 provisioner 用于标识置备 PV 的内部或外部服务插件的字段;以及一个 parameters 字段,该字段将 Kubernetes 存储类与基础架构级别定义的存储选项(如 vSphere 中的虚拟机存储策略)相关联。有关信息,请参见 Kubernetes 文档中的存储类

支持的存储类型

Tanzu Kubernetes Grid 支持由 Kubernetes 内部(“树内”)或外部(“树外”)插件置备的不同存储类型的 StorageClass 对象。

存储类型

  • vSphere 云原生存储 (CNS)
  • Amazon EBS
  • Azure Disk
  • Azure File
  • iSCSI
  • NFS
注意

vSphere CSI 不支持 Storage DRS,但在 vSphere CSI 文档中 vSphere Container Storage 插件支持的 vSphere 功能中所述的条件下支持 Storage vMotion。

vSphere CSI 有条件支持 Storage vMotion,请阅读 CSI 文档以了解更多详细信息。

有关 vSphere CNS、Amazon EBS 和 Azure Disk 默认存储类,请参见默认存储类

外部置备

在 TKG v2.2 中,所有默认存储类都使用外部(“树外”)存储置备,而不是“树内”置备。

  • 存储类不随核心 Kubernetes 一起提供。
  • StorageClass 对象 provisioner 值不带有 kubernetes.io 前缀。
  • 置备器遵循外部存储的容器存储接口 (CSI) 标准。
  • 具有由先前版本的 TKG 部署的默认存储类的工作负载集群可能具有树内存储置备。请参见使用存储类创建持久卷

默认存储类

Tanzu Kubernetes Grid 提供了默认 StorageClass 对象,使工作负载集群用户可以在交钥匙环境中在其基础架构上置备持久性存储,而无需集群管理员创建的 StorageClass 对象。

在传递到 tanzu cluster create--file 选项的集群配置文件中 ENABLE_DEFAULT_STORAGE_CLASS 变量默认设置为 true,以便为工作负载集群启用默认存储类。

重要

请勿修改默认存储类定义。要自定义存储类,请使用不同的 name 而不是修改 TKG 创建的默认对象创建新的 StorageClass 定义。

Tanzu Kubernetes Grid 默认存储类定义为:

vSphere CNS

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: default
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: csi.vsphere.vmware.com
parameters:
  storagePolicyName: optional

请参见 Kubernetes 文档中的 vSphere CSI 存储类参数。

Amazon EBS

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: default
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com

请参见 AWS 文档中的 Amazon EBS CSI 驱动程序存储类参数。

Azure Disk

apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: default
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "true"
  labels:
    kubernetes.io/cluster-service: "true"
provisioner: disk.csi.azure.com
parameters:
  kind: Managed
  storageaccounttype: Standard_LRS
  cachingmode: ReadOnly
volumeBindingMode: WaitForFirstConsumer

请参见 Azure 文档中的 Azure Disk CSI 驱动程序存储类参数。

Azure File

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: azure-file
  labels:
    kubernetes.io/cluster-service: "true"
provisioner: file.csi.azure.com
mountOptions:
  - dir_mode=0777
  - file_mode=0777
  - uid=0
  - gid=0
  - mfsymlinks
  - cache=strict
  - actimeo=30
allowVolumeExpansion: true
parameters:
  skuName: Premium_LRS

请参见 Kubernetes 文档中的 Azure File 存储类参数。

设置 CNS 并创建存储策略 (vSphere)

vSphere 管理员可以根据 Tanzu Kubernetes Grid 集群用户的需求设置 vSphere CNS 并为虚拟磁盘 (VMDK) 存储创建存储策略。

您可以将 vSAN 或本地VMFS(虚拟机文件系统) 用于 Kubernetes 集群中的持久性存储,如下所示:

vSAN 存储

要在 vSphere Client 中为 vSAN 存储创建存储策略,请浏览到主页 (Home) > 策略和配置文件 (Policies and Profiles) > 虚拟机存储策略 (VM Storage Policies),然后单击创建 (Create) 以启动创建虚拟机存储策略 (Create VM Storage Policy) 向导。

按照 vSphere 文档中的创建存储策略中的说明进行操作。确保:

  • 策略结构 (Policy structure) 窗格中的数据存储特定规则 (Datastore specific rules) 下,选择为“vSAN”存储启用规则 (Enable rules for “vSAN” storage)
  • 配置其他窗格或根据需要接受默认值。
  • 将存储策略名称记录为 StorageClass 对象中的 storagePolicyName 值供参考。

本地 VMFS 存储

要为本地存储创建存储策略,请将标记应用于存储,并根据标记创建存储策略,如下所示:

  1. 从顶部 vSphere 菜单中,选择标记和自定义属性 (Tags & Custom Attributes)

  2. 标记 (Tags) 窗格中,选择类别 (Categories),然后单击新建 (New)

  3. 输入类别名称,例如 tkg-storage。使用复选框将其与数据中心 (Datacenter) 和存储对象(文件夹 (Folder)数据存储 (Datastore))相关联。单击创建 (Create)

  4. 从顶级存储 (Storage) 视图中,选择 VMFS 卷,然后在其总结 (Summary) 窗格中,单击标记 (Tags) > 分配 (Assign) …

  5. 分配标记 (Assign Tag) 弹出窗口中,单击添加标记 (Add Tag)

  6. 创建标记 (Create Tag) 弹出窗口中,为标记指定一个名称,例如 tkg-storage-ds1 并为其分配您创建的类别 (Category)。单击确定 (OK)

  7. 分配标记 (Assign Tag) 中,选择标记,然后单击分配 (Assign)

  8. 从顶级 vSphere 中,选择虚拟机存储策略 (VM Storage Policies) > 创建存储策略 (Create a Storage Policy)。配置向导将启动。

  9. 名称和描述 (Name and description) 窗格中,输入存储策略的名称。将存储策略名称记录为 StorageClass 对象中的 storagePolicyName 值供参考。

  10. 策略结构 (Policy structure) 窗格中的数据存储特定规则 (Datastore specific rules) 下,选择启用基于标记的放置规则 (Enable tag-based placement rules)

  11. 基于标记的放置 (Tag based placement) 窗格中,单击添加标记规则 (Add Tag Rule),然后配置:

    • 标记类别:选择类别名称
    • 使用情况选项 (Usage option)Use storage tagged with
    • 标记:浏览并选择标记名称
  12. 确认并配置其他窗格或根据需要接受默认值。,然后单击查看并完成 (Review and finish)完成 (Finish) 用于创建存储策略。

创建自定义存储类

集群管理员可以创建新的存储类,如下所示:

  1. 在 vSphere 上,选择或创建要用作 Kubernetes StorageClass 基础的虚拟机存储策略。
  2. 使用 provisionerparameters 和其他选项创建 StorageClass 配置.yaml
    • 在 vSphere 上,通过将 Kubernetes 存储类的 storagePolicyName 参数设置为 vSphere 存储策略名称(双引号字符串),将 Kubernetes 存储类与 vSphere 存储策略相关联。
  3. 将文件传递到 kubectl create -f
  4. 通过运行 kubectl describe storageclass <storageclass metadata.name> 验证存储类。

例如,请参见 Kubernetes 文档中的启用动态置备

有关 vSphere CSI 信息和资源,请参见 VMware vSphere Container Storage 常见文档

在集群中使用自定义存储类

要为不使用上述默认存储类之一的集群节点置备持久性存储,集群用户可在 Pod 配置中包含自定义存储类,如下所示:

  1. kubectl 的上下文设置为集群。例如:

    kubectl config use-context my-cluster-admin@my-cluster
    
  2. 选择或创建存储类。

    • 选择
      • 要列出可用的存储类,请运行 kubectl get storageclass
    • 创建
  3. 创建 PVC 及其 PV:

    1. 创建一个 PersistentVolumeClaim 配置 .yaml 并将 spec.storageClassName 设置为 StorageClass 对象的 metadata.name 值。有关示例,请参见 Kubernetes 文档中的启用动态置备
    2. 将文件传递到 kubectl create -f
    3. 运行 kubectl describe pvc <pvc metadata.name> 以验证 PVC。
    4. PV 是使用 PVC 自动创建的。记录其名称,列在 Successfully provisioned volume 之后的 kubectl describe pvc 输出中。
    5. 运行 kubectl describe pv <pv unique name> 以验证 PV。
  4. 使用 PVC 创建 Pod:

    1. 创建一个 Pod 配置 .yaml,该配置设置 spec.volumes 以将 PVC 包含在 persistentVolumeClaim.claimName 下。有关示例,请参见 vSphere Container Storage 插件文档中的使用 vSphere Container Storage 插件动态置备块卷
    2. 将文件传递到 kubectl create -f
    3. 运行 kubectl get pod <pod metadata.name> 以验证 Pod。

为 vSphere CSI 启用卷扩展 (vSphere 7)

要为工作负载集群使用的 vSphere CSI 存储启用卷扩展,您需要将 csi-resizer sidecar Pod 添加到集群的 CSI 进程。

工作负载集群的 CSI 配置编码为 Kubernetes 密钥。此过程通过修改 CSI 配置密钥来添加 csi-resizer 过程。它向密钥中添加了一个 stringData 定义,该定义组合了两个编码的配置数据字符串:一个是包含密钥之前 CSI 配置数据的 values.yaml 字符串,另一个是部署 csi-resizer Pod 的新 overlays.yaml 字符串。

注意

从 Update 2 起,vSphere 7.0 支持联机卷扩展;请参见 vSphere with Tanzu 中的卷扩展

  1. 登录到要更改的工作负载集群的管理集群,如果需要检索工作负载集群的名称,请运行 tanzu cluster list

  2. 使用标签选择器 vsphere-csi 和集群名称检索工作负载集群的 CSI 密钥名称:

    $ kubectl get secret \
      -l tkg.tanzu.vmware.com/cluster-name=NAME_OF_WORKLOAD_CLUSTER \
      -l tkg.tanzu.vmware.com/addon-name=vsphere-csi
    my-wc-vsphere-csi-secret
    
  3. 将密钥内容的备份以 YAML 格式保存到 vsphere-csi-secret.yaml

    kubectl get secret my-wc-vsphere-csi-secret -o yaml > vsphere-csi-secret.yaml
    
  4. 再次输出密钥的当前内容,并将 data.valuesbase64 解码为普通 YAML。

    $ kubectl get secret my-wc-vsphere-csi-secret -o jsonpath={.data.values\\.yaml} | base64 -d
    
    #@data/values
    #@overlay/match-child-defaults missing_ok=True
    ---
    vsphereCSI:
    CSIAttacherImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/csi-attacher
      tag: v3.0.0_vmware.1
      pullPolicy: IfNotPresent
    vsphereCSIControllerImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/vsphere-block-csi-driver
      tag: v2.2.0_vmware.1
      pullPolicy: IfNotPresent
    livenessProbeImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/csi-livenessprobe
      tag: v2.2.0_vmware.1
      pullPolicy: IfNotPresent
    vsphereSyncerImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/volume-metadata-syncer
      tag: v2.2.0_vmware.1
      pullPolicy: IfNotPresent
    CSIProvisionerImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/csi-provisioner
      tag: v2.0.0_vmware.1
      pullPolicy: IfNotPresent
    CSINodeDriverRegistrarImage:
      repository: projects.registry.vmware.com/tkg
      path: csi/csi-node-driver-registrar
      tag: v2.0.1_vmware.1
      pullPolicy: IfNotPresent
    namespace: kube-system
    clusterName: wc-1
    server: 10.170.104.114
    datacenter: /dc0
    publicNetwork: VM Network
    username: <MY-VSPHERE-USERNAME>
    password: <MY-VSPHERE-PASSWORD>
    
    
  5. 在编辑器中打开 vsphere-csi-secret.yaml 并执行以下操作,使其类似于下面的代码:

    1. 删除 values.yaml 的现有定义,这是一个长字符串。
    2. 在第一行之后,添加一行定义 stringData 并缩进 values.yaml 使其成为第一个元素。
    3. 复制上一步 data.values 的输出。
    4. 第三行后,粘贴 data.values 输出,并将其缩进为 values.yaml 的值。
    5. values.yaml 定义正下方,为 stringData 添加另一个 overlays.yaml 定义,如下所示。请勿修改文件中的其他定义。
    apiVersion: v1
    stringData:
      values.yaml: |
        #@data/values
        #@overlay/match-child-defaults missing_ok=True
        ---
        vsphereCSI:
          CSIAttacherImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/csi-attacher
            tag: v3.0.0_vmware.1
            pullPolicy: IfNotPresent
          vsphereCSIControllerImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/vsphere-block-csi-driver
            tag: v2.2.0_vmware.1
            pullPolicy: IfNotPresent
          livenessProbeImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/csi-livenessprobe
            tag: v2.2.0_vmware.1
            pullPolicy: IfNotPresent
          vsphereSyncerImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/volume-metadata-syncer
            tag: v2.2.0_vmware.1
            pullPolicy: IfNotPresent
          CSIProvisionerImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/csi-provisioner
            tag: v2.0.0_vmware.1
            pullPolicy: IfNotPresent
          CSINodeDriverRegistrarImage:
            repository: projects.registry.vmware.com/tkg
            path: csi/csi-node-driver-registrar
            tag: v2.0.1_vmware.1
            pullPolicy: IfNotPresent
          namespace: kube-system
          clusterName: wc-1
          server: 10.170.104.114
          datacenter: /dc0
          publicNetwork: VM Network
          username: <MY-VSPHERE-USERNAME>
          password: <MY-VSPHERE-PASSWORD>
      overlays.yaml: |
        #@ load("@ytt:overlay", "overlay")
        #@overlay/match by=overlay.subset({"kind": "Deployment", "metadata": {"name": "vsphere-csi-controller"}})
        ---
        spec:
          template:
            spec:
              containers:
              #@overlay/append
                - name: csi-resizer
                  image: projects.registry.vmware.com/tkg/kubernetes-csi_external-resizer:v1.0.0_vmware.1
                  args:
                    - "--v=4"
                    - "--timeout=300s"
                    - "--csi-address=$(ADDRESS)"
                    - "--leader-election"
                  env:
                    - name: ADDRESS
                      value: /csi/csi.sock
                  volumeMounts:
                    - mountPath: /csi
                      name: socket-dir
    kind: Secret
    ...
    
  6. 运行 kubectl apply 以使用修订的定义更新集群密钥,然后重新创建 csi-controller Pod:

    kubectl apply -f vsphere-csi-secret.yaml
    
  7. 要验证 vsphere-csi-controller 和外部调整器是否在集群上正常工作,请执行以下操作:

    1. 确认 vsphere-csi-controller 在具有六个正常 Pod 的工作负载集群上运行:

      $ kubectl get pods -n kube-system -l app=vsphere-csi-controller
      NAME                                     READY   STATUS    RESTARTS   AGE
      vsphere-csi-controller-<ID-HASH>   6/6     Running   0          6m49s
      
    2. 检查 vsphere-csi-controller 的日志以查看外部调整器是否已启动。

      $ kubectl logs vsphere-csi-controller-<ID-HASH> -n kube-system -c csi-resizer
      I0308 23:44:45.035254       1 main.go:79] Version : v1.0.0-0-gb22717d
      I0308 23:44:45.037856       1 connection.go:153] Connecting to unix:///csi/csi.sock
      I0308 23:44:45.038572       1 common.go:111] Probing CSI driver for readiness
      I0308 23:44:45.040579       1 csi_resizer.go:77] CSI driver name: "csi.vsphere.vmware.com"
      W0308 23:44:45.040612       1 metrics.go:142] metrics endpoint will not be started because `metrics-address` was not specified.
      I0308 23:44:45.042184       1 controller.go:117] Register Pod informer for resizer csi.vsphere.vmware.com
      I0308 23:44:45.043182       1 leaderelection.go:243] attempting to acquire leader lease  kube-system/external-resizer-csi-vsphere-vmware-com...
      I0308 23:44:45.073383       1 leaderelection.go:253] successfully acquired lease kube-system/external-resizer-csi-vsphere-vmware-com
      I0308 23:44:45.076028       1 leader_election.go:172] new leader detected, current leader: vsphere-csi-controller-87d7dcf48-jcht2
      I0308 23:44:45.079332       1 leader_election.go:165] became leader, starting
      I0308 23:44:45.079638       1 controller.go:241] Starting external resizer csi.vsphere.vmware.com
      

有关在联机或脱机模式下扩展 vSphere CSI 存储卷的详细信息,请参见 vSphere with Tanzu 中的卷扩展

拓扑感知卷置备 (vSphere)

对于从独立管理集群创建的工作负载集群,可以配置拓扑感知的本地存储卷置备。通过拓扑感知卷置备,Kubernetes 可以在动态置备卷时做出智能决策。Kubernetes 在为 Pod 置备卷的最佳位置获取调度程序输入。

创建可用区 (AZ):

  1. 按照部署工作负载集群到多个可用区(vSphere 技术预览版)中的说明,在 vSphere 中创建以下内容:

    1. 添加主机组和虚拟机组。
    2. 添加规则以限制主机组中的虚拟机组。

      一个虚拟机组和一个主机组用于在工作负载集群中运行 AZ。

      注意

      限制规则仅适用于本地卷配置。如果要部署到多个可用区,则无需创建限制规则。

    3. 在独立管理集群中部署自定义资源定义 (CRD) VSphereFailureDomainVSphereDeploymentZone

      AZ 将映射到 VSphereDeploymentZone,然后映射到 vSphere 中的主机组。

  2. 添加新 AZ。您可以使用 ytt 覆盖网络配置或使用 Tanzu CLI 添加新的 AZ。

    ytt
    下面显示了旧版集群和分类集群中的 ytt 覆盖网络配置。

    旧版集群

    #@overlay/match by=overlay.subset({"kind":"MachineDeployment", "metadata":{"name": "${CLUSTER_NAME}-md-0"}})
      ---
      apiVersion: cluster.x-k8s.io/v1beta1
      kind: MachineDeployment
      metadata:
        name: #@ "{}-md-0".format(data.values.CLUSTER_NAME)
      spec:
        clusterName: #@ data.values.CLUSTER_NAME
        replicas: #@ data.values.WORKER_MACHINE_COUNT_0
        selector:
          matchLabels: null
        strategy:
          type: #@ verify_and_configure_machine_deployment_rollout_strategy(data.values.WORKER_ROLLOUT_STRATEGY)
        template:
          metadata:
            labels:
              node-pool: #@ "{}-worker-pool".format(data.values.CLUSTER_NAME)
          spec:
            clusterName: #@ data.values.CLUSTER_NAME
            version: #@ data.values.KUBERNETES_VERSION
            bootstrap:
              configRef:
                name: #@ "{}-md-0".format(data.values.CLUSTER_NAME)
                apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
                kind: KubeadmConfigTemplate
            infrastructureRef:
              name: #@ "{}-md-0".format(data.values.CLUSTER_NAME)
              apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
              kind: AWSMachineTemplate
            failureDomain: #@ default_az_0
    
    

    分类集群

    workers:
      machineDeployments:
      #@overlay/match by=overlay.index(0)
      - class: tkg-worker
        name: md-0
        replicas: #@ data.values.WORKER_MACHINE_COUNT_0
        #@overlay/match missing_ok=True
        failureDomain: #@ default_az_0
        metadata:
          annotations:
            run.tanzu.vmware.com/resolve-os-image: #@ "ami-region={},os-name={},os-arch={}".format(data.values.AWS_REGION, data.values.OS_NAME, data.values.OS_ARCH)
    
    Tanzu CLI
    您可以使用 Tanzu CLI 创建新的 AZ 以支持拓扑感知本地存储置备。

    旧版集群

    tanzu cl node-pool set cl-name -f node-pool.yaml
    
    # node-pool.yaml
    name: vsphere-wc-1-manual-node-pool
    replicas: 1
    az: "rack4"
    

    分类集群

    请参见基于 ClusterClass 的集群的节点池配置中的设置(创建)

check-circle-line exclamation-circle-line close-line
Scroll to top icon