文章目录
存储卷与数据持久化
我们了解以Docker为代表的容器运行时一般都支持配置容器使用的“存储卷”将数据持久存储与容器自身文件系统之外的存储空间中。相应地Kubernetes也支持类似的存储卷功能,其存储卷绑定于Pod对象而非容器级别,并可共享给内部所有容器使用。
存储卷可简单归为一下几类:
1)临时存储卷:emptyDir
2)本地存储卷:hostPath和local
3)网络存储卷:
- 云存储-------------awsElasticBlockStore、gcePersistentDisk、azureDisk、azureFile
- 网络文件系统----NFS、GlusterFS、CephFS、Cinder
- 网络块设备-------iscsi、FC、RBD、vSphereVolume
- 网络存储平台----Quobyte、PortworxVolume、StorageOS、ScaleIO
4)特殊存储卷:Secret、ConfigMap、DownwardAPI、Projected
5)扩展支持第三方存储的存储接口(Out-of-Tree卷插件):CSI和Flex Volume
配置Pod存储卷
临时存储卷
emptyDir卷
emptyDir,临时目录,从名字就可以看出初始内容为空,在pod分配到Node时kubernetes自动分配目录,所以无需指定宿主机目录,当Pod删除时,emptyDir将永久删除。
主要字段:
medium:存储介质,default或Memory,其中Memory使用RAM的临时文件系统tmpfs
sizeLimit:默认值为nil,表示不限制,使用Memory时务必定义限额。
...
spec:
containers:
- image: luksa/fortune
name: html-gen
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: nginx:apache
name: web
volumeMounts:
- name: html
mountPath: /user/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html
emptyDir: {}
#emptyDir的文件存储在内存中
volumes:
- name: html
emptyDir:
medium: Memory #指定使用内存
sizeLimit: 100Mi #使用大小
gitRepo卷
gitRepo卷其实也是一个emptyDir卷,在Pod创建前通过clone将指定的git代码到该目录中,生命周期和Pod相同。使用的前提是运行Pod的节点能执行git clone,即需要提前安装git。另外gitRepo即将废弃,建议在初始化容器或Sidecar容器中运行git命令实现。
主要字段:
repository: GIT仓库的URL
directory: 目标目录
revision: revision
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html #注意,挂载的是空文件,如果原来此目录有内容,将不复存在,区别在下面
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html
gitRepo:
repository: http://121.196.57.33:32083/root/html1.git #此git下面是一个index.html文件
revision: master
directory: .
###这种是指定文件挂载,/usr/share/nginx/html/文件下其他文件还在
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/index.html
readOnly: true
subPath: index.html
下面的小例子,访问nginx服务,即可看到它来自Git仓库的页面资源:
apiVersion: v1
kind: Pod
metadata:
name: volumes-gitrepo-demo
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
gitRepo:
repository: https://github.com/iKubernetes/Kubernetes_Advanced_Practical_2rd.git
directory: .
revision: "master"
hostPath存储卷
hostPath 卷能将工作节点文件系统上的文件或目录挂载到您的 Pod 中,其数据和工作节点生命周期一样的持久性,但对于由调度器按需调度的应用来说并不适用。
hostPath
的一些用法:
- 运行一个需要访问 Docker 引擎内部机制的容器;请使用
hostPath
挂载/var/lib/docker
路径。 - 在容器中运行 cAdvisor 时,以
hostPath
方式挂载/sys
。 - 允许 Pod 指定给定的
hostPath
在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。
volumes:
- name: test-volume
hostPath:
path: /data #映射宿主机的data目录
type: DirectoryOrCreate #没有就创建
除了必需的 path
属性之外,用户可以选择性地为 hostPath
卷指定 type
。
取值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate |
如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 Kubelet 相同的组和所有权。 |
Directory |
在给定路径上必须存在的目录。 |
FileOrCreate |
如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所有权。 |
File |
在给定路径上必须存在的文件。 |
Socket |
在给定路径上必须存在的 UNIX 套接字。 |
CharDevice |
在给定路径上必须存在的字符设备。 |
BlockDevice |
在给定路径上必须存在的块设备。 |
apiVersion: v1
kind: Pod
metadata:
name: volumes-hostpath-demo
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.7-alpine
env:
- name: REDIS_HOST
value: redis.ilinux.io:6379
- name: LOG_LEVEL
value: info
volumeMounts:
- name: varlog
mountPath: /var/log
- name: socket
mountPath: /var/run/docker.sock
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: socket
hostPath:
path: /var/run/docker.sock
网络存储卷
通常网络存储都是独立运行的存储系统,因此相应的存储卷可以支持超越节点生命周期的数据持久性。
NFS存储卷
NFS即网络文件系统(Network File System),它是一种分布式文件系统协议,客户端可以像访问本地存储一样通过网络访问服务端文件,内核原生支持的网络文件系统。kubernetes的NFS存储卷用于关联某事先存在的NFS服务器上导出的存储空间到Pod对象*容器使用。如果Pod中止NFS存储卷内容不被删除。
主要字段:
server:NFS服务器地址
path:NFS服务器共享的文件系统路径
readOnly:是否以只读方式挂载,默认false
下面我们以redis-demo为例演示NFS存储卷
apiVersion: v1
kind: Pod
metadata:
name: volumes-nfs-demo
labels:
app: redis
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
name: redisport
securityContext:
runAsUser: 888
volumeMounts:
- mountPath: /data
name: redisdata
volumes:
- name: redisdata
nfs:
server: 192.168.124.22
path: /data/redis
readOnly: false
设定一台NFS服务器
# yum install nfs-utils -y
# mkdir -p /data/redis
# useradd -u 888 redis
# chown redis /data/redis
# vim /etc/exports
/data/redis *(rw,no_root_squash)
# systemctl start rpcbind.service
# systemctl start nfs.service
# chkconfig nfs on
# exportfs -v
/data/redis <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
# 验证
[root@vm1 ~]# kubectl exec -it volumes-nfs-demo -- redis-cli
127.0.0.1:6379> set mykey "tewstst"
OK
127.0.0.1:6379> get mykey
"tewstst"
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> exit
# 删除pod,重新启动后验证
[root@vm1 ~]# kubectl exec -it volumes-nfs-demo -- redis-cli
127.0.0.1:6379> get mykey
"tewstst"
RBD存储卷
待更新。。。
CephFS存储卷
待更新。。。
GlusterFS存储卷
待更新。。。
持久存储卷
网络存储卷的弊端在于用户必须要清楚了解用的的网络存储系统的访问细节才能完成存储卷相关的配置,这与Kubernetes向用户和开发隐藏底层架构的理念不符合,而PV和PVC就是Kubernetes在用户和存储服务之间添加的一个中间层,管理员根据PV支持的存储卷插件及适配存储系统细节定义好可以支撑存储卷的底层存储空间,用户通过PVC声明要使用的存储特性绑定PV,从而实现存储系统的使用与管理职能的解耦,大大简化了用户使用存储的方式。
PV和PVC基础
PV由集群管理员在Kubernetes集群上全局配置的预挂载存储空间,可以抽象的理解为Kubernetes系统全局级别的API,由集群管理员负责管理和维护。
当Pod对象要使用PV存储时,用户需要事先使用PVC在名称空间级别下声明所需要的存储空间大小和访问模式并提交给Kubernetes API Server,然后PV控制器负责查找与之匹配的PV资源进行绑定。这种通过管理员手动创建PV来满足PVC需求的静态预配是存在问题的,列如5G的PVC可能会绑定到20G的PV上。后面有更好的解决方案:动态预配,按需创建PV的机制。
PV和PVC的生命周期有Controller Manager中PV控制器管理,不在受限于Pod的生命周期,PV和PVC相关解释:
-
PersistentVolume(持久卷,简称PV),PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”。比如Node是Pod可以消费的资源,PV由管理员创建和配置。
-
PersistentVolumeClaim(持久卷声明,简称PVC),是用户对存储资源的一个申请。就像Pod消费Node一样,PVC能够消费PV资源。
kubernetes支持的PV类型如下:
-
AWSElasticBlockStore:AWS公有云提供的ElasticBlockStore。
-
AzureFile:Azure公有云提供的File。
-
AzureDisk:Azure公有云提供的Disk。
-
CephFS:一种开源共享存储系统。
-
FC(Fibre Channel):光纤存储设备。
-
FlexVolume:一种插件式的存储机制。
-
Flocker:一种开源共享存储系统。
-
GCEPersistentDisk:GCE公有云提供的PersistentDisk。
-
Glusterfs:一种开源共享存储系统。
-
HostPath:宿主机目录,仅用于单机测试。
-
iSCSI:iSCSI存储设备。
-
Local:本地存储设备,目前可以通过指定块(Block)设备提供Local PV,或通过社区开发的sig-storage-local-static-provisioner插件( https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner )来管理Local PV的生命周期。
-
NFS:网络文件系统。
-
Portworx Volumes:Portworx提供的存储服务。
-
Quobyte Volumes:Quobyte提供的存储服务。
-
RBD(Ceph Block Device):Ceph块存储。
-
ScaleIO Volumes:DellEMC的存储设备。
-
StorageOS:StorageOS提供的存储服务。
-
VsphereVolume:VMWare提供的存储系统。
静态PV资源
PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity: #存储能力
storage: 1Gi
accessModes: #访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle #回收策略
storageClassName: manual #存储类别
nfs: #后端存储
server: 192.168.207.121
path: "/nas/dg_vd"
1、存储能力(Capacity)
描述存储设备具备的能力,支持对存储空间的设置(storage=xx)
2、存储卷模式(Volume Mode)
volumeMode=xx,可选项包括Filesystem(文件系统)和Block(块设备),默认值是FileSystem。
目前有以下PV类型支持块设备类型:
AWSElasticBlockStore、AzureDisk、FC、GCEPersistentDisk、iSCSI、Local volume、RBD(Ceph Block Device)、VsphereVolume(alpha)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
volumeMode: Block
fc:
targetWWNs: ["url"]
lun: 0
readOnly: false
3、访问模式(Access Modes)
用于描述应用对存储资源的访问权限。
◎ ReadWriteOnce(RWO):读写权限,并且只能被单个Node挂载。
◎ ReadOnlyMany(ROX):只读权限,允许被多个Node挂载。
◎ ReadWriteMany(RWX):读写权限,允许被多个Node挂载。
4、存储类别(Class)
设定存储的类别,通过storageClassName参数指定给一个StorageClass资源对象的名称,具有特定类别的PV只能与请求了该类别的PVC进行绑定。未绑定类别的PV则只能与不请求任何类别的PVC进行绑定。
5、回收策略(Reclaim Policy)
通过persistentVolumeReclaimPolicy字段设置,
◎ Retain 保留:保留数据,需要手工处理。
◎ Recycle 回收空间:简单清除文件的操作(例如执行rm -rf /thevolume/* 命令)。
◎ Delete 删除:与PV相连的后端存储完成Volume的删除操作
EBS、GCE PD、Azure Disk、OpenStack Cinder等设备的内部Volume清理)。
6、挂载参数(Mount Options)
在将PV挂载到一个Node上时,根据后端存储的特点,可能需要设置额外的挂载参数,可根据PV定义中的mountOptions字段进行设置。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
mountOptions:
- hard
- nolock
- nfsvers=3
gcePersistentDisk:
fsType: ext4
pdName: gce-disk-1
目前,以下PV类型支持设置挂载参数:
AWSElasticBlockStore、AzureDisk、AzureFile、CephFS、Cinder (OpenStack block storage)、GCEPersistentDisk、Glusterfs、NFS、Quobyte Volumes、RBD (Ceph Block Device)、StorageOS、VsphereVolume、iSCSI
7、节点亲和性(Node Affinity)
限制只能通过某些Node来访问Volume,可在nodeAffinity字段中设置。使用这些Volume的Pod将被调度到满足条件的Node上。
此参数仅用于Local存储卷上。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- my-node
NFS PV示例
定义一个nfs-pv.yaml资源清单,一个使用NFS存储系统的PV资源,空间大小限制为5GB,并支持多路的读写操作。
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: "/data/redis"
server: 192.168.124.22
创建该PV资源
# kubectl apply -f nfs-pv.yaml
persistentvolume/pv-nfs-demo created
如果正确关联到指定的后端,该PV对象的状态将显示为Available,否则其状态为Pending。如果PVC绑定该PV其状态为Bound。
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 5Gi RWX Retain Available 7s
# kubectl describe pv pv-nfs
Name: pv-nfs
Labels: <none>
Annotations: Finalizers: [kubernetes.io/pv-protection]
StorageClass:
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 5Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.124.22
Path: /data/redis
ReadOnly: false
Events: <none>
RBD PV示例
下面使用RBD存储后端,空间大小为2GB,访问模式为RWO,回收策略为Retain,该PV资源还有一个usedof的资源标签,可被PVC标签选择器匹配。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-rbd-demo
labels:
usedof: redisdata
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
rbd:
monitors:
- ceph01.ilinux.io
- ceph02.ilinux.io
- ceph03.ilinux.io
pool: kube
image: pv-test
user: kube
keyring: /etc/ceph/ceph.client.kube.keyring
fsType: xfs
readOnly: false
persistentVolumeReclaimPolicy: Retain
PVC资源
PVC作为用户对存储资源的需求申请,主要包括存储空间请求、访问模式、PV选择条件和存储类别等信息的设置。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
spec:
accessModes: #访问模式
- ReadWriteOnce
resources: #申请资源,8Gi存储空间
requests:
storage: 8Gi
storageClassName: slow #存储类别
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
关键配置
- accessModes:PV的访问模式,与PV设置相同
- dataSrouces:用于从自定的数据源恢复该PVC卷
- resources: 对存储资源的请求,目前仅支持request.storage的设置,即是存储空间的大小
- selector:通过对Label Selector的设置,可使PVC对于系统中已存在的各种PV进行筛选。选择条件可以使用matchLabels和matchExpressions进行设置
- storageClassName:
NFS PVC示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0001
namespace: default
spec:
accessModes: ["ReadWriteMany"]
volumeMode: Filesystem
resources:
requests:
storage: 3Gi
limits:
storage: 10Gi
RBD VPC示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo-0002
spec:
accessModes: ["ReadWriteOnce"]
volumeMode: Filesystem
resources:
requests:
storage: 2Gi
limits:
storage: 5Gi
selector:
matchLabels:
usedof: "redisdata"
在Pod中使用PVC
persistentVolumeClaim配置字段:
claimName:要使用的PVC名称,注意:PVC卷和Pod同一命名空间
readOnly:是否强制将存储卷挂载为只读模式,默认为false
apiVersion: v1
kind: Pod
metadata:
name: volumes-pvc-demo
namespace: default
spec:
containers:
- name: redis
image: redis:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
name: redisport
volumeMounts:
- mountPath: /data
name: redis-rbd-vol
volumes:
- name: redis-rbd-vol
persistentVolumeClaim:
claimName: pvc-demo-0002
PV和PVC的生命周期
将PV看作可用的存储资源,PVC则是对存储资源的需求。
(1)资源供应
k8s支持两种资源的供应模式:静态模式(Static)和动态模式(Dynamic)。资源供应的结果就是创建好的PV。
静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。
动态模式:集群管理员无需手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种类型。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及与PVC的绑定。PVC可以声明Class为"",说明该PVC禁止使用动态模式。
(2)资源绑定1
在定义好PVC之后,系统将根据PVC对存储资源的要求(存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与定义的PVC进行绑定,应用就可以使用这个PVC了。如果系统中没有这个PV,则PVC则会一直处理Pending状态,直到系统中有符合条件的PV。PV一旦绑定到PVC上,就会被PVC独占,不能再与其他PVC进行绑定。当PVC申请的存储空间比PV的少时,整个PV的空间就都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在为PVC找到合适的StorageClass后,将自动创建一个PV并完成与PVC的绑定。
(3)资源使用
Pod使用Volume定义,将PVC挂载到容器内的某个路径进行使用。Volume的类型为Persistent VolumeClaim,在容器挂载了一个PVC后,就能被持续独占使用。多个Pod可以挂载到同一个PVC上。
volumes:
- name: pv
persistentVolumeClaim:
claimName: pvc
(4)资源释放
当存储资源使用完毕后,可以删除PVC,与该PVC绑定的PV会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被保留在存储设备上,只有在清除之后该PV才能被再次使用。
(5)资源回收
对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。
通过两张图分别对在静态资源供应模式和动态资源供应模式下,PV、PVC、StorageClass及Pod使用PVC的原理进行说明。
在静态资源供应模式下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制
在动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制
StorageClass
StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,一方面减少了用户对存储资源细节的关注,另一方面减少了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。
StorageClass的定义主要包括名称、后端存储的提供者(privisioner)和后端存储的相关参数配置。StorageClass一旦被创建,就无法修改,如需修改,只能删除重建。
下例定义了一个名为standard的StorageClass,提供者为aws-ebs,其参数设置了一个type,值为gp2:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
privisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
关键配置
1、提供者(Privisioner)
描述存储资源的提供者,也可以看作后端存储驱动。
2、参数(Parameters)
后端存储资源提供者的参数设置,不同的Provisioner包括不同的参数设置。某些参数可以不显示设定,Provisioner将使用其默认值。
设置默认的StorageClass
首先需要启用名为DefaultStorageClass的admission controller,即在kube-apiserver的命令行参数–admission-control中增加
--admission-control=...,DefaultStorageClass
然后,在StorageClass的定义中设置一个annotation:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
annotations:
storageclass.beta.kubernetes.io/is-default-class="true"
privisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
通过kubectl create命令创建成功后,查看StorageClass列表,可以看到名为gold的StorageClass被标记为default:
kubectl get sc
CSI存储机制
Container Storage Interface(CSI)机制,用于在kubenetes和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务。
CSI存储插件的关键组件和部署架构
主要包括两个组件:CSI Controller和CSI Node
1、CSI Controller
提供存储服务视角对存储资源和存储进行管理和操作,在k8s中建议部署为单实例Pod,可以使用StatefulSet和Deployment控制器进行部署,设置副本数为1,保证为一种存储插件只运行一个控制器实例。
在此Pod内部署两个容器:
(1)与Master(kubernetes Controller Manager)通信的辅助sidecar容器,
在sidecar容器内又可以包含extenal-attacher和extenal-privisioner两个容器,功能如下:
◎ external-attacher:监控VolumeAttachment资源对象的变更,触发针对CSI端点的ControllerPublish和ControllerUnpublish操作。
◎ external-provisioner:监控PersistentVolumeClaim资源对象的变更,触发针对CSI端点的CreateVolume和DeleteVolume操作
(2)CSI Driver存储驱动容器,第三方提供,需实现上述接口
这两个容器使用本地Socket(Unix Domain Socket,UDS),并使用gPRC协议进行通信,sidecar容器通过socket调用CSI Driver容器的CSI接口,CSI Driver容器负责具体的存储卷操作。
2、CSI Node
对主机(Node)上的Volume进行管理和操作,建议使用DaemonSet,每个Node上都运行一个Pod。
在此Pod上部署如下两个容器:
(1)与kubelet通信的辅助sidecar容器node-driver-register,主要功能是将存储驱动注册到kubelet中。
(2)CSI Driver存储驱动容器,由第三方存储提供商提供,主要功能是接收kubelet的调用,需要实现一系列与Node相关的CSI接口,例如NodePublishVolume接口(用于将Volume挂载到容器内的目标路径)、NodeUnpublishVolume接口(用于从容器中卸载Volume),等等。
node-driver-register容器与kubelet通过Node主机的一个hostPath目录下的unix Socket进行通信,CSI Driver容器与kubelet通过Node主机的另一个hostPath目录下的unix Socket进行通信,同时需要将kubelet的工作目录(/var/lib/kubelet)挂载到CSI Driver容器,用于为Pod进行Volume的管理操作(包括mount,unmount等)。