K8S之存儲Volume概述與說明,並詳解常用Volume示例
主機配置規划
服務器名稱(hostname) | 系統版本 | 配置 | 內網IP | 外網IP(模擬) |
---|---|---|---|---|
k8s-master | CentOS7.7 | 2C/4G/20G | 172.16.1.110 | 10.0.0.110 |
k8s-node01 | CentOS7.7 | 2C/4G/20G | 172.16.1.111 | 10.0.0.111 |
k8s-node02 | CentOS7.7 | 2C/4G/20G | 172.16.1.112 | 10.0.0.112 |
Volume概述
在容器中的文件在磁盤上是臨時存放的,當容器關閉時這些臨時文件也會被一並清除。這給容器中運行的特殊應用程序帶來一些問題。
首先,當容器崩潰時,kubelet 將重新啟動容器,容器中的文件將會丟失——因為容器會以干凈的狀態重建。
其次,當在一個 Pod 中同時運行多個容器時,常常需要在這些容器之間共享文件。
Kubernetes 抽象出 Volume 對象來解決這兩個問題。
Kubernetes Volume卷具有明確的生命周期——與包裹它的 Pod 相同。 因此,Volume比 Pod 中運行的任何容器的存活期都長,在容器重新啟動時數據也會得到保留。 當然,當一個 Pod 不再存在時,Volume也將不再存在。更重要的是,Kubernetes 可以支持許多類型的Volume卷,Pod 也能同時使用任意數量的Volume卷。
使用卷時,Pod 聲明中需要提供卷的類型 (.spec.volumes 字段)和卷掛載的位置 (.spec.containers.volumeMounts 字段).
Volume類型
Kubernetes 支持下列類型的卷:
1 awsElasticBlockStore 2 azureDisk 3 azureFile 4 cephfs 5 cinder 6 configMap 7 csi 8 downwardAPI 9 emptyDir 10 fc (fibre channel) 11 flexVolume 12 flocker 13 gcePersistentDisk 14 gitRepo (deprecated) 15 glusterfs 16 hostPath 17 iscsi 18 local 19 nfs 20 persistentVolumeClaim 21 projected 22 portworxVolume 23 quobyte 24 rbd 25 scaleIO 26 secret 27 storageos 28 vsphereVolume
這里我們只介紹常用的存儲,包括:Secret、ConfigMap、emptyDir、hostPath。
其中Secret參考文章:「Kubernetes K8S之存儲Secret詳解」
ConfigMap參考文章:「Kubernetes K8S之存儲ConfigMap詳解」
本文只說emptyDir和hostPath存儲。
emptyDir卷
當 Pod 指定到某個節點上時,首先創建的是一個 emptyDir 卷,並且只要 Pod 在該節點上運行,卷就一直存在。就像它的名稱表示的那樣,卷最初是空的。
盡管 Pod 中每個容器掛載 emptyDir 卷的路徑可能相同也可能不同,但是這些容器都可以讀寫 emptyDir 卷中相同的文件。
如果Pod中有多個容器,其中某個容器重啟,不會影響emptyDir 卷中的數據。當 Pod 因為某些原因被刪除時,emptyDir 卷中的數據也會永久刪除。
注意:容器崩潰並不會導致 Pod 被從節點上移除,因此容器崩潰時 emptyDir 卷中的數據是安全的。
emptyDir的一些用途:
- 緩存空間,例如基於磁盤的歸並排序
- 為耗時較長的計算任務提供檢查點,以便任務能方便地從崩潰前狀態恢復執行
- 在 Web 服務器容器服務數據時,保存內容管理器容器獲取的文件
emptyDir示例
yaml文件
1 [root@k8s-master emptydir]# pwd 2 /root/k8s_practice/emptydir 3 [root@k8s-master emptydir]# cat pod_emptydir.yaml 4 apiVersion: v1 5 kind: Pod 6 metadata: 7 name: pod-emptydir 8 namespace: default 9 spec: 10 containers: 11 - name: myapp-pod 12 image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 13 imagePullPolicy: IfNotPresent 14 volumeMounts: 15 - mountPath: /cache 16 name: cache-volume 17 - name: busybox-pod 18 image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24 19 imagePullPolicy: IfNotPresent 20 command: ["/bin/sh", "-c", "sleep 3600"] 21 volumeMounts: 22 - mountPath: /test/cache 23 name: cache-volume 24 volumes: 25 - name: cache-volume 26 emptyDir: {}
啟動pod,並查看狀態
1 [root@k8s-master emptydir]# kubectl apply -f pod_emptydir.yaml 2 pod/pod-emptydir created 3 [root@k8s-master emptydir]# 4 [root@k8s-master emptydir]# kubectl get pod -o wide 5 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 6 pod-emptydir 2/2 Running 0 10s 10.244.2.166 k8s-node02 <none> <none> 7 [root@k8s-master emptydir]# 8 [root@k8s-master emptydir]# kubectl describe pod pod-emptydir 9 Name: pod-emptydir 10 Namespace: default 11 Priority: 0 12 Node: k8s-node02/172.16.1.112 13 Start Time: Fri, 12 Jun 2020 22:49:11 +0800 14 Labels: <none> 15 Annotations: kubectl.kubernetes.io/last-applied-configuration: 16 {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-emptydir","namespace":"default"},"spec":{"containers":[{"image":"... 17 Status: Running 18 IP: 10.244.2.166 19 IPs: 20 IP: 10.244.2.166 21 Containers: 22 myapp-pod: 23 Container ID: docker://d45663776b40a24e7cfc3cf46cb08cf3ed6b98b023a5d2cb5f42bee2234c7338 24 Image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 25 Image ID: docker-pullable://10.0.0.110:5000/k8s-secret/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e 26 Port: <none> 27 Host Port: <none> 28 State: Running 29 Started: Fri, 12 Jun 2020 22:49:12 +0800 30 Ready: True 31 Restart Count: 0 32 Environment: <none> 33 Mounts: 34 /cache from cache-volume (rw) ##### 掛載信息 35 /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro) 36 busybox-pod: 37 Container ID: docker://c2917ba30c3322fb0caead5d97476b341e691f9fb1990091264364b8cd340512 38 Image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24 39 Image ID: docker-pullable://registry.cn-beijing.aliyuncs.com/ducafe/busybox@sha256:f73ae051fae52945d92ee20d62c315306c593c59a429ccbbdcba4a488ee12269 40 Port: <none> 41 Host Port: <none> 42 Command: 43 /bin/sh 44 -c 45 sleep 3600 46 State: Running 47 Started: Fri, 12 Jun 2020 22:49:12 +0800 48 Ready: True 49 Restart Count: 0 50 Environment: <none> 51 Mounts: 52 /test/cache from cache-volume (rw) ##### 掛載信息 53 /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro) 54 Conditions: 55 Type Status 56 Initialized True 57 Ready True 58 ContainersReady True 59 PodScheduled True 60 Volumes: 61 cache-volume: 62 Type: EmptyDir (a temporary directory that shares a pod's lifetime) 63 Medium: 64 SizeLimit: <unset> 65 default-token-v48g4: 66 Type: Secret (a volume populated by a Secret) 67 SecretName: default-token-v48g4 68 Optional: false 69 QoS Class: BestEffort 70 Node-Selectors: <none> 71 Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s 72 node.kubernetes.io/unreachable:NoExecute for 300s 73 Events: 74 Type Reason Age From Message 75 ---- ------ ---- ---- ------- 76 Normal Scheduled 3s default-scheduler Successfully assigned default/pod-emptydir to k8s-node02 77 Normal Pulled 2s kubelet, k8s-node02 Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine 78 Normal Created 2s kubelet, k8s-node02 Created container myapp-pod 79 Normal Started 2s kubelet, k8s-node02 Started container myapp-pod 80 Normal Pulled 2s kubelet, k8s-node02 Container image "registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24" already present on machine 81 Normal Created 2s kubelet, k8s-node02 Created container busybox-pod 82 Normal Started 2s kubelet, k8s-node02 Started container busybox-pod
emptyDir驗證
在pod中的myapp-pod容器內操作
1 [root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c myapp-pod -- sh 2 / # cd /cache 3 /cache # 4 /cache # pwd 5 /cache 6 /cache # 7 /cache # date >> data.info 8 /cache # ls -l 9 total 4 10 -rw-r--r-- 1 root root 29 Jun 12 14:53 data.info 11 /cache # cat data.info 12 Fri Jun 12 14:53:27 UTC 2020
在pod中的busybox-pod容器內操作
1 [root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c busybox-pod -- sh 2 / # cd /test/cache 3 /test/cache # ls -l 4 total 4 5 -rw-r--r-- 1 root root 29 Jun 12 14:53 data.info 6 /test/cache # cat data.info 7 Fri Jun 12 14:53:27 UTC 2020 8 /test/cache # 9 /test/cache # echo "===" >> data.info 10 /test/cache # date >> data.info 11 /test/cache # cat data.info 12 Fri Jun 12 14:53:27 UTC 2020 13 === 14 Fri Jun 12 14:56:05 UTC 2020
由上可見,一個Pod中多個容器可共享同一個emptyDir卷。
hostPath卷
hostPath 卷能將主機node節點文件系統上的文件或目錄掛載到你的 Pod 中。 雖然這不是大多數 Pod 需要的,但是它為一些應用程序提供了強大的逃生艙。
hostPath 的一些用法有
- 運行一個需要訪問 Docker 引擎內部機制的容器;請使用 hostPath 掛載 /var/lib/docker 路徑。
- 在容器中運行 cAdvisor 時,以 hostPath 方式掛載 /sys。
- 允許 Pod 指定給定的 hostPath 在運行 Pod 之前是否應該存在,是否應該創建以及應該以什么方式存在。
支持類型
除了必需的 path 屬性之外,用戶可以選擇性地為 hostPath 卷指定 type。支持的 type 值如下:
取值 | 行為 |
---|---|
空字符串(默認)用於向后兼容,這意味着在安裝 hostPath 卷之前不會執行任何檢查 | |
DirectoryOrCreate | 如果指定的路徑不存在,那么將根據需要創建空目錄,權限設置為 0755,具有與 Kubelet 相同的組和所有權 |
Directory | 給定的路徑必須存在 |
FileOrCreate | 如果給定路徑的文件不存在,那么將在那里根據需要創建空文件,權限設置為 0644,具有與 Kubelet 相同的組和所有權【前提:文件所在目錄必須存在;目錄不存在則不能創建文件】 |
File | 給定路徑上的文件必須存在 |
Socket | 在給定路徑上必須存在的 UNIX 套接字 |
CharDevice | 在給定路徑上必須存在的字符設備 |
BlockDevice | 在給定路徑上必須存在的塊設備 |
注意事項
當使用這種類型的卷時要小心,因為:
- 具有相同配置(例如從 podTemplate 創建)的多個 Pod 會由於節點上文件的不同而在不同節點上有不同的行為。
- 當 Kubernetes 按照計划添加資源感知的調度時,這類調度機制將無法考慮由 hostPath 卷使用的資源。
- 基礎主機上創建的文件或目錄只能由 root 用戶寫入。需要在 特權容器 中以 root 身份運行進程,或者修改主機上的文件權限以便容器能夠寫入 hostPath 卷。
hostPath示例
yaml文件
1 [root@k8s-master hostpath]# pwd 2 /root/k8s_practice/hostpath 3 [root@k8s-master hostpath]# cat pod_hostpath.yaml 4 apiVersion: v1 5 kind: Pod 6 metadata: 7 name: pod-hostpath 8 namespace: default 9 spec: 10 containers: 11 - name: myapp-pod 12 image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 13 imagePullPolicy: IfNotPresent 14 volumeMounts: 15 - name: hostpath-dir-volume 16 mountPath: /test-k8s/hostpath-dir 17 - name: hostpath-file-volume 18 mountPath: /test/hostpath-file/test.conf 19 volumes: 20 - name: hostpath-dir-volume 21 hostPath: 22 # 宿主機目錄 23 path: /k8s/hostpath-dir 24 # hostPath 卷指定 type,如果目錄不存在則創建(可創建多層目錄) 25 type: DirectoryOrCreate 26 - name: hostpath-file-volume 27 hostPath: 28 path: /k8s2/hostpath-file/test.conf 29 # 如果文件不存在則創建。 前提:文件所在目錄必須存在 目錄不存在則不能創建文件 30 type: FileOrCreate
啟動pod,並查看狀態
1 [root@k8s-master hostpath]# kubectl apply -f pod_hostpath.yaml 2 pod/pod-hostpath created 3 [root@k8s-master hostpath]# 4 [root@k8s-master hostpath]# kubectl get pod -o wide 5 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 6 pod-hostpath 1/1 Running 0 17s 10.244.4.133 k8s-node01 <none> <none> 7 [root@k8s-master hostpath]# 8 [root@k8s-master hostpath]# kubectl describe pod pod-hostpath 9 Name: pod-hostpath 10 Namespace: default 11 Priority: 0 12 Node: k8s-node01/172.16.1.111 13 Start Time: Sat, 13 Jun 2020 16:12:15 +0800 14 Labels: <none> 15 Annotations: kubectl.kubernetes.io/last-applied-configuration: 16 {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-hostpath","namespace":"default"},"spec":{"containers":[{"image":"... 17 Status: Running 18 IP: 10.244.4.133 19 IPs: 20 IP: 10.244.4.133 21 Containers: 22 myapp-pod: 23 Container ID: docker://8cc87217fb483288067fb6d227c46aa890d02f75cae85c6d110646839435ab96 24 Image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 25 Image ID: docker-pullable://registry.cn-beijing.aliyuncs.com/google_registry/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e 26 Port: <none> 27 Host Port: <none> 28 State: Running 29 Started: Sat, 13 Jun 2020 16:12:17 +0800 30 Ready: True 31 Restart Count: 0 32 Environment: <none> 33 Mounts: 34 /test-k8s/hostpath-dir from hostpath-dir-volume (rw) 35 /test/hostpath-file/test.conf from hostpath-file-volume (rw) 36 /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro) 37 Conditions: 38 Type Status 39 Initialized True 40 Ready True 41 ContainersReady True 42 PodScheduled True 43 Volumes: 44 hostpath-dir-volume: 45 Type: HostPath (bare host directory volume) 46 Path: /k8s/hostpath-dir 47 HostPathType: DirectoryOrCreate 48 hostpath-file-volume: 49 Type: HostPath (bare host directory volume) 50 Path: /k8s2/hostpath-file/test.conf 51 HostPathType: FileOrCreate 52 default-token-v48g4: 53 Type: Secret (a volume populated by a Secret) 54 SecretName: default-token-v48g4 55 Optional: false 56 QoS Class: BestEffort 57 Node-Selectors: <none> 58 Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s 59 node.kubernetes.io/unreachable:NoExecute for 300s 60 Events: 61 Type Reason Age From Message 62 ---- ------ ---- ---- ------- 63 Normal Scheduled <unknown> default-scheduler Successfully assigned default/pod-hostpath to k8s-node01 64 Normal Pulled 12m kubelet, k8s-node01 Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine 65 Normal Created 12m kubelet, k8s-node01 Created container myapp-pod 66 Normal Started 12m kubelet, k8s-node01 Started container myapp-pod
hostPath驗證
根據pod,在k8s-node01節點宿主機操作【因為Pod分配到了該節點】
1 # 對掛載的目錄操作 2 [root@k8s-node01 hostpath-dir]# pwd 3 /k8s/hostpath-dir 4 [root@k8s-node01 hostpath-dir]# echo "dir" >> info 5 [root@k8s-node01 hostpath-dir]# date >> info 6 [root@k8s-node01 hostpath-dir]# cat info 7 dir 8 Sat Jun 13 16:22:37 CST 2020 9 # 對掛載的文件操作 10 [root@k8s-node01 hostpath-file]# pwd 11 /k8s2/hostpath-file 12 [root@k8s-node01 hostpath-file]# echo "file" >> test.conf 13 [root@k8s-node01 hostpath-file]# date >> test.conf 14 [root@k8s-node01 hostpath-file]# 15 [root@k8s-node01 hostpath-file]# cat test.conf 16 file 17 Sat Jun 13 16:23:05 CST 2020
在Pod 容器中操作
1 # 進入pod 中的指定容器【如果只有一個容器,那么可以不指定容器】 2 [root@k8s-master hostpath]# kubectl exec -it pod-hostpath -c myapp-pod -- /bin/sh 3 ##### 對掛載的目錄操作 4 / # cd /test-k8s/hostpath-dir 5 /test-k8s/hostpath-dir # ls -l 6 total 4 7 -rw-r--r-- 1 root root 33 Jun 13 08:22 info 8 /test-k8s/hostpath-dir # cat info 9 dir 10 Sat Jun 13 16:22:37 CST 2020 11 /test-k8s/hostpath-dir # 12 /test-k8s/hostpath-dir # date >> info 13 /test-k8s/hostpath-dir # cat info 14 dir 15 Sat Jun 13 16:22:37 CST 2020 16 Sat Jun 13 08:26:10 UTC 2020 17 ##### 對掛載的文件操作 18 # cd /test/hostpath-file/ 19 /test/hostpath-file # cat test.conf 20 file 21 Sat Jun 13 16:23:05 CST 2020 22 /test/hostpath-file # echo "file====" >> test.conf 23 /test/hostpath-file # cat test.conf 24 file 25 Sat Jun 13 16:23:05 CST 2020 26 file====
相關閱讀
2、Kubernetes K8S之存儲ConfigMap詳解
———END———
如果覺得不錯就關注下唄 (-^O^-) !