使用 CSI 拓扑
Trident可以利用以下方式选择性地创建卷并将其附加到 Kubernetes 集群中的节点: "CSI拓扑功能" 。
概述
使用 CSI 拓扑功能,可以根据区域和可用区域将对卷的访问限制到节点子集。如今,云服务提供商允许 Kubernetes 管理员创建基于区域的节点。节点可以位于一个区域内的不同可用区,也可以跨多个区域。为了方便在多区域架构中为工作负载配置卷, Trident使用了 CSI 拓扑。
|
|
了解更多关于 CSI 拓扑功能的信息 "此处"。 |
Kubernetes 提供了两种独特的卷绑定模式:
-
和 `VolumeBindingMode`设置为 `Immediate`Trident创建卷时没有任何拓扑感知。卷绑定和动态配置在创建 PVC 时处理。这是默认设置。 `VolumeBindingMode`适用于不强制执行拓扑约束的集群。持久卷的创建不依赖于请求 pod 的调度要求。
-
和 `VolumeBindingMode`设置为 `WaitForFirstConsumer`PVC 的持久卷的创建和绑定将被延迟,直到使用该 PVC 的 pod 被调度和创建。这样,就可以创建卷来满足拓扑要求所强制执行的调度约束。
|
|
这 `WaitForFirstConsumer`绑定模式不需要拓扑标签。这可以独立于 CSI 拓扑功能使用。 |
要使用 CSI 拓扑结构,您需要以下组件:
-
运行中的 Kubernetes 集群"支持的 Kubernetes 版本"
kubectl version Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:50:19Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"} -
集群中的节点应带有标签,以体现拓扑感知能力。(
topology.kubernetes.io/region`和 `topology.kubernetes.io/zone)。在安装Trident之前,集群中的节点上*应该存在这些标签*,以便Trident能够感知拓扑结构。kubectl get nodes -o=jsonpath='{range .items[*]}[{.metadata.name}, {.metadata.labels}]{"\n"}{end}' | grep --color "topology.kubernetes.io" [node1, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node1","kubernetes.io/os":"linux","node-role.kubernetes.io/master":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-a"}] [node2, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node2","kubernetes.io/os":"linux","node-role.kubernetes.io/worker":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-b"}] [node3, {"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node3","kubernetes.io/os":"linux","node-role.kubernetes.io/worker":"","topology.kubernetes.io/region":"us-east1","topology.kubernetes.io/zone":"us-east1-c"}]
步骤 1:创建拓扑感知后端
Trident存储后端可以设计为根据可用区选择性地配置卷。每个后端都可以携带一个可选组件 `supportedTopologies`表示所支持的区域和地区列表的块。对于使用此类后端的 StorageClasses,只有在受支持的区域/区域中调度的应用程序请求时才会创建卷。
以下是一个后端定义示例:
---
version: 1
storageDriverName: ontap-san
backendName: san-backend-us-east1
managementLIF: 192.168.27.5
svm: iscsi_svm
username: admin
password: password
supportedTopologies:
- topology.kubernetes.io/region: us-east1
topology.kubernetes.io/zone: us-east1-a
- topology.kubernetes.io/region: us-east1
topology.kubernetes.io/zone: us-east1-b
{
"version": 1,
"storageDriverName": "ontap-san",
"backendName": "san-backend-us-east1",
"managementLIF": "192.168.27.5",
"svm": "iscsi_svm",
"username": "admin",
"password": "password",
"supportedTopologies": [
{
"topology.kubernetes.io/region": "us-east1",
"topology.kubernetes.io/zone": "us-east1-a"
},
{
"topology.kubernetes.io/region": "us-east1",
"topology.kubernetes.io/zone": "us-east1-b"
}
]
}
|
|
`supportedTopologies`用于提供每个后端区域和分区的列表。这些区域和分区代表了 StorageClass 中可以提供的允许值的列表。对于包含后端提供的区域和可用区子集的存储类, Trident会在后端创建一个卷。 |
你可以定义 `supportedTopologies`每个存储池也是如此。请参见以下示例:
---
version: 1
storageDriverName: ontap-nas
backendName: nas-backend-us-central1
managementLIF: 172.16.238.5
svm: nfs_svm
username: admin
password: password
supportedTopologies:
- topology.kubernetes.io/region: us-central1
topology.kubernetes.io/zone: us-central1-a
- topology.kubernetes.io/region: us-central1
topology.kubernetes.io/zone: us-central1-b
storage:
- labels:
workload: production
supportedTopologies:
- topology.kubernetes.io/region: us-central1
topology.kubernetes.io/zone: us-central1-a
- labels:
workload: dev
supportedTopologies:
- topology.kubernetes.io/region: us-central1
topology.kubernetes.io/zone: us-central1-b
在这个例子中, `region`和 `zone`标签代表存储池的位置。 `topology.kubernetes.io/region`和 `topology.kubernetes.io/zone`决定存储池可以从何处使用。
步骤 2:定义拓扑感知的存储类。
根据提供给集群中节点的拓扑标签,可以定义 StorageClasses 来包含拓扑信息。这将决定哪些存储池可作为 PVC 请求的候选对象,以及哪些节点子集可以使用Trident提供的卷。
请参见以下示例:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: null
name: netapp-san-us-east1
provisioner: csi.trident.netapp.io
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions: null
- key: topology.kubernetes.io/zone
values:
- us-east1-a
- us-east1-b
- key: topology.kubernetes.io/region
values:
- us-east1
parameters:
fsType: ext4
在上述 StorageClass 定义中, volumeBindingMode`设置为 `WaitForFirstConsumer。使用此 StorageClass 请求的 PVC 只有在 pod 中被引用后才会执行。和, `allowedTopologies`提供要使用的区域和范围。这 `netapp-san-us-east1`StorageClass 在存储上创建 PVC。 `san-backend-us-east1`后端定义如上所述。
步骤 3:制作并使用 PVC
创建 StorageClass 并将其映射到后端后,现在可以创建 PVC。
请参阅示例 `spec`以下:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata: null
name: pvc-san
spec: null
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 300Mi
storageClassName: netapp-san-us-east1
使用此清单创建 PVC 将产生以下结果:
kubectl create -f pvc.yaml persistentvolumeclaim/pvc-san created kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-san Pending netapp-san-us-east1 2s kubectl describe pvc Name: pvc-san Namespace: default StorageClass: netapp-san-us-east1 Status: Pending Volume: Labels: <none> Annotations: <none> Finalizers: [kubernetes.io/pvc-protection] Capacity: Access Modes: VolumeMode: Filesystem Mounted By: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal WaitForFirstConsumer 6s persistentvolume-controller waiting for first consumer to be created before binding
为了让Trident形成体积并将其与 PVC 结合,请使用 PVC 管。请参见以下示例:
apiVersion: v1
kind: Pod
metadata:
name: app-pod-1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/region
operator: In
values:
- us-east1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east1-a
- us-east1-b
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: vol1
persistentVolumeClaim:
claimName: pvc-san
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: vol1
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
此 podSpec 指示 Kubernetes 将 pod 调度到存在于以下位置的节点上: `us-east1`在该区域中,选择任何存在的节点。 `us-east1-a`或者 `us-east1-b`区域。
请查看以下输出:
kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app-pod-1 1/1 Running 0 19s 192.168.25.131 node2 <none> <none> kubectl get pvc -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE pvc-san Bound pvc-ecb1e1a0-840c-463b-8b65-b3d033e2e62b 300Mi RWO netapp-san-us-east1 48s Filesystem
更新后端以包含 supportedTopologies
可以更新现有的后端,使其包含以下列表: supportedTopologies`使用 `tridentctl backend update。这不会影响已经分配的容量,只会用于后续的PVC。