docker容器是有生命周期的。
volume
創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比喀什網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式喀什網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋喀什地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。
1,存儲(chǔ)類(Storage class)是k8s資源類型的一種,它是有管理員為管理PV更加方便創(chuàng)建的一個(gè)邏輯組,可以按照存儲(chǔ)系統(tǒng)的性能高低,或者綜合服務(wù)質(zhì)量,備份策略等分類。不過k8s本身不知道類別到底是什么,它這是作為一個(gè)描述。
2,存儲(chǔ)類的好處之一就是支持PV的動(dòng)態(tài)創(chuàng)建,當(dāng)用戶用到持久性存儲(chǔ)時(shí),不必再去提前創(chuàng)建PV,而是直接創(chuàng)建PVC就可以了,非常的方便。
3,存儲(chǔ)類對(duì)象的名稱很重要,并且出了名稱之外,還有3個(gè)關(guān)鍵字段
Provisioner(供給方):
及提供了存儲(chǔ)資源的存儲(chǔ)系統(tǒng)。k8s內(nèi)建有多重供給方,這些供給方的名字都以“kubernetes.io”為前綴。并且還可以自定義。
Parameters(參數(shù)):存儲(chǔ)類使用參數(shù)描述要關(guān)聯(lián)到的存儲(chǔ)卷,注意不同的供給方參數(shù)也不同。
reclaimPolicy:PV的回收策略,可用值有Delete(默認(rèn))和Retain
1, 由于容器本身是非持久化的,因此需要解決在容器中運(yùn)行應(yīng)用程序遇到的一些問題。首先,當(dāng)容器崩潰時(shí),kubelet將重新啟動(dòng)容器,但是寫入容器的文件將會(huì)丟失,容器將會(huì)以鏡像的初始狀態(tài)重新開始;第二,在通過一個(gè)Pod中一起運(yùn)行的容器,通常需要共享容器之間一些文件。Kubernetes通過存儲(chǔ)卷解決上述的兩個(gè)問題。
2, 在Docker有存儲(chǔ)卷的概念卷,但Docker中存儲(chǔ)卷只是磁盤的或另一個(gè)容器中的目錄,并沒有對(duì)其生命周期進(jìn)行管理。Kubernetes的存儲(chǔ)卷有自己的生命周期,它的生命周期與使用的它Pod生命周期一致。因此,相比于在Pod中運(yùn)行的容器來說,存儲(chǔ)卷的存在時(shí)間會(huì)比的其中的任何容器都長,并且在容器重新啟動(dòng)時(shí)會(huì)保留數(shù)據(jù)。當(dāng)然,當(dāng)Pod停止存在時(shí),存儲(chǔ)卷也將不再存在。在Kubernetes支持多種類型的卷,而Pod可以同時(shí)使用各種類型和任意數(shù)量的存儲(chǔ)卷。在Pod中通過指定下面的字段來使用存儲(chǔ)卷:
spec.volumes:通過此字段提供指定的存儲(chǔ)卷
spec.containers.volumeMounts:通過此字段將存儲(chǔ)卷掛接到容器中
主機(jī) | IP地址 | 服務(wù) |
---|---|---|
master | 192.168.1.21 | k8s |
node01 | 192.168.1.22 | k8s |
node02 | 192.168.1.23 | k8s |
使用場景:在同一 個(gè)Pod里,不同的容器,共享數(shù)據(jù)卷。
如果容器被刪除,數(shù)據(jù)仍然存在,如果Pod被 刪除,數(shù)據(jù)也會(huì)被刪除。
一個(gè)emptyDir 第一次創(chuàng)建是在一個(gè)pod被指定到具體node的時(shí)候,并且會(huì)一直存在在pod的生命周期當(dāng)中,正如它的名字一樣,它初始化是一個(gè)空的目錄,pod中的容器都可以讀寫這個(gè)目錄,這個(gè)目錄可以被掛在到各個(gè)容器相同或者不相同的的路徑下。當(dāng)一個(gè)pod因?yàn)槿魏卧虮灰瞥臅r(shí)候,這些數(shù)據(jù)會(huì)被永久刪除。注意:一個(gè)容器崩潰了不會(huì)導(dǎo)致數(shù)據(jù)的丟失,因?yàn)槿萜鞯谋罎⒉⒉灰瞥齪od.
- 空白的初始空間,例如合并/排序算法中,臨時(shí)將數(shù)據(jù)保存在磁盤上。
- 長時(shí)間計(jì)算中存儲(chǔ)檢查點(diǎn)(中間結(jié)果),以便容器崩潰時(shí),可以從上一次存儲(chǔ)的檢查點(diǎn)(中間結(jié)果)繼續(xù)進(jìn)行,而不是從頭開始。
- 作為兩個(gè)容器的共享存儲(chǔ),使得第一個(gè)內(nèi)容管理的容器可以將生成的數(shù)據(jù)存入其中,同時(shí)由一個(gè)webserver容器對(duì)外提供這些頁面。
- 默認(rèn)情況下,emptyDir數(shù)據(jù)卷存儲(chǔ)在node節(jié)點(diǎn)的存儲(chǔ)介質(zhì)(機(jī)械硬盤、SSD或網(wǎng)絡(luò)存儲(chǔ))上。
(1)普通空間,基于磁盤的數(shù)據(jù)存儲(chǔ)
(2)作為從崩潰中恢復(fù)的備份點(diǎn)
(3)存儲(chǔ)那些那些需要長久保存的數(shù)據(jù),例web服務(wù)中的數(shù)據(jù)
默認(rèn)的,emptyDir 磁盤會(huì)存儲(chǔ)在主機(jī)所使用的媒介上,可能是SSD,或者網(wǎng)絡(luò)硬盤,這主要取決于你的環(huán)境。當(dāng)然,我們也可以將emptyDir.medium的值設(shè)置為Memory來告訴Kubernetes 來掛在一個(gè)基于內(nèi)存的目錄tmpfs,因?yàn)?br/>tmpfs速度會(huì)比硬盤塊度了,但是,當(dāng)主機(jī)重啟的時(shí)候所有的數(shù)據(jù)都會(huì)丟失。
測試編寫一個(gè)yaml文件
[root@master yaml]# vim emptyDir.yaml apiVersion: v1 kind: Pod metadata: name: producer-consumer spec: containers: - image: busybox name: producer volumeMounts: - mountPath: /producer_dir name: shared-volume args: - /bin/sh - -c - echo "hello k8s" > /producer_dir/hello; sleep 30000 - image: busybox name: consumer volumeMounts: - mountPath: /consumer_dir name: shared-volume args: - /bin/sh - -c - cat /consumer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {}
執(zhí)行一下
[root@master yaml]# kubectl apply -f emptyDir.yaml
查看一下
[root@master yaml]# kubectl get pod
查看日志
[root@master yaml]# kubectl logs producer-consumer producer [root@master yaml]# kubectl logs producer-consumer consumer
查看掛載的目錄
node節(jié)點(diǎn)查看容器名,并通過容器名查看掛載的目錄
[root@node01 shared-volume]# docker ps
[root@node01 shared-volume]# docker inspect k8s_consumer_producer-consumer_default_9ec83f9e-e58b-4bf8-8e16-85b0f83febf9_0
進(jìn)入掛載目錄查看一下
hostPath宿主機(jī)路徑,就是把pod所在的宿主機(jī)之上的脫離pod中的容器名稱空間的之外的宿主機(jī)的文件系統(tǒng)的某一目錄和pod建立關(guān)聯(lián)關(guān)系,在pod刪除時(shí),存儲(chǔ)數(shù)據(jù)不會(huì)丟失。
如果Pod被刪除,數(shù)據(jù)會(huì)保留,相比較emptyDir要好一點(diǎn)。不過一旦host崩潰,hostPath也無法訪問 了。
docker或者k8s集群本身的存儲(chǔ)會(huì)采用hostPath這種方式。
某容器需要訪問 Docker,可使用 hostPath 掛載宿主節(jié)點(diǎn)的 /var/lib/docker
在容器中運(yùn)行 cAdvisor,使用 hostPath 掛載宿主節(jié)點(diǎn)的 /sys
PersistentVolume(PV)是集群中已由管理員配置的一段網(wǎng)絡(luò)存儲(chǔ)。 集群中的資源就像一個(gè)節(jié)點(diǎn)是一個(gè)集群資源。 PV是諸如卷之類的卷插件,但是具有獨(dú)立于使用PV的任何單個(gè)pod的生命周期。 該API對(duì)象捕獲存儲(chǔ)的實(shí)現(xiàn)細(xì)節(jié),即NFS,iSCSI或云提供商特定的存儲(chǔ)系統(tǒng)。
我們前面提到kubernetes提供那么多存儲(chǔ)接口,但是首先kubernetes的各個(gè)Node節(jié)點(diǎn)能管理這些存儲(chǔ),但是各種存儲(chǔ)參數(shù)也需要專業(yè)的存儲(chǔ)工程師才能了解,由此我們的kubernetes管理變的更加復(fù)雜的。由此kubernetes提出了PV和PVC的概念,這樣開發(fā)人員和使用者就不需要關(guān)注后端存儲(chǔ)是什么,使用什么參數(shù)等問題。如下圖:
PersistentVolume(PV)是集群中已由管理員配置的一段網(wǎng)絡(luò)存儲(chǔ)。 集群中的資源就像一個(gè)節(jié)點(diǎn)是一個(gè)集群資源。 PV是諸如卷之類的卷插件,但是具有獨(dú)立于使用PV的任何單個(gè)pod的生命周期。 該API對(duì)象捕獲存儲(chǔ)的實(shí)現(xiàn)細(xì)節(jié),即NFS,iSCSI或云提供商特定的存儲(chǔ)系統(tǒng)。
PersistentVolumeClaim(PVC)是用戶存儲(chǔ)的請(qǐng)求。PVC的使用邏輯:在pod中定義一個(gè)存儲(chǔ)卷(該存儲(chǔ)卷類型為PVC),定義的時(shí)候直接指定大小,pvc必須與對(duì)應(yīng)的pv建立關(guān)系,pvc會(huì)根據(jù)定義去pv申請(qǐng),而pv是由存儲(chǔ)空間創(chuàng)建出來的。pv和pvc是kubernetes抽象出來的一種存儲(chǔ)資源。
雖然PersistentVolumeClaims允許用戶使用抽象存儲(chǔ)資源,但是常見的需求是,用戶需要根據(jù)不同的需求去創(chuàng)建PV,用于不同的場景。而此時(shí)需要集群管理員提供不同需求的PV,而不僅僅是PV的大小和訪問模式,但又不需要用戶了解這些卷的實(shí)現(xiàn)細(xì)節(jié)。 對(duì)于這樣的需求,此時(shí)可以采用StorageClass資源。這個(gè)在前面就已經(jīng)提到過此方案。
PV是集群中的資源。 PVC是對(duì)這些資源的請(qǐng)求,也是對(duì)資源的索賠檢查。 PV和PVC之間的相互作用遵循這個(gè)生命周期:
Provisioning(配置)---> Binding(綁定)--->Using(使用)---> Releasing(釋放) ---> Recycling(回收)
nfs使的我們可以掛在已經(jīng)存在的共享到的我們的Pod中,和emptyDir不同的是,emptyDir會(huì)被刪除當(dāng)我們的Pod被刪除的時(shí)候,但是nfs不會(huì)被刪除,僅僅是解除掛在狀態(tài)而已,這就意味著NFS能夠允許我們提前對(duì)數(shù)據(jù)進(jìn)行處理,而且這些數(shù)據(jù)可以在Pod之間相互傳遞.并且,nfs可以同時(shí)被多個(gè)pod掛在并進(jìn)行讀寫
注意:必須先保證NFS服務(wù)器正常運(yùn)行在我們進(jìn)行掛在nfs的時(shí)候
下載nfs所需安裝包
[root@node02 ~]# yum -y install nfs-utils rpcbind
創(chuàng)建共享目錄
[root@master ~]# mkdir /nfsdata
創(chuàng)建共享目錄的權(quán)限
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
開啟nfs和rpcbind
[root@master ~]# systemctl start nfs-server.service
[root@master ~]# systemctl start rpcbind
測試一下
[root@master ~]# showmount -e
[root@master yaml]# cd yaml/
[root@master yaml]# vim nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv
spec:
capacity: #pv容量的大小
storage: 1Gi
accessModes: #訪問pv的模式
- ReadWriteOnce #能以讀-寫mount到單個(gè)的節(jié)點(diǎn)
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.1.21
accessModes:(PV支持的訪問模式) - ReadWriteOnce: 能以讀-寫mount到單個(gè)的節(jié)點(diǎn) - ReadWriteMany: 能以讀-寫mount到多個(gè)的節(jié)點(diǎn)。 - ReadOnlyOnce: 能以只讀的方式mount到單個(gè)節(jié)點(diǎn)。
persistentVolumeReclaimPolicy : (PV存儲(chǔ)空間的回收策略是什么) Recycle: 自動(dòng)清除數(shù)據(jù)。 Retain: 需要管理員手動(dòng)回收。 Delete: 云存儲(chǔ)專用。
[root@master yaml]# kubectl apply -f nfs-pv.yaml
[root@master yaml]# kubectl get pv
PersistentVolumeClaim(PVC)是用戶存儲(chǔ)的請(qǐng)求。PVC的使用邏輯:在pod中定義一個(gè)存儲(chǔ)卷(該存儲(chǔ)卷類型為PVC),定義的時(shí)候直接指定大小,pvc必須與對(duì)應(yīng)的pv建立關(guān)系,pvc會(huì)根據(jù)定義去pv申請(qǐng),而pv是由存儲(chǔ)空間創(chuàng)建出來的。pv和pvc是kubernetes抽象出來的一種存儲(chǔ)資源。
[root@master yaml]# vim nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master yaml]# kubectl apply -f nfs-pvc.yaml
[root@master yaml]# kubectl get pvc
[root@master yaml]# kubectl get pv
[root@master yaml]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: pod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/mydata"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: test-pvc
[root@master yaml]# kubectl apply -f pod.yaml
[root@master yaml]# kubectl get pod -o wide
可以看到現(xiàn)在沒有開啟成功
[root@master yaml]# kubectl describe pod test-pod
[root@master yaml]# mkdir /nfsdata/pv1/
//要和nfs-pv.yaml的名字一樣
[root@master yaml]# kubectl delete -f pod.yaml
[root@master yaml]# kubectl apply -f pod.yaml
[root@master yaml]# kubectl get pod -o wide
[root@master yaml]# kubectl exec test-pod touch /mydata/hello
進(jìn)入容器
[root@master yaml]# kubectl exec -it test-pod /bin/sh
/ # echo 123 > /mydata/hello
/ # exit
掛載目錄查看一下
[root@master yaml]# cat /nfsdata/pv1/hello
和剛剛的一樣
[root@master yaml]# kubectl delete pod test-pod
[root@master yaml]# kubectl delete pvc test-pvc
[root@master yaml]# kubectl delete pv test-pv
[root@master yaml]# kubectl get pv
[root@master yaml]# cat /nfsdata/pv1/hello
文件已被回收
[root@master yaml]# vim nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv
spec :
capacity :
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain #修改
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.1.21
[root@master yaml]# kubectl apply -f nfs-pv.yaml
[root@master yaml]# kubectl apply -f pod.yaml
[root@master yaml]# kubectl describe pod test-pod
[root@master yaml]# kubectl apply -f nfs-pvc.yaml
[root@master yaml]# kubectl get pod
[root@master yaml]# kubectl exec test-pod touch /mydata/k8s
[root@master yaml]# ls /nfsdata/pv1/
[root@master yaml]# kubectl delete pod test-pod
[root@master yaml]# kubectl delete pvc test-pvc
[root@master yaml]# kubectl delete pv test-pv
[root@master yaml]# ls /nfsdata/pv1/
內(nèi)容還在
下面演示如何為 MySQL 數(shù)據(jù)庫提供持久化存儲(chǔ),步驟為:
[root@master yaml]# kubectl apply -f nfs-pv.yaml
[root@master yaml]# kubectl apply -f nfs-pvc.yaml
[root@master yaml]# kubectl get pv
[root@master yaml]# kubectl get pvc
[root@master yaml]# vim mysql.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-mysql
spec:
selector:
matchLabels: #支持等值的標(biāo)簽
app: mysql
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: 123.com
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: test-pvc
[root@master yaml]# kubectl apply -f mysql.yaml
[root@master yaml]# kubectl get pod
① 切換到數(shù)據(jù)庫 mysql。
② 創(chuàng)建數(shù)據(jù)庫表 my_id。
③ 插入一條數(shù)據(jù)。
④ 確認(rèn)數(shù)據(jù)已經(jīng)寫入。
關(guān)閉 k8s-node2,模擬節(jié)點(diǎn)宕機(jī)故障。
[root@master yaml]# kubectl exec -it test-mysql-569f8df4db-rkpwm -- mysql -u root -p123.com
mysql> create database yun33;
mysql> use yun33;
mysql> create table my_id( id int(4));
mysql> insert my_id values(9527);
mysql> select * from my_id;
[root@master yaml]# ls /nfsdata/pv1/
[root@master yaml]# kubectl get pod -o wide -w
[root@master yaml]# kubectl exec -it test-mysql-569f8df4db-nsdnz -- mysql -u root -p123.com
mysql> show databases;
mysql> show tables;
mysql> select * from my_id;
可以看到數(shù)據(jù)還在
kubectl describe
//查看詳細(xì)信息,找出問題
kubectl logs
//查看日志,找出問題
/var/ log/messages
//查看該節(jié)點(diǎn)的kubelet的日志。
本章我們討論了 Kubernetes 如何管理存儲(chǔ)資源。
emptyDir 和 hostPath 類型的 Volume 很方便,但可持久性不強(qiáng),Kubernetes 支持多種外部存儲(chǔ)系統(tǒng)的 Volume。
PV 和 PVC 分離了管理員和普通用戶的職責(zé),更適合生產(chǎn)環(huán)境。我們還學(xué)習(xí)了如何通過 StorageClass 實(shí)現(xiàn)更高效的動(dòng)態(tài)供給。
最后,我們演示了如何在 MySQL 中使用 PersistentVolume 實(shí)現(xiàn)數(shù)據(jù)持久性。
accessModes:(PV支持的訪問模式)
persistentVolumeReclaimPolicy : (PV存儲(chǔ)空間的回收策略是什么)
? Recycle: 自動(dòng)清除數(shù)據(jù)。
? Retain: 需要管理員手動(dòng)回收。
? Delete: 云存儲(chǔ)專用。
是通過accessModes和storageClassName模塊關(guān)聯(lián)的