您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)詳解Kubernetes存儲體系,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
先思考一個問題,為什么會引入Volume
這樣一個概念?
“答案很簡單,為了實現(xiàn)數(shù)據(jù)持久化,數(shù)據(jù)的生命周期不隨著容器的消亡而消亡。
”
在沒有介紹Kubernetes Volume
之前,先來回顧下Docker Volume
,Docker Volume
常用使用方式有兩種,
volumes
通過這種方式,
Docker
管理宿主機文件系統(tǒng)的一部分,默認(rèn)位于
/var/lib/docker/volumes
目錄中,由于在創(chuàng)建時沒有創(chuàng)建指定數(shù)據(jù)卷,
docker
自身會創(chuàng)建默認(rèn)數(shù)據(jù)卷;bind mounts
通過這種方式,可以把容器內(nèi)文件掛載到宿主機任意目錄。既然有了Docker Volume
,為啥Kubernetes
又搞出了自己的Volume
?谷歌的標(biāo)新立異?
“答案是否定的,
”Kubernetes Volume
和Docker Volume
概念相似,但是又有不同的地方,Kubernetes Volume
與Pod
的生命周期相同,但與容器的生命周期不相關(guān)。當(dāng)容器終止或重啟時,Volume
中的數(shù)據(jù)也不會丟失。當(dāng)Pod
被刪除時,Volume
才會被清理。并且數(shù)據(jù)是否丟失取決于Volume
的具體類型,比如emptyDir
類型的Volume
數(shù)據(jù)會丟失,而持久化類型的數(shù)據(jù)則不會丟失。另外Kubernetes
提供了將近20
種Volume
類型。
現(xiàn)在有了Kubernetes
的Volume
,我們就可以完全可以在Yaml
編排文件中填寫上Volume
是字段,如下nfs
所示:
....
volumes:
- name: static-nfs
nfs:
server: 12.18.17.240
path: /nfs/data/static
如果你使用ceph
作為存儲插件,你可以在編排文件中這樣定義:
volumes:
- name: ceph-vol
cephfs:
monitors:
- 12.18.17.241:6789
- 12.18.17.242:6789
user: admin
secretRef:
name: ceph-secret
readOnly: true
當(dāng)然只要是Kubernetes
已經(jīng)實現(xiàn)的數(shù)據(jù)卷類型,你都可以按照如上方式進(jìn)行直接在Yaml
編排文件中定義使用。
看到這里其實已經(jīng)完成了80%
的工作,那么為什么還要設(shè)計多此一舉的PV
呢?這個問題先擱置下,后面會有說明。
在沒有說明為什么要設(shè)計多此一舉的PV PVC
之前,先來看看什么是PV PVC
?
“”
PV
是對持久化存儲數(shù)據(jù)卷的一種描述。
PV
通常是由運維人員提前在集群里面創(chuàng)建等待使用的一種數(shù)據(jù)卷。如下所示:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: 10.244.1.4
path: "/nfs"
“”
PVC
描述的是持久化存儲的屬性,比如大小、讀寫權(quán)限等。
PVC
通常由開發(fā)人員創(chuàng)建,如下所示:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
而用戶創(chuàng)建的PV PVC
必須綁定完成之后才能被利用起來。而PV PVC
綁定起來的前提是PV
中spec
中聲明字段大小、權(quán)限等必須滿足PVC
的要求。
成功綁定之后,就可以在Pod Yaml
編排文件中定義和使用。如下所示:
apiVersion: v1
kind: Pod
metadata:
labels:
role: web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
看到這里,我們還會認(rèn)為僅僅是PV
對Volume
多了一層抽象,并不見得比直接在Yaml
中聲明Volume
高明多少。仔細(xì)思考下,我們?yōu)槭裁茨軌蛑苯釉?code>Yaml中直接定義Volume
?因為Kubernetes
已經(jīng)幫助我們實現(xiàn)了這種Volume
類型,如果我們有自己的存儲類型,而Kubernetes
中并沒有實現(xiàn),這種是沒有辦法直接在Yaml
編排文件中直接定義Volume
的。這個時候PV PVC
面向?qū)ο蟮脑O(shè)計就體現(xiàn)出其價值了。這也是在軟件開發(fā)領(lǐng)域經(jīng)常碰到的問題,開源軟件無法滿足要求,但也沒有提供出可擴展的接口,沒辦法,只能重新造輪子。
我們在開發(fā)過程中經(jīng)常碰到這樣一個問題,在Pod
中聲明一個PVC
之后,發(fā)現(xiàn)Pod
不能被調(diào)度成功,原因是因為PVC
沒有綁定到合適的PV
,這個時候要求運維人員創(chuàng)建一個PV
,緊接著Pod
調(diào)度成功。剛才上在介紹PV PVC
,它們的創(chuàng)建過程都是手動,如果集群中需要成千上萬的PV
,那么運維人員豈不累死?在實際操作中,這種方式根本行不通。所以Kubernetes
給我們提供了一套自動創(chuàng)建PV
的機制Dynamic Provisioning
.在沒有介紹這套自動創(chuàng)建機制之前,先看看Static Provisioning
,什么是Static Provisioning
?剛才人工創(chuàng)建PV PVC
的方式就是Static Provisioning
。你可以在PV PVC
編排文件中聲明StorageClass
,如果沒有聲明,那么默認(rèn)為"".具體交互流程如下所示:
首先由集群管理員事先去規(guī)劃這個集群中的用戶會怎樣使用存儲,它會先預(yù)分配一些存儲,也就是預(yù)先創(chuàng)建一些 PV
;然后用戶在提交自己的存儲需求(PVC
)的時候,Kubernetes
內(nèi)部相關(guān)組件會幫助它把PVC PV
做綁定;最后pod
使用存儲的時候,就可以通過PVC
找到相應(yīng)的PV
,它就可以使用了。不足之處也非常清楚,首先繁瑣,然后運維人員無法預(yù)知開發(fā)人員的真實存儲需求,比如運維人員創(chuàng)建了多個100Gi
的PV
存儲,但是在實際開發(fā)過程中,開發(fā)人員只能使用10Gi
,這就造成了資源的浪費。當(dāng)然Kubernetes
也為我們提供更好的使用方式,即Dynamic Provisioning
它是什么呢?
“”
Dynamic Provisioning
包含了創(chuàng)建某種PV
所需要的參數(shù)信息,類似于一個創(chuàng)建PV
的模板。具體交互流程如下所示:
Kubernetes
集群中的控制器,會結(jié)合PVC
和StorageClass
的信息動態(tài)生成用戶所需要的PV
,將PVC PV
進(jìn)行綁定后,pod
就可以使用PV
了。通過 StorageClass
配置生成存儲所需要的存儲模板,再結(jié)合用戶的需求動態(tài)創(chuàng)建PV
對象,做到按需分配,在沒有增加用戶使用難度的同時也解放了集群管理員的運維工作。
Dynamic Provisioning
上面提到過,運維人員不再預(yù)分配PV
,而只是創(chuàng)建一個模板文件,這個模板文件正是StorageClass
。下面以NFS
為例進(jìn)行說明,動態(tài)PV
的整個使用過程。
#安裝nfs
yum -y install nfs-utils rpcbind
#開機自啟動
systemctl enable rpcbind nfs-server
#配置nfs 文件
echo "/nfs/data *(rw,no_root_squash,sync)" >/etc/exports
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: logging
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
selector:
matchLabels:
app: nfs-client-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 12.18.7.20
- name: NFS_PATH
value: /nfs/data
volumes:
- name: nfs-client
nfs:
server: 12.18.7.20
path: /nfs/data
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: fuseim.pri/ifs
reclaimPolicy: Retain
這些參數(shù)是通過Kubernetes
創(chuàng)建存儲的時候,需要指定的一些細(xì)節(jié)參數(shù)。對于這些參數(shù),用戶是不需要關(guān)心的,像這里provisioner
指的是使用nfs
的置備程序。ReclaimPolicy
就是說動態(tài)創(chuàng)建出來的PV
,當(dāng)使用方使用結(jié)束、Pod
及 PVC
被刪除后,這塊PV
應(yīng)該怎么處理,我們這個地方寫的是Retain
,意思就是說當(dāng)使用方pod PVC
被刪除之后,這個PV
會保留。
Pod yaml
文件定義
PVC
,即可自動創(chuàng)建
PV
和
PVC
。apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es
spec:
........
template:
metadata:
labels:
app: elasticsearch
spec:
.........
initContainers:
........
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
.......
volumeClaimTemplates:
- metadata:
name: data
labels:
app: elasticsearch
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: nfs-storage
resources:
requests:
storage: 50Gi`
Capacity
:存儲對象的大?。?/p>
AccessModes
:也是用戶需要關(guān)心的,就是說使用這個PV
的方式。它有三種使用方式:ReadWriteOnce
是單node
讀寫訪問;ReadOnlyMany
是多個node
只讀訪問,常見的一種數(shù)據(jù)共享方式;ReadWriteMany
是多個node
上讀寫訪問;
StorageClassName
:StorageClassName
這個我們剛才說了,動態(tài)Provisioning
時必須指定的一個字段,就是說我們要指定到底用哪一個模板文件來生成PV
。
PV Controller
: 負(fù)責(zé)
PV PVC
的綁定、生命周期管理,并根據(jù)需求進(jìn)行數(shù)據(jù)卷的
Provision Delete
操作AD Controller
:負(fù)責(zé)存儲設(shè)備的
Attach Detach
操作,將設(shè)備掛載到目標(biāo)節(jié)點Volume Manager
:管理卷的
Mount Unmount
操作、卷設(shè)備的格式化以及掛載到一些公用目錄上的操作Volume Plugins
:它主要是對上面所有掛載功能的實現(xiàn)。
PV Controller、AD Controller、Volume Manager
主要是進(jìn)行操作的調(diào)用,而具體操作則是由
Volume Plugins
實現(xiàn)的。根據(jù)源碼的位置可將
Volume Plugins
分為
In-Tree
和
Out-of-Tree
兩類:
In-Tree
表示源碼是放在
Kubernetes
內(nèi)部的(常見的
NFS、cephfs
等),和
Kubernetes
一起發(fā)布、管理與迭代,缺點是迭代速度慢、靈活性差;
Out-of-Tree
的
Volume Plugins
的代碼獨立于
Kubernetes
,它是由存儲
提供商實現(xiàn)的,目前主要有
Flexvolume CSI
兩種實現(xiàn)機制,可以根據(jù)存儲類型實現(xiàn)不同的存儲插件Scheduler
:實現(xiàn)對
Pod
的調(diào)度能力,會根據(jù)一些存儲相關(guān)的的定義去做存儲相關(guān)的調(diào)度PVC
的
Pod
PV Controller
會觀察
ApiServer
,如果它發(fā)現(xiàn)一個
PVC
已經(jīng)創(chuàng)建完畢但仍然是未綁定的狀態(tài),它就會試圖把一個
PV
和
PVC
綁定Provision
就是從遠(yuǎn)端上一個具體的存儲介質(zhì)創(chuàng)建一個
Volume
,并且在集群中創(chuàng)建一個
PV
對象,然后將此
PV
和
PVC
進(jìn)行綁定Scheduler
進(jìn)行多個維度考量完成后,把
Pod
調(diào)度到一個合適的
Node
Kubelet
不斷
watch APIServer
是否有
Pod
要調(diào)度到當(dāng)前所在節(jié)點Pod
調(diào)度到某個節(jié)點之后,它所定義的
PV
還沒有被掛載(
Attach
),此時
AD Controller
就會調(diào)用
VolumePlugin
,把遠(yuǎn)端的
Volume
掛載到目標(biāo)節(jié)點中的設(shè)備上(
/dev/vdb
);當(dāng)
Volum Manager
發(fā)現(xiàn)一個
Pod
調(diào)度到自己的節(jié)點上并且
Volume
已經(jīng)完成了掛載,它就會執(zhí)行
mount
操作,將本地設(shè)備(也就是剛才得到的
/dev/vdb
)掛載到
Pod
在節(jié)點上的一個子目錄中Volume
映射到容器中看完上述內(nèi)容,你們對詳解Kubernetes存儲體系有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。