文章目錄
-
- 存儲卷與資料持久化
-
- 配置Pod存儲卷
- 臨時存儲卷
-
- emptyDir卷
- gitRepo卷
- hostPath存儲卷
- 網絡存儲卷
-
- NFS存儲卷
- RBD存儲卷
- CephFS存儲卷
- GlusterFS存儲卷
- 持久存儲卷
-
- PV和PVC基礎
- 靜态PV資源
-
- NFS PV示例
- RBD PV示例
- PVC資源
-
- NFS PVC示例
- RBD VPC示例
- 在Pod中使用PVC
- PV和PVC的生命周期
- StorageClass
- **CSI存儲機制**
-
- **CSI存儲插件的關鍵元件和部署架構**
存儲卷與資料持久化
我們了解以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 指定給定的
在運作 Pod 之前是否應該存在,是否應該建立以及應該以什麼方式存在。hostPath
volumes:
- name: test-volume
hostPath:
path: /data #映射主控端的data目錄
type: DirectoryOrCreate #沒有就建立
除了必需的
path
屬性之外,使用者可以選擇性地為
hostPath
卷指定
type
。
取值 | 行為 |
---|---|
空字元串(預設)用于向後相容,這意味着在安裝 hostPath 卷之前不會執行任何檢查。 | |
| 如果在給定路徑上什麼都不存在,那麼将根據需要建立空目錄,權限設定為 0755,具有與 Kubelet 相同的組和所有權。 |
| 在給定路徑上必須存在的目錄。 |
| 如果在給定路徑上什麼都不存在,那麼将在那裡根據需要建立空檔案,權限設定為 0644,具有與 Kubelet 相同的組和所有權。 |
| 在給定路徑上必須存在的檔案。 |
| 在給定路徑上必須存在的 UNIX 套接字。 |
| 在給定路徑上必須存在的字元裝置。 |
| 在給定路徑上必須存在的塊裝置。 |
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)
# 驗證
[[email protected] ~]# 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,重新啟動後驗證
[[email protected] ~]# 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等)。