【本文目標(biāo)】
- Kubernetes集群怎樣通過Volume做數(shù)據(jù)持久化的?
- 持久卷組件 -
Persistemt Volume
- 使用持久卷,組件 -
Persistent Volume Claim
- 在使用持久卷中想要自動創(chuàng)建持久卷,組件 -
Storage Class
【前置文章】
- 【k8s學(xué)習(xí)】Kubernetes學(xué)習(xí)——核心組件和架構(gòu)
- 【k8s學(xué)習(xí)】minikube楚殿、kubectl、yaml配置文件的介紹
- 【k8s學(xué)習(xí)】在minikube上布署MongoDB和MongoExpress
- 【k8s學(xué)習(xí)】kubernetes namespace介紹
- 【k8s學(xué)習(xí)】Kubernetes Ingress介紹
- 【k8s學(xué)習(xí)】Kubernetes打包工具Helm介紹
1. Volume使用場景
1.1 Use Case-1:mysql Pod需要Storage:
假設(shè)我們有個項目叫my-app,接連了另一個Pod叫mysql岸军,如果mysql重啟了奋刽,那么里面存放的數(shù)據(jù)也會丟失,原因是Kubernetes并沒有提供在Pod之外的持久化艰赞,一旦Pod重啟了佣谐,數(shù)據(jù)就丟失了。
-
Storage that doesn't depend on the pod lifecycle
:我們需要在Pod外有存儲數(shù)據(jù)方妖,以便不受Pod重啟的影響狭魂。 -
Storage must be available on all nodes
:假設(shè)一個mysql Pod掛掉了,那么admin controller manager發(fā)現(xiàn)后党觅,就會讓scheduler再找合適的Node重新創(chuàng)建一個Pod雌澄,所以新的Pod有可能創(chuàng)建在活著的Worker Node中的任一一個,即這個存儲要對所有的節(jié)點(diǎn)都可見杯瞻。 -
Storage needs to survive even if cluster crashes
:當(dāng)所有的節(jié)點(diǎn)都掛了掷伙,Storage里的數(shù)據(jù)也不能丟失。
1.2 Use Case-2:my-app本身可能也需要讀寫文件
比如一些session或是額外的配置等信息又兵,my-app Pod本身任柜,也可能會讀寫數(shù)據(jù),這時候我們就可以配置Persistent Volume
沛厨,簡稱pv宙地。
2. Persistent Volume
官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
2.1 介紹
-
a cluster resource
:集群中的一種資源,比如ram內(nèi)存或是cpu逆皮。 -
created via YAML file
:和別的組件一樣宅粥,可以通過YAML文件創(chuàng)建。- 創(chuàng)建的時候kind為
PersistentVolume
电谣。 - spec中定義了一些自有的屬性秽梅,比如占有空間為多少?(
spec.capacity.storage
)
- 創(chuàng)建的時候kind為
-
Needs actual physical storage
:持久化的地方必須是能支持存儲的地方剿牺,如集群里的某個存儲空間或是集群外的某臺Server或是云服務(wù)器企垦。所以這里有個問題就是如何讓Kubernetes集群讀取到這些存儲。 -
what type of storage do you need? need to create & manage them by yourself
:Persistent Volume更像是一個接口晒来,它只提供了一些規(guī)范钞诡,至于存儲的類型以及創(chuàng)建和管理、備份湃崩,都在Kubernetes之外荧降,并不歸K8s集群管理。
2.2 yaml配置示例
下述示例中的Storage的地方是NFS文件系統(tǒng):
apiVersion:
kind: persistentVolume
metadata:
name: pv-name
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessMode:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.0
nfs:
path: /dir/path/on/nfs/server
server: nfs-server-ip-address
上述spec中定義了三部分:
- 存儲能力
- 額外的信息比如進(jìn)入的模式
- nfs參數(shù)
不同的存儲類型攒读,配置可能會長不一樣朵诫。
從官網(wǎng)上可以看到,卷的類型超過了20種:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes
Persistent Volume并不從屬于某個命令空間薄扁,它是全局的組件
剪返。即所有的命名空間下的組件瞎领,都可引用到該pv組件。
2.3 Local Volume vs. Remote Volume
根據(jù)存放地點(diǎn)分類:
-
Local Volume
(在Kubernetes集群內(nèi))随夸,這種Storage就違反了1.1章的特點(diǎn)2和特點(diǎn)3九默,即它是跟集群中的某個Node綁定了,所以有可能會掛掉宾毒,以及如果集群down了驼修,這個Storage也可能down掉。正因為此诈铛,像DB數(shù)據(jù)庫的持久化存儲乙各,最好放在集群外,即Remove Volume中幢竹。 -
Remote Volume
耳峦,即集群外部存儲,符合1.1章節(jié)的三個特點(diǎn)焕毫。
什么時候創(chuàng)建Persistent Volume蹲坷?
如果某個Pod依賴于pv,那么這個pv需要在Pod被創(chuàng)建之前創(chuàng)建邑飒。
誰來創(chuàng)建循签?
一般來說,開發(fā)人員需要告訴admin(可能是DevOps Team)某個項目需要用到Persistent Volume疙咸,然后DevOps人員根據(jù)開發(fā)人員的需求县匠,在Kubernetes集群中幫忙定義并創(chuàng)建好了該pv。
在定義好之后撒轮,開發(fā)人員則需要在具體的Pod的yaml中定義引用該pv乞旦,在yaml中聲明需要用到某個pv,這時候需要另一個組件题山,叫Persistent Volume Claim
兰粉,簡稱pvc
。
3. Persistent Volume Claim
官網(wǎng):
- https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#binding
- https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
3.1 Persistent Volume Claim yaml示例
pvc如何找到pv臀蛛?通過屬性例如大小等找到合適的pv:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-name
spec:
storageClassName: manual
volumeMode: Filesystem
accessMode:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
定義了pvc后亲桦,怎么在Pod中引用呢?即通過spec.volumes.persistenceVolumeClaim.claimName
進(jìn)行關(guān)聯(lián):
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: pvc-name
【整個過程】
Pod通過pv claim請求volume
--> pv claim嘗試在集群中找到合適的volume
--> 找到的volume才是真正擁有存儲空間的地方浊仆。
--> 這時候volume會被mounted(掛載)到這個Pod
--> 然后才被掛載到Pod中的Container(這也是為什么上述Container中定義了volumeMounts屬性)
--> 至此,具體的app應(yīng)用才能讀寫該volume
pvc并不是全局的組件豫领,它可以被創(chuàng)建到某個namespace下抡柿,pvc所屬的namespace必須要和Pod相同(因為Pod定義中需要引用到pvc組件)。
3.2 思考:為什么需要這么多層抽像等恐?
- DevOps人員聲明并創(chuàng)建全局組件
pv
洲劣。 - 開發(fā)人員聲明并創(chuàng)建
pvc
备蚓,并在Pod中使用。
這樣設(shè)計的主要好處是開發(fā)人員友好囱稽,因為開發(fā)人員并不需要具體知道Storage存放地點(diǎn)(解藕)郊尝,而只需要使用即可。
3.3 通過spec.volumes引用ConfigMap和Secret
ConfigMap
組件和Secret
組件:
-
local volumes
:這兩個組件都是本地存儲卷战惊。 -
not created via pv and pvc
:不是通過pv和pvc聲明創(chuàng)建的流昏。 managed by Kubernetes
我們也可以通過volume屬性定義這兩個組件,然后在container中mounts吞获,以下是示例:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox-container
image: busybox
volumeMounts:
- name: config-dir
mountPath: /etc/config
volumes:
- name: config-dir
configMap:
name: bb-configmap
注:一個Pod可以有多個volume claim况凉。
4. Storage Class
官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
為了讓pv創(chuàng)建以及pvc創(chuàng)建更加高效,則需要第三個組件各拷,叫Storage Class
刁绒,簡稱sc。
sc可以根據(jù)PersistentVolumeClaim的定義烤黍,動態(tài)的生成pv知市。
示例:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: storage-class-name
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
-
via "provisioner" attribute
:provisioner意思為供應(yīng)方,聲明了pv的具體提供商速蕊,每個Storage類型都有自己的provisioner初狰,在需要的時候查閱官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner -
configure "parameters" for storage we want to request for Persistent Volume
:parameters屬性定義了pv所需要的信息,例如類型互例,空間大小等奢入。
sc主要是為了減少DevOps的工具,即可以動態(tài)的生成pv媳叨,那么誰來引入sc組件呢腥光?答案很明顯,是pvc糊秆。即開發(fā)人員不需要每次讓DevOps的人手動創(chuàng)建pv武福,而是通過Storage Class來自動創(chuàng)建pv。
在pvc中使用:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessMode:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: storage-class-name
【整個過程】
-
Pod
通過pvc
請求存儲痘番。 -
pvc
通過sc
請求存儲捉片。 -
sc
自動創(chuàng)建可以滿足要求的pv
。