原创 吴就业 138 0 2024-06-12
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/75fbcb443be741509a422b4e63d31e2b
作者:吴就业
链接:https://wujiuye.com/article/75fbcb443be741509a422b4e63d31e2b
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
背景:基于前面两篇文章:
实验环境:
关于csi驱动:
如需项目代码:k8s csi驱动demo项目代码
I0612 07:46:59.848726 1 controller.go:44] create volume req params. map[network:default tier:ZONAL type:filestore]
I0612 07:47:00.257136 1 nfs_help.go:47] success to create volume dir, mkdir path /tmp/nfs-mnt/172.19.156.66-test/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee
当pvc创建后,k8s会监听pvc资源的创建,并根据StorageClasses调用csi的controller组件的CreateVolume接口。
创建deployment资源来部署一个demo服务,这个demo服务要求挂载我们创建的pvc
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-web-demo
namespace: default
spec:
replicas: 0
selector:
matchLabels:
app: go-web-demo
template:
metadata:
name: go-web-demo
namespace: default
labels:
app: go-web-demo
spec:
containers:
- name: go-web-demo
image: us-central1-docker.pkg.dev/wujiuye-410808/deployment-web-demo:v1.0.0
imagePullPolicy: Always
resources:
requests:
cpu: 10m
memory: 10Mi
volumeMounts:
- name: demo-pvc
mountPath: /data
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- name: demo-pvc
persistentVolumeClaim:
claimName: example-test-pvc-2
先将副本数设置为1,然后apply这个deployment资源。
看这个pod被调度到哪个node上,然后查看部署在该node上的csi驱动的node组件的日记。
0612 07:47:31.601400 1 node.go:54] grpc NodeGetCapabilities...
I0612 07:47:31.603213 1 node.go:103] grpc NodeStageVolume...
I0612 07:47:31.689811 1 node.go:175] NodeStageVolume succeeded on volume filestore/nfs/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/csi-202406110748 to path /var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
I0612 07:47:31.694933 1 node.go:54] grpc NodeGetCapabilities...
I0612 07:47:31.699558 1 node.go:54] grpc NodeGetCapabilities...
I0612 07:47:31.701355 1 node.go:54] grpc NodeGetCapabilities...
I0612 07:47:31.703388 1 node.go:181] grpc NodePublishVolume...
I0612 07:47:31.712107 1 node.go:233] Successfully mounted /var/lib/kubelet/pods/a3b89a53-152c-4ccc-bd34-84c186fdbd42/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
首先k8s会调用NodeGetCapabilities获取csi node组件支持的能力,因为我们实现的node组件支持NodeStageVolume和NodeUnstageVolume。所以这一步NodeStageVolume方法会被调用。
NodeStageVolume被调用之后,我们将卷挂载到了节点上的一个全局目录/var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
。之后立马调用NodePublishVolume接口,将全局卷挂载目录挂载到pod的容器卷目录。
现在,我们可以到这个node上,看是不是存在这两个目录。
检查全局卷挂载目录:
gke-autoscaler-test2-default-pool-236cef71-fg1h / # df /var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
Filesystem 1K-blocks Used Available Use% Mounted on
172.19.156.66:/mycsi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee 1073741824 0 1073741824 0% /var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
gke-autoscaler-test2-default-pool-236cef71-fg1h / #
检查Pod容器卷目录:
gke-autoscaler-test2-default-pool-236cef71-fg1h / # df /var/lib/kubelet/pods/a3b89a53-152c-4ccc-bd34-84c186fdbd42/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
Filesystem 1K-blocks Used Available Use% Mounted on
172.19.156.66:/mycsi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee 1073741824 0 1073741824 0% /var/lib/kubelet/pods/a3b89a53-152c-4ccc-bd34-84c186fdbd42/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
gke-autoscaler-test2-default-pool-236cef71-fg1h /
多增加副本数,让多一个Pod被调度到这个节点上。然后观察该节点的csi node组件的日志。
I0612 08:02:57.091455 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:02:57.093363 1 node.go:181] grpc NodePublishVolume...
I0612 08:02:57.102379 1 node.go:233] Successfully mounted /var/lib/kubelet/pods/21456002-1403-41d9-938e-54cb63cfc0e5/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
I0612 08:02:57.179181 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:02:57.180736 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:02:57.182167 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:02:57.183586 1 node.go:181] grpc NodePublishVolume...
I0612 08:02:57.193519 1 node.go:233] Successfully mounted /var/lib/kubelet/pods/ea574d4a-aa3d-4945-9c93-79f6ceb9eab5/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
可以看到,没有再调用NodeStageVolume接口,而是直接调用了NodePublishVolume接口。因为该节点已经挂载了这个PV到一个全局目录。NodePublishVolume只是将全局目录挂载到Pod的容器卷目录。
缩容一个副本,找到这个副本对应的node,查看部署在该node上的csi node组件的日志。
I0612 08:30:03.603534 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:30:08.217280 1 node.go:258] grpc NodeUnpublishVolume...
可以看到,只有NodeUnpublishVolume接口被调用了。
因为这个节点上还有Pod挂载着这个卷,所以全局卷挂载目录还不能被取消挂载,所以NodeUnstageVolume接口没有被调用。
缩小副本数,一个个缩,直到出现有node上没有demo服务的Pod了。
I0612 08:39:19.178063 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:40:07.581197 1 node.go:258] grpc NodeUnpublishVolume...
I0612 08:40:07.685575 1 node.go:54] grpc NodeGetCapabilities...
I0612 08:40:07.687284 1 node.go:239] grpc NodeUnstageVolume...
I0612 08:40:07.709397 1 node.go:252] NodeUnstageVolume succeeded on volume filestore/nfs/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/csi-202406110748 from staging target path /var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
如日记所示,只有该node因为没有部署任何一个pod引用这个pv了,k8s在调用NodeUnpublishVolume接口之后,才会调用NodeUnstageVolume接口。另外两个node由于还有副本部署在上面,没有出现NodeUnstageVolume接口被调用的情况。
我们依次缩容副本数到0,观察到当每个node都没有部署任何一个pod引用这个pv的时候,NodeUnstageVolume都会被调用。
NodeUnstageVolume接口被调用后,node上就删除了对应的卷全局挂载目录了。
当有Pod挂载卷(PV)时,卷不能被删除。只有所有挂载该卷的Pod都删除了,卷才能被删除。
当我们删除PVC的时候,k8s监听到pvc被删除,调用了DeleteVolume接口。
I0612 08:45:42.347518 1 controller.go:59] delete volume req params. with volumeId filestore/nfs/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/csi-202406110748
I0612 08:45:42.705714 1 nfs_help.go:62] success to clean volume, remove path /tmp/nfs-mnt/172.19.156.66-mycsi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee
我们在实现DeleteVolume接口的时候,清除这个卷的目录。
每个csi node组件只会负责管理本node的卷挂载和卸载。所有csi node组件的接口是由kubelet调用的。
k8s负责监听PVC资源的创建和删除,调用csi controller组件的接口来创建卷和删除卷(PV)。
csi controller组件和csi node组件并不依赖。每个组件有自己的职责。
csi node组件是以DaemonSet部署的,那么csi挂载目录是怎么挂载到node上的?因为我们给csi node组件的Pod挂载了node的一个目录。
volumeMounts:
- name: kubelet-dir
mountPath: /var/lib/kubelet
mountPropagation: Bidirectional
volumes:
- hostPath:
path: /var/lib/kubelet
type: Directory
name: kubelet-dir
我们再来看前面实验过程中输出的挂载目录:
/var/lib/kubelet/plugins/kubernetes.io/csi/csi.mycsi.wujiuye.com/c42aacd58bc7e735e76b900c9e0547a3a4b743c189a5df3d341bc284b1b26149/globalmount
和
/var/lib/kubelet/pods/a3b89a53-152c-4ccc-bd34-84c186fdbd42/volumes/kubernetes.io~csi/pvc-acce141b-0bf0-43bf-bb2e-3118ab406eee/mount
这两个目录都是/var/lib/kubelet
目录下的。
关于mountPropagation: Bidirectional
,用于指定容器的挂载传播方式。在Kubernetes中,一个Pod可以包含多个容器。当一个容器挂载了一个卷,默认情况下,这个卷只会在挂载它的容器内可见,其他容器无法访问。可以通过设置mountPropagation: Bidirectional
,实现挂载的传播,使得挂载的卷在Pod中的所有容器之间可见。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
gke和cloudrun混合部署的情况下,gke中的服务如何走内网调用cloudrun服务,以及cloudrun服务如何走内网调用gke中的服务是需要解决的问题。
CSI驱动必不可少的几个组件:csi-provisioner、controller组件、csi-node-driver-registrar、node组件,controller组件和node组件就是需要我们开发的,其实就是实现几个gRPC接口。
我们在自己部署autoscaler到gke集群中的时候遇到了403的问题,这个问题后来我们自己部署gcp-filestore-csi-driver的时候也遇到了。
在gcp平台上,使用gke服务,创建一个k8s集群,若想在本地能够通过kubectl命令或者可视化工具访问到集群,需要通过gcloud命令获取访问集群的证书。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。