目錄
- 概念
- Volumes
- ConfigMap && Secret
- hostPath
- 模版
- emptyDir
- 模版
- PV
- 模版
- PVC
- 模版
- 實戰
- volumes - hostPath
- volumes - emptyDir
- PV & PVC - hostPath
- 注意項
- 參考
概念
Volumes
容器中的磁盤檔案是短暫的,容器崩潰後,再次重新開機,資料就丢失了。k8s通過volumes進行資料持久化和共享資料。volumes的本質就是一個目錄。volume有很多類型,有些已經棄用了,這裡提幾個還在用的。
ConfigMap && Secret
之前介紹過,可以檢視下面的文章:
k8s學習-ConfigMap(建立、使用、更新、删除等)k8s學習-Secret(建立、使用、更新、删除等)
hostPath
hostPath卷能将主機節點檔案系統上的檔案或目錄挂載到你的 Pod 中。
hostPath卷存在許多安全風險,最佳做法是盡可能避免使用hostPath。 當必須使用hostPath 卷時,它的範圍應僅限于所需的檔案或目錄,并以隻讀方式挂載。
如果通過 AdmissionPolicy 限制hostPath 對特定目錄的通路,則必須要求 volumeMounts 使用 readOnly 挂載以使政策生效。
注意:使用hostPath時,别忘了指定Pod部署的節點。
模版
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主上目錄位置
path: /data
# 此字段為可選
type:
支援的 type 值如下:
取值 | 行為 |
空字元串(預設)用于向後相容,這意味着在安裝 hostPath 卷之前不會執行任何檢查。 | |
| 如果在給定路徑上什麼都不存在,那麼将根據需要建立空目錄,權限設定為 0755,具有與 kubelet 相同的組和屬主資訊。 |
| 在給定路徑上必須存在的目錄。 |
| 如果在給定路徑上什麼都不存在,那麼将在那裡根據需要建立空檔案,權限設定為 0644,具有與 kubelet 相同的組和所有權。 |
| 在給定路徑上必須存在的檔案。 |
| 在給定路徑上必須存在的 UNIX 套接字。 |
| 在給定路徑上必須存在的字元裝置。 |
| 在給定路徑上必須存在的塊裝置。 |
emptyDir
當 Pod 分派到某個 Node 上時,emptyDir 卷會被建立,并且在 Pod 在該節點上運作期間,卷一直存在。 就像其名稱表示的那樣,卷最初是空的。 盡管 Pod 中的容器挂載 emptyDir 卷的路徑可能相同也可能不同,這些容器都可以讀寫 emptyDir 卷中相同的檔案。 當 Pod 因為某些原因被從節點上删除時,emptyDir 卷中的資料也會被永久删除。
說明: 容器崩潰并不會導緻 Pod 被從節點上移除,是以容器崩潰期間 emptyDir 卷中的資料是安全的。
emptyDir 的一些用途:
- 緩存空間,例如基于磁盤的歸并排序。
- 為耗時較長的計算任務提供檢查點,以便任務能方便地從崩潰前狀态恢複執行。
- 在Web伺服器容器服務資料時,儲存内容管理器容器擷取的檔案。
模版
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
- image: test-webserver
name: test-container2
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
PV
PV就是持久卷(Persistent Volume),是叢集中的一塊存儲,可以由管理者事先制備, 或者使用存儲類(Storage Class)來動态制備。與Volume不同的是,它們有獨立的生命周期,是一種k8s資源,在kubectl中可以縮寫為pv。
模版
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server:
persistentVolumeReclaimPolicy有以下三種:
- Retain – 手動回收
- Delete – 諸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷這類關聯存儲資産也被删除
- Recycle – 基本擦除 (rm -rf /thevolume/*),已被廢棄,使用動态制備替代。
capacity: PV的容量
VolumeMode(卷模式)有兩種:
- Filesystem:被 Pod 挂載到某個目錄
- Block:這類卷以塊裝置的方式交給 Pod 使用,其上沒有任何檔案系統。
accessModes(通路模式)有以下幾種:
- ReadWriteOnce:單節點讀寫模式挂載
- ReadWriteMany:多節點讀寫模式挂載
- ReadOnlyMany:多節點隻讀模式挂載
說明:Kubernetes 使用卷通路模式來比對 PersistentVolumeClaim 和 PersistentVolume。 在某些場合下,卷通路模式也會限制 PersistentVolume 可以挂載的位置。
storageClassName:PVC和PV的保持一緻
每個卷會處于以下階段(Phase)之一:
- Available(可用)-- 卷是一個空閑資源,尚未綁定到任何申領;
- Bound(已綁定)-- 該卷已經綁定到某申領;
- Released(已釋放)-- 所綁定的申領已被删除,但是資源尚未被叢集回收;
- Failed(失敗)-- 卷的自動回收操作失敗。
PVC
PVC就是持久卷申領(PersistentVolumeClaim,PVC) 表達的是使用者對存儲的請求。Pod 将 PVC 申領當做存儲卷來使用。叢集會檢視 PVC 申領,找到所綁定的卷, 并為 Pod 挂載該卷。如果使用者删除被某 Pod 使用的 PVC 對象,該 PVC 申領不會被立即移除。 PVC 對象的移除會被推遲,直至其不再被任何 Pod 使用。
模版
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
selector說明:
- matchLabels - 卷必須包含帶有此值的标簽
- matchExpressions - 通過設定鍵(key)、值清單和操作符(operator) 來構造的需求。合法的操作符有 In、NotIn、Exists 和 DoesNotExist。
實戰
volumes - hostPath
主控端的時區、時間和Pod中容器的不一緻
修改一下上面的模版,nginx-hostpath.yaml如下
apiVersion: v1
kind: Pod
metadata:
name: nginx-hostpath
spec:
nodeName: xxx-105-centos
containers:
- image: nginx:1.14.2
name: nginx
volumeMounts:
- mountPath: /etc/timezone
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /etc/timezone
type:
根據個人情況,替換node名,鏡像等
指令
kubectl create -f nginx-hostpath.yaml
結果
可以看到,檔案挂載成功了。
volumes - emptyDir
busybox-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox-emptydir
spec:
containers:
- image: busybox:latest
name: busybox1
imagePullPolicy: IfNotPresent
command: ['sh','-c','sleep 3600']
volumeMounts:
- mountPath: /home
name: cache-volume
- image: busybox:latest
name: busybox2
imagePullPolicy: IfNotPresent
command: ['sh','-c','sleep 3600']
volumeMounts:
- mountPath: /home
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
指令
kubectl create -f busybox-emptydir.yaml
kubectl exec -it busybox-emptydir -c busybox1 -- touch /home/lady_killer
kubectl exec -it busybox-emptydir -c busybox2 -- ls
結果
PV & PVC - hostPath
任務:
- 建立一個pv,名字為app-config,大小為2Gi,通路權限為ReadWriteMany,storageClassName為manual。Volume的類型為hostPath,路徑為/srv/app-config
- 建立一個名字為app-config-pvc的pvc,綁定上面的pv,大小為10Mi
- 建立一個Pod,名字為web-server,鏡像為nginx:1.14.2,并且挂載該PVC至/usr/share/nginx/html,挂載的權限為ReadWriteMany。
app-config.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"
app-config-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-config
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage:
web-server-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
volumes:
- name: app-config
persistentVolumeClaim:
claimName: app-config
containers:
- name: nginx
image: nginx:1.14.2
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: app-config
指令
kubectl create -f app-config.yaml
kubectl create -f app-config-pvc.yaml
kubectl create -f web-server-pvc.yaml
結果
可以看到PV在建立PVC後,狀态由Available轉為Bound,說明PVC綁定成功。
注意項
綁定不上pv的可能情況:
- PVC的空間申領大小大于PV的大小
- PVC的StorageClassName與PV的不一緻
- PVC的accessModes和PV的不一緻
挂在PVC的Pod處于Pending狀态:
- PVC建立失敗
- PVC和Pod不在同一個namespace