Volume
本節我們討論 Kubernetes 的存儲模型 Volume,學習如何將各種持久化存儲映射到容器。
其含義是它們的生命週期可能很短,會被頻繁地銷燬和創建。容器銷燬時,保存在容器內部文件系統中的數據都會被清除。
爲了持久化保存容器的數據,可以使用 Kubernetes Volume。
Volume 的生命週期獨立於容器,Pod 中的容器可能被銷燬和重建,但 Volume 會被保留。
kubernetes Volume種類:
emptyDir
emptyDir 是最基礎的 Volume 類型。正如其名字所示,一個 emptyDir Volume 是 Host 上的一個空目錄。
emptyDir Volume 對於容器來說是持久的,對於 Pod 則不是。當 Pod 從節點刪除時,Volume 的內容也會被刪除。但如果只是容器被銷燬而 Pod 還在,則 Volume 不受影響。
① 文件最底部 volumes 定義了一個 emptyDir 類型的 Volume shared-volume。
② producer 容器將 shared-volume mount 到 /producer_dir 目錄。
③ producer 通過 echo 將數據寫到文件 hello 裏。
④ consumer 容器將 shared-volume mount 到 /consumer_dir 目錄。
⑤ consumer 通過 cat 從文件 hello 讀數據。
hostPath Volume
這裏定義了三個 hostPath volume k8s、certs 和 pki,分別對應 Host 目錄 /etc/kubernetes、/etc/ssl/certs 和 /etc/pki。
如果 Pod 被銷燬了,hostPath 對應的目錄也還會被保留,從這點看,hostPath 的持久性比 emptyDir 強。不過一旦 Host 崩潰,hostPath 也就沒法訪問了。
外部 Storage Provider
如果 Kubernetes 部署在諸如 AWS、GCE、Azure 等公有云上,可以直接使用雲硬盤作爲 Volume,下面是 AWS Elastic Block Store 的例子:
要在 Pod 中使用 ESB volume,必須先在 AWS 中創建,然後通過 volume-id 引用。其他雲硬盤的使用方法可參考各公有云廠商的官方文檔。
Kubernetes Volume 也可以使用主流的分佈式存,比如 Ceph、GlusterFS 等,下面是 Ceph 的例子:
Ceph 文件系統的 /some/path/in/side/cephfs 目錄被 mount 到容器路徑 /test-ceph。
當然,運維這樣的存儲系統通常不是項簡單的工作,特別是對可靠性、高可用和擴展性有較高要求時。
Volume 提供了非常好的數據持久化方案,不過在可管理性上還有不足。
PV & PVC
Volume 提供了非常好的數據持久化方案,不過在可管理性上還有不足。
拿前面 AWS EBS 的例子來說,要使用 Volume,Pod 必須事先知道如下信息:
Pod 通常是由應用的開發人員維護,而 Volume 則通常是由存儲系統的管理員維護。開發人員要獲得上面的信息:
Kubernetes 給出的解決方案是 PersistentVolume 和 PersistentVolumeClaim。
PersistentVolume (PV) 是外部存儲系統中的一塊存儲空間,由管理員創建和維護。與 Volume 一樣,PV 具有持久性,生命週期獨立於 Pod。
NFS PersistentVolume
部署節點搭建nfs服務器
創建 PV
#vim nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.146.151
② accessModes
指定訪問模式爲 ReadWriteOnce
,支持的訪問模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到單個節點。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節點。
ReadWriteMany – PV 能以 read-write 模式 mount 到多個節點。
③ persistentVolumeReclaimPolicy
指定當 PV 的回收策略爲 Recycle
,支持的策略有:
Recycle – 清除 PV 中的數據,效果相當於執行 rm -rf /thevolume/*
。
Delete – 刪除 Storage Provider 上的對應存儲資源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。
④ storageClassName
指定 PV 的 class 爲 nfs
。相當於爲 PV 設置了一個分類,PVC 可以指定 class 申請相應 class 的 PV。
#kubectl apply -f nfs-pv1.yml
#kubectl get pv
創建pvc
#vim nfs-pvc1.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
#kubectl apply -f nfs-pvc1.yml
Pod使用pvc
接下來就可以在 Pod 中使用存儲了,Pod 配置文件 pod1.yml
如下:
kind: Pod
apiVersion: v1
metadata:
name: mypod1
spec:
containers:
- name: mypod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/mydata"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc
驗證
通過pvc回收pv
#kubectl delete -f pod1.yml
#kubectl delete pvc mypvc1
當數據清除完畢,mypv1 的狀態重新變爲 Available,此時則可以被新的 PVC 申請。
因爲 PV 的回收策略設置爲 Recycle,所以數據會被清除,但這可能不是我們想要的結果。如果我們希望保留數據,可以將策略設置爲 Retain。