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

csi-driver-host-path/docs/deploy-1.17-and-later.md 在 master ·kubernetes-csi/csi-driver-host-path ·GitHub上

GitHub - kubernetes-csi/csi-driver-nfs: This driver allows Kubernetes to access NFS server on Linux node.

 

posted @ 2024-06-12 17:21  fengjian1585  阅读(302)  评论(0编辑  收藏  举报