本主题介绍了如何使用持久卷和存储类为 Tanzu Kubernetes Grid (TKG) 工作负载集群实施动态存储。
在 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 CSI 不支持 Storage DRS,但在 vSphere CSI 文档中 vSphere Container Storage 插件支持的 vSphere 功能中所述的条件下支持 Storage vMotion。
vSphere CSI 有条件支持 Storage vMotion,请阅读 CSI 文档以了解更多详细信息。
有关 vSphere CNS、Amazon EBS 和 Azure Disk 默认存储类,请参见默认存储类。
外部置备
在 TKG v2.1 中,所有默认存储类都使用外部(“树外”)存储置备,而不是“树内”置备。
StorageClass
对象 provisioner
值不带有 kubernetes.io
前缀。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 存储类参数。
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 文档中的创建存储策略中的说明进行操作。确保:
StorageClass
对象中的 storagePolicyName
值供参考。本地 VMFS 存储:
要为本地存储创建存储策略,请将标记应用于存储,并根据标记创建存储策略,如下所示:
从顶部 vSphere 菜单中,选择标记和自定义属性 (Tags & Custom Attributes)
在标记 (Tags) 窗格中,选择类别 (Categories),然后单击新建 (New)。
输入类别名称,例如 tkg-storage
。使用复选框将其与数据中心 (Datacenter) 和存储对象(文件夹 (Folder) 和数据存储 (Datastore))相关联。单击创建 (Create)。
从顶级存储 (Storage) 视图中,选择 VMFS 卷,然后在其总结 (Summary) 窗格中,单击标记 (Tags) > 分配 (Assign) …。
从分配标记 (Assign Tag) 弹出窗口中,单击添加标记 (Add Tag)。
从创建标记 (Create Tag) 弹出窗口中,为标记指定一个名称,例如 tkg-storage-ds1
并为其分配您创建的类别 (Category)。单击确定 (OK)。
从分配标记 (Assign Tag) 中,选择标记,然后单击分配 (Assign)。
从顶级 vSphere 中,选择虚拟机存储策略 (VM Storage Policies) > 创建存储策略 (Create a Storage Policy)。配置向导将启动。
在 名称和描述 (Name and description) 窗格中,输入存储策略的名称。将存储策略名称记录为 StorageClass
对象中的 storagePolicyName
值供参考。
在策略结构 (Policy structure) 窗格中的数据存储特定规则 (Datastore specific rules) 下,选择启用基于标记的放置规则 (Enable tag-based placement rules)。
在基于标记的放置 (Tag based placement) 窗格中,单击添加标记规则 (Add Tag Rule),然后配置:
Use storage tagged with
确认并配置其他窗格或根据需要接受默认值。,然后单击查看并完成 (Review and finish)。完成 (Finish) 用于创建存储策略。
集群管理员可以创建新的存储类,如下所示:
StorageClass
基础的虚拟机存储策略。
provisioner
、parameters
和其他选项创建 StorageClass
配置.yaml
。
storagePolicyName
参数设置为 vSphere 存储策略名称(双引号字符串),将 Kubernetes 存储类与 vSphere 存储策略相关联。kubectl create -f
kubectl describe storageclass <storageclass metadata.name>
验证存储类。例如,请参见 Kubernetes 文档中的启用动态置备。
有关 vSphere CSI 信息和资源,请参见 VMware vSphere Container Storage 常见文档。
要为不使用上述默认存储类之一的集群节点置备持久性存储,集群用户可在 Pod 配置中包含自定义存储类,如下所示:
将 kubectl
的上下文设置为集群。例如:
kubectl config use-context my-cluster-admin@my-cluster
选择或创建存储类。
kubectl get storageclass
。创建 PVC 及其 PV:
PersistentVolumeClaim
配置 .yaml
并将 spec.storageClassName
设置为 StorageClass
对象的 metadata.name
值。有关示例,请参见 Kubernetes 文档中的启用动态置备。kubectl create -f
kubectl describe pvc <pvc metadata.name>
以验证 PVC。Successfully provisioned volume
之后的 kubectl describe pvc
输出中。kubectl describe pv <pv unique name>
以验证 PV。使用 PVC 创建 Pod:
Pod
配置 .yaml
,该配置设置 spec.volumes
以将 PVC 包含在 persistentVolumeClaim.claimName
下。有关示例,请参见 vSphere Container Storage 插件文档中的使用 vSphere Container Storage 插件动态置备块卷。kubectl create -f
kubectl get pod <pod metadata.name>
以验证 Pod。要为工作负载集群使用的 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 中的卷扩展。
登录到要更改的工作负载集群的管理集群,如果需要检索工作负载集群的名称,请运行 tanzu cluster list
。
使用标签选择器 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
将密钥内容的备份以 YAML 格式保存到 vsphere-csi-secret.yaml
:
kubectl get secret my-wc-vsphere-csi-secret -o yaml > vsphere-csi-secret.yaml
再次输出密钥的当前内容,并将 data.values
值 base64
解码为普通 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.1.1_vmware.1
pullPolicy: IfNotPresent
livenessProbeImage:
repository: projects.registry.vmware.com/tkg
path: csi/csi-livenessprobe
tag: v2.1.1_vmware.1
pullPolicy: IfNotPresent
vsphereSyncerImage:
repository: projects.registry.vmware.com/tkg
path: csi/volume-metadata-syncer
tag: v2.1.1_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>
在编辑器中打开 vsphere-csi-secret.yaml
并执行以下操作,使其类似于下面的代码:
values.yaml
的现有定义,这是一个长字符串。stringData
并缩进 values.yaml
使其成为第一个元素。data.values
的输出。data.values
输出,并将其缩进为 values.yaml
的值。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.1.1_vmware.1
pullPolicy: IfNotPresent
livenessProbeImage:
repository: projects.registry.vmware.com/tkg
path: csi/csi-livenessprobe
tag: v2.1.1_vmware.1
pullPolicy: IfNotPresent
vsphereSyncerImage:
repository: projects.registry.vmware.com/tkg
path: csi/volume-metadata-syncer
tag: v2.1.1_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
...
运行 kubectl apply
以使用修订的定义更新集群密钥,然后重新创建 csi-controller
Pod:
kubectl apply -f vsphere-csi-secret.yaml
要验证 vsphere-csi-controller
和外部调整器是否在集群上正常工作,请执行以下操作:
确认 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
检查 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 存储卷的详细信息,请参见在联机模式下扩展持久卷和在脱机模式下扩展持久卷。
对于从独立管理集群创建的工作负载集群,可以配置拓扑感知的本地存储卷置备。通过拓扑感知卷置备,Kubernetes 可以在动态置备卷时做出智能决策。Kubernetes 在为 Pod 置备卷的最佳位置获取调度程序输入。
创建可用区 (AZ):
按照部署工作负载集群到多个可用区(vSphere 技术预览版)中的说明,在 vSphere 中创建以下内容:
添加规则以限制主机组中的虚拟机组。
一个虚拟机组和一个主机组用于在工作负载集群中运行 AZ。
注意限制规则仅适用于本地卷配置。如果要部署到多个可用区,则无需创建限制规则。
在独立管理集群中部署自定义资源定义 (CRD) VSphereFailureDomain
和 VSphereDeploymentZone
。
AZ 将映射到 VSphereDeploymentZone
,然后映射到 vSphere 中的主机组。
添加新 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 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 的集群的节点池配置中的设置(创建)。