k8s存储CSI插件的存储方案
Kubernetes从1.9版本开始引入容器存储接口 Container Storage Interface (CSI)机制,用于在Kubernetes和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务。
CSI的核心组件和部署架构
Kubernetes CSI存储插件的关键组件和推荐的容器化部署架构如下(其中主要包括两类组件:CSI Controller和CSI Node):
CSI Controller
CSI Controller的主要功能是 提供存储服务视角对存储资源和存储卷进行管理和操作。在Kubernetes中建议将其部署为单实例Pod,可以使用StatefulSet或 Deployment控制器进行部署,设置副本数量为1,保证一种存储插件只运行一个控制器实例。
在这个Pod内部署两个容器,分别提供以下功能.
与Master ( kube-controller-manager) 通信的辅助sidecar容器:在 sidecar容器内又可以包含external-attacher和external-provisioner两个容器,它们的功能分别如下: external-attacher:监控VolumeAttachment资源对象的变更,触发针对 CSI端点的ControllerPublish和ControllerUnpublish操作; externail-provisioner:监控PersistentVolumeClaim资源对象的变更,触发针对CSI端点的CreateVolume和DeleteVolume操作。 另外,社区正在引入具备其他管理功能的sidecar工具,例如:externalsnapshotter,用于管理存储快照,目前为Alpha阶段;external-resizer用于管理存储容量扩容,目前为Beta阶段。
CsI Driver存储驱动容器,由第三方存储提供商提供,需要实现上述接口:这两个容器通过本地Socket (Unix Domain Socket, UDS),并使用gPRC协议进行通信。sidecar容器通过Socket调用CSI Driver容器的CSI接口,CSI Driver 容器负责具体的存储卷操作。
CSI Node
CSI Node的主要功能是对主机(Node )上的Volume进行管理和操作,在 Kubernetes中建议将其部署为DaemonSet,在需要提供存储资源的各个Node上都运行一个Pod。 在这个Pod中部署以下两个容器: 与kubelet通信的辅助sidecar容器node-driver-registrar:主要功能是将存储驱动注册到kubelet中; CSI Driver存储驱动容器:由第三方存储提供商提供,主要功能是接收 kubelet 的调用,需要实现一系列与 Node 相关的 CSI 接口,例如: NodePublishVolume 接口(用于将 Volume 挂载到容器内的目标路径)、NodeUnpublishVolume接口(用于从容器中卸载Volu加粗样式me),等等。
流程:
node-driver-registrar容器与kubelet通过 Node主机一个hostPath目录下的 unix socket进行通信。
CSI Driver容器与kubelet通过Node主机另一个hostPath目录下的 unix socket 进行通信,同时需要将 kubelet 的工作目录(默认为 /var/lib/kubelet)挂载给CSI Driver容器,用于为Pod进行Volume的管理操作 (包括mount、 umount等)。
在k8s中安装nfs csi driver实现动态存储
安装部署nfs csi driver
git clone https://github.com/kubernetes-csi/csi-driver-nfs.git cd csi-driver-nfs/deploy/v4.7.0/
kubectl apply -f .
创建storageclass,配置CSI Driver 部署的nfs server作为存储后端
cd /root/csi-driver-nfs/deploy/example [root@master1 example]# cat storageclass-nfs.yaml --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-csi provisioner: nfs.csi.k8s.io parameters: server: 192.168.148.139 share: /opt/nfsdata reclaimPolicy: Delete volumeBindingMode: Immediate mountOptions: - nfsvers=4.1 - hard
创建pvc
[root@master1 example]# cat pvc-nfs-csi-dynamic.yaml --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs-dynamic spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: nfs-csi
创建pod
[root@master1 example]# cat 1.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: deployment-nfs spec: replicas: 1 selector: matchLabels: name: deployment-nfs template: metadata: name: deployment-nfs labels: name: deployment-nfs spec: nodeSelector: "kubernetes.io/os": linux containers: - image: 192.168.148.139/nginx/nginx:latest imagePullPolicy: IfNotPresent name: deployment-nfs command: - "/bin/bash" - "-c" - set -euo pipefail; while true; do echo $(hostname) $(date) >> /mnt/nfs/outfile; sleep 1; done volumeMounts: - name: nfs mountPath: "/mnt/nfs" readOnly: false volumes: - name: nfs persistentVolumeClaim: claimName: pvc-nfs-dynamic
csi-driver-host-path 部署
检查是否有任何 Pod 正在运行 snapshot-controller 映像
[root@master1 example]# kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{range .spec.containers[*]}{.image}{", "}{end}{end}' | grep snapshot-controller registry-k8s-io.mirrors.sjtug.sjtu.edu.cn/sig-storage/snapshot-controller:v6.3.3, registry-k8s-io.mirrors.sjtug.sjtu.edu.cn/sig-storage/snapshot-controller:v6.3.3,
如果没有 Pod 运行 snapshot-controller,请按照以下说明创建 snapshot-controller
VolumeSnapshot CRD 和快照控制器安装
# Change to the latest supported snapshotter version $ SNAPSHOTTER_VERSION=v6.3.3 # Create snapshot controller $ kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml $ kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${SNAPSHOTTER_VERSION}/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
安装部署
git clone https://github.com/kubernetes-csi/csi-driver-host-path.git
创建rbac
cd csi-driver-host-path/
deploy/kubernetes-latest/deploy.sh
替换镜像
sed -i 's/registry.k8s.io/registry-k8s-io.mirrors.sjtug.sjtu.edu.cn/g' *.yaml
kubectl applyf -f ./
部署测试验证
[root@master1 deploy]# cd /root/csi-driver-host-path/examples/
for i in ./examples/csi-storageclass.yaml ./examples/csi-pvc.yaml ./examples/csi-app.yaml; do kubectl apply -f $i; done
storageclass.storage.k8s.io/csi-hostpath-sc created
persistentvolumeclaim/csi-pvc created
pod/my-csi-app created
确认 Hostpath 驱动程序正常工作
Hostpath 驱动程序配置为在 hostpath 容器内创建新卷,该容器在此处找到的插件 StatefulSet 中指定。只要 StatefulSet Pod 启动并运行,此路径就会持续存在。/csi-data-dir
在应用程序内正确挂载的 Hostpath 卷中写入的文件应显示在 Hostpath 容器中。以下步骤确认 Hostpath 工作正常。首先,从应用程序 Pod 创建一个文件,如下所示:
$ kubectl exec -it my-csi-app /bin/sh / # touch /data/hello-world / # exit
接下来,通过 ssh 进入 Hostpath 容器并验证文件是否显示在那里:
$ kubectl exec -it $(kubectl get pods --selector app=csi-hostpathplugin -o jsonpath='{.items[*].metadata.name}') -c hostpath /bin/sh
然后,使用以下命令找到该文件。如果一切正常,您应该会得到类似于以下内容的结果:
# find / -name hello-world
/var/lib/kubelet/pods/803b5144-12a5-4af9-8d11-68b929fdab37/volumes/kubernetes.io~csi/pvc-eff69d7c-df46-40d2-9e46-56ee0fc7abf7/mount/hello-world
/var/lib/csi-hostpath-data/6a1c69e7-2892-11ef-a1bd-126b1bab9631/hello-world
引用:
https://blog.51cto.com/u_15294985/6236368