- 存盤卷的使用方式
- 臨時存盤卷emptyDir
- 節點存盤卷hostPath
- 網路存盤卷
- NFS存盤卷
- RBD存盤卷
- GlusterFS存盤卷
- Cinder存盤卷
- PersistentVolumeClaim
- 創建PV
- 創建PVC
- 在Pod中使用PVC
- downwardAPI存盤卷
- 環境變數式元資料注入
- 存盤卷式元資料注入
Pod被銷毀時,其內部容器的資料也無法持久存在,與Docker類似,K8S也支持配置容器使用存盤卷將資料持久存盤于容器自身檔案系統之外的存盤空間中,它們可以是節點檔案系統或網路檔案系統之上的存盤空間,但K8S的存盤卷是與Pod資源系結而非容器,存盤卷定義在Pod資源之上、可被其內部的所有容器掛載的共享目錄,而資料是否具有持久能力則取決于存盤卷自身是否支持持久機制,
Kubernetes支持多種存盤卷型別,包括本地存盤(節點)和網路存盤系統中的諸多存盤機制,甚至還支持Secret和ConfigMap這樣的特殊存盤資源,
存盤卷的使用方式
在Pod中定義使用存盤卷之前,首先要通過spec.volumes欄位定義在Pod之上的存盤卷串列,其支持使用多種不同型別的存盤卷且配置引數差別很大;然后通過spec.containers.volumeMounts欄位在容器上定義存盤卷掛載串列,它只能掛載當前Pod資源中定義的具體存盤卷,
spec.volumes舉例:
spec:
volumes:
- name: logdata
emptyDir: {}
- name: example
gitRepo:
repository: ...
revision: master
directory: .
上面的資源清單片段定義了由兩個存盤卷組成的卷串列,一個是emptyDir型別,一個是gitRepo型別,定義好的存盤卷可由當前Pod資源內的各容器進行掛載,當Pod中存在多個容器且它們掛載同一個存盤卷時,卷可以用于容器間資料共享,當Pod中只有一個容器時,使用存盤卷的目的通常在于資料持久化,
spec.containers.volumeMounts舉例:
spec
containers:
- name: myapp
volumeMounts:
- name:
mountPath:
readOnly:
subPath:
其中,name、mountPath為必填欄位,
臨時存盤卷emptyDir
emptyDir存盤卷的生命周期與其所屬的Pod物件相同,它無法脫離Pod物件的生命周期提供資料存盤功能,因此emptyDir通常僅用于一些特殊場景中,比如同一Pod內的多個容器間檔案的共享,或者作為容器資料的臨時存盤目錄用于資料快取系統等,
emptyDir存盤卷則定義于spec.volumes.emptyDir嵌套欄位中,可用欄位主要包含:
- medium:指定此目錄所在的存盤介質的型別,可取值為“default”或“Memory”,默認為default,表示使用節點的默認存盤介質;“Memory”表示使用基于RAM的臨時檔案系統tmpfs,空間受限于記憶體,但性能非常好,通常用于為容器中的應用提供快取空間,?
- sizeLimit:當前存盤卷的空間限額,默認值為nil,表示不限制;不過,在medium欄位值為“Memory”時建議務必定義此限額,
下面是emptyDir存盤卷的簡單示例:
apiVersion: v1
kind: Pod
metadata:
name: vol-emptydir-pod
spec:
volumes:
- name: html
emptyDir: {}
containers:
- name: nginx
image: nginx:1.12-alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: pagegen
image: alpine
volumeMounts:
- name: html
mountPath: /html
command: ["bin/sh", "-c"]
args: ["-c", "while true; do echo $(hostname) $(date) >> /html/index.html;sleep 10; done"]
作為邊車的容器paggen,其每隔10秒生成一行資訊追加到存盤卷上的index.html檔案中,然后通過主容器nginx的應用訪問到的內容會不斷變化,
apply上述配置清單后,啟動一個運行CirrOS容器的Pod來測驗:
kubectl run cirros-$RANDOM --rm -it --image=cirros -- sh
測驗curl Pod IP
/# curl 10.1.1.109
vol-emptydir-pod Mon May 31 14:07:14 UTC 2021
vol-emptydir-pod Mon May 31 14:07:24 UTC 2021
vol-emptydir-pod Mon May 31 14:07:34 UTC 2021
節點存盤卷hostPath
hostPath型別的存盤卷是將作業節點上某檔案系統的目錄或檔案掛載于Pod中的一種存盤卷,它可獨立于Pod資源的生命周期,具有持久性;但一般僅受控于daemonset,因為一旦Pod資源被重新調度至其他節點,別的節點并不一定保證存在掛載所指定的檔案或目錄,因此,這種型別的存盤卷只適用于Daemonset下的特定場景,比如運行有管理任務的系統級Pod資源需要訪問節點上的檔案時,
定義方式如:
spec:
volumes:
- name: html
hostPath:
path: /var/log
hostPath嵌套欄位共有兩個,path用于指定作業節點上的目錄路徑,屬于必選欄位,另外還是可選的type,用于指定存盤卷型別,包含以下幾種:
DirectoryOrCreate:指定的路徑不存時自動將其創建為權限是0755的空目錄,屬主和屬組同是kubelet,
Directory:必須存在的目錄路徑,?
FileOrCreate:指定的路徑不存時自動將其創建為權限是0644的空檔案,屬主和屬組同是kubelet,
File:必須存在的檔案路徑,?
Socket:必須存在的Socket檔案路徑,?
CharDevice:必須存在的字符設備檔案路徑,?
BlockDevice:必須存在的塊設備檔案路徑,
網路存盤卷
Kubernetes擁有眾多型別的用于適配專用存盤系統的網路存盤卷,這類存盤卷包括傳統的NAS或SAN設備(如NFS、iSCSI、fc)、分布式存盤(如GlusterFS、RBD)、云端存盤(如gcePersistentDisk、azureDisk、cinder和awsElasticBlockStore)以及建構在各類存盤系統之上的抽象管理層(如flocker、portworxVolume和vsphereVolume)等,
NFS存盤卷
NFS即網路檔案系統(Network File System),它是一種分布式檔案系統協議,允許客戶端主機可以像訪問本地存盤一樣通過網路訪問服務器端檔案,
Kubernetes的NFS存盤卷用于將某事先存在的NFS服務器上匯出的存盤空間掛載到Pod中以供容器使用,NFS存盤卷在Pod物件終止后僅是被卸載而非洗掉,此外NFS是檔案系統級共享服務,它支持同時存在的多路掛載請求,
下面示例定義了用于redis持久化的nfs:
spec:
volumes:
- name: redisdata
nfs:
server: nfs.ilinux.io
path: /var/log
readOnly: false
前提要存在名為nfs.ilinux.io的NFS服務器,其輸出了/data/redis目錄,并授權給了Kubernetes集群中的節點訪問,
RBD存盤卷
要使用RBD存盤卷需要先準備Ceph RDB存盤集群,Ceph是一個專注于分布式的、彈性可擴展的、高可靠的、性能優異的存盤系統平臺,同時支持提供塊設備、檔案系統和REST三種存盤介面,
使用示例:
spec:
volumes:
- name: redis-rdb-vol
rdb:
monitors:
- '172.16.0.45:6379'
- '172.16.0.46:6379'
pool: kube
image: redis
fsType: ext4
readOnly: false
user: admin
secretRef:
name: ceph-secret
配置RBD型別的存盤卷時,需要指定的欄位有:
monitors <[]string>:Ceph存盤監視器,逗號分隔的字串串列;必選欄位,?
image <string>:rados image的名稱,必選欄位,?
pool <string>:rados存盤池名稱,默認為RBD,?
user <string>:rados用戶名,默認為admin,?
keyring <string>:RBD用戶認證時使用的keyring檔案路徑,默認為/etc/ceph/keyring,?
secretRef <Object>:RBD用戶認證時使用的保存有相應認證資訊的Secret物件,會覆寫由keyring欄位提供的密鑰資訊,
readOnly <boolean>:是否以只讀的方式進行訪問,
GlusterFS存盤卷
GlusterFS(Gluster File System)是一個開源的分布式檔案系統,是水平擴展存盤解決方案Gluster的核心,具有強大的橫向擴展能力,GlusterFS通過擴展能夠支持數PB存盤容量和處理數千客戶端,GlusterFS借助TCP/IP或InfiniBand RDMA網路將物理分布的存盤資源聚集在一起,使用單一全域命名空間來管理資料,另外,GlusterFS基于可堆疊的用戶空間設計,可為各種不同的資料負載提供優異的性能,是另一種流行的分布式存盤解決方案,
使用示例:
spec:
volumes:
- name: redis-glusterfs-vol
glusterfs:
endpoints: glusterfs-endpoints
path: kube-redis
readOnly: false
常用的欄位有:
endpoints <string>:Endpoints資源的名稱,此資源需要事先存在,必選欄位,
path <string>:用到的GlusterFS集群的卷路徑,必選欄位,
readOnly <boolean>:是否為只讀卷,
其中的Endpoints資源需要提前創建,glusterfs-endpoints資源定義了GlusterFS集群的節點資訊:
apiVersion: v1
kind: Endpoints
metadata:
name: glusterfs-endpoints
spec:
- addresses:
- ip: gfs01.test.io
ports:
- port: 24007
name: glustered
Cinder存盤卷
Cinder是OpenStack Block Storage的專案名稱,用來為虛擬機(VM)實體提供持久塊存盤,將Kubernetes集群部署于OpenStack構建的IaaS環境中時,Cinder的塊存盤功能可為Pod資源提供外部持久存盤的有效方式,
使用示例:
spec:
volumes:
- name: redis-cinder-vol
cinder:
volumeID: ***
fsType: ext4
可定義的的欄位有:
volumeID <string>:用于標識Cinder中的存盤卷的卷識別符號,必選欄位,?
readOnly <boolean>:是否以只讀方式訪問,?
fsType:要掛載的存盤卷的檔案系統型別,至少應該是節點作業系統支持的檔案系統,如ext4、xfs、ntfs等,默認為“ext4”,
PersistentVolumeClaim
從前面對持久存盤卷的使用可知,Kubernetes用戶必須要清晰了解所用到的網路存盤系統的訪問細節才能完成存盤卷相關的配置任務,為了能進一步地隱藏底層架構的細節,使得對存盤資源的使用最好也能像使用計算資源一樣,用戶和開發人員無須了解Pod資源究竟運行于哪個節點,也無須了解存盤系統是什么設備以及位于何處,Kubernetes的PersistentVolume子系統在用戶與管理員之間添加了一個抽象層,從而使得存盤系統的使用和管理職能互相解耦,
PersistentVolume(PV)是指由集群管理員配置提供的某存盤系統上的一段存盤空間,它是對底層共享存盤的抽象,通過存盤插件機制,PV支持使用存盤系統,例如NFS、RBD和Cinder等,
PV是集群級別的資源,不屬于任何名稱空間,用戶對PV資源的使用需要通過PersistentVolumeClaim(PVC)來完成系結,PVC是PV資源的消費者,它向PV申請特定大小的空間及訪問模式(如rw或ro),從而創建出PVC存盤卷,Pod關聯使用的是PVC存盤卷,
創建PV
創建PV時需要定義PV的容量、訪問模式和回收策略等:
- Capacity,PV的容量
- 訪問模式,PV依賴的存盤設備支持及啟用的功能特性不盡相同,所以PV的模式要與存盤設備支持的功能保持一致,比如
- ReadWriteOnce:僅可被單個節點讀寫掛載;
- ReadOnlyMany:可被多個節點同時只讀掛載;
- ReadWriteMany:可被多個節點同時讀寫掛載;
- persistentVolumeReclaimPolicy,PV空間被釋放時的處理機制
- Retain:保持不動,由管理員隨后手動回收,這是默認選項
- Recycle:洗掉存盤卷目錄下的所有檔案(包括子目錄和隱藏檔案),目前僅NFS和hostPath支持此操作,
- Delete:洗掉存盤卷,區域分云端存盤系統支持,如AWS EBS、GCE PD、Azure Disk和Cinder,
- volumeMode:卷模型,用于指定此卷可被用作檔案系統還是裸格式的塊設備;默認為Filesystem,
- storageClassName:當前PV所屬的StorageClass的名稱;默認為空值,即不屬于任何StorageClass,
- mountOptions:掛載選項組成的串列,如ro、soft和hard等,
下面的配置清單定義了一個使用NFS存盤后端的PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-1
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: "/webdata"
server: nfs.ilinux.io
通過kubectl get pv可以看到,雖然指定的nfs server不可用,也可以apply成功,
創建PVC
創建PersistentVolumeClaim(PVC),即申請占用某個PersistentVolume,它與PV是一對一的關系,申請時,需要定義的欄位有:
- accessMode:當前PVC的訪問模式,其可用模式與PV相同,?
- resources:當前PVC存盤卷需要占用的資源量最小值;目前,PVC的資源限定僅指其空間大小,
- selector:系結時對PV應用的標簽選擇器(matchLabels)或匹配條件運算式(matchEx-pressions),用于挑選要系結的PV;如果同時指定了兩種挑選機制,則必須同時滿足,
- storageClassName:所依賴的存盤類的名稱,?
- volumeMode:卷模型,用于指定此卷可被用作檔案系統還是裸格式的塊設備;默認為“Filesystem”,
- volumeName:用于直接指定要系結的PV的卷名,
下面的PVC申請使用了前面創建的pv-nfs-1:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs-1
spec:
accessModes:
- ReadWriteMany
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
storageClassName: slow
volumeName: pv-nfs-1
在Pod中使用PVC
在Pod資源中呼叫PVC資源,只需要在定義volumes時使用persistentVolumeClaims欄位嵌套指定兩個欄位即可:
- claimName:要呼叫的PVC存盤卷的名稱,PVC卷要與Pod在同一名稱空間中,?
- readOnly:是否將存盤卷強制掛載為只讀模式,默認為false,
downwardAPI存盤卷
downwardAPI用于提供所在環境資訊的元資料,要使用downwardAPI可以通過環境變數和downwardAPI存盤卷兩種方式,
環境變數式元資料注入
只有常量類的屬性才能夠通過環境變數注入到容器中,因為在行程啟動完成后將無法再向其告知變數值的變動,環境變數也不支持中途的更新操作,
可以在valueFrom欄位中嵌套fieldRef或resourceFieldRef欄位來參考相應的資料源,通過fieldRef欄位可參考的資訊有:
spec.nodeName?
status.hostIP
metadata.name
metadata.namespace
status.podIP
spec.serviceAccountName:Pod物件使用的ServiceAccount資源的名稱
metadata.uid
metadata.labels['<KEY>']:Pod物件標簽中的指定鍵的值, 只有1.9及之后的版本支持
metadata.annotations['<KEY>']:Pod物件注解資訊中的指定鍵的值,僅1.9及之后的版本支持
通過resourceFieldRef欄位可參考的資訊是指當前容器的資源請求及資源限額的定義,包括requests.cpu、limits.cpu、requests.memory和limits.memory四項,
下面的示例中為容器注入了元資料資訊,應用會列印出所有的環境變數:
apiVersion: v1
kind: Pod
metadata:
name: env-test-pod
labels:
app: label-env-test-pod
spec:
containers:
- name: env-test-container
image: busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_APP_LABEL
valueFrom:
fieldRef:
fieldPath: metadata.labels['app']
apply后運行logs命令就可以看到成功注入的元資料資訊:
? kubectl logs env-test-pod | grep "^MY_"
MY_APP_LABEL=label-env-test-pod
MY_POD_NAME=env-test-pod
另外,在定義資源請求或資源限制時還可額外指定“divisor”欄位,用于為參考的值指定一個除數以實作所參考的相關值的單位換算,
存盤卷式元資料注入
向容器注入元資料資訊的另一種方式是使用downwardAPI存盤卷,它將配置的欄位資料映射為檔案并可通過容器中的掛載點進行訪問,
使用這種方式非常方便的一點是可通過metadata.labels或metadata.annotations獲取Pod物件的所有標簽資訊或注解資訊,每行一個,
apiVersion: v1
kind: Pod
metadata:
name: vol-test-pod
labels:
app: label-vol-test-pod
zone: us-east-2
spec:
containers:
- name: vol-test-container
image: busybox
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
defaultMode: 420
items:
- fieldRef:
fieldPath: metadata.name
path: pod_name
- fieldRef:
fieldPath: metadata.labels
path: pod_labels
apply后,可以在pod_labels查看所有的label
? kubectl exec vol-test-pod -- cat /etc/podinfo/pod_labels
app="label-vol-test-pod"
zone="us-east-2"%
而且對label的修改可以實時反映到volume中,比如執行kubectl label pods vol-test-pod env="test"后,再查看pod_labels檔案,已經包含了新增的label,
學習資料
《Kubernetes實戰進階》 馬永亮著
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/285970.html
標籤:其他
