Kubernetes(k8s)儲存管理之資料卷volumes(二):hostPath資料卷
一.系統環境
伺服器版本 | docker軟體版本 | Kubernetes(k8s)叢集版本 | CPU架構 |
---|---|---|---|
CentOS Linux release 7.4.1708 (Core) | Docker version 20.10.12 | v1.21.9 | x86_64 |
Kubernetes叢集架構:k8scloude1作為master節點,k8scloude2,k8scloude3作為worker節點
伺服器 | 作業系統版本 | CPU架構 | 程序 | 功能描述 |
---|---|---|---|---|
k8scloude1/192.168.110.130 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico | k8s master節點 |
k8scloude2/192.168.110.129 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker節點 |
k8scloude3/192.168.110.128 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker節點 |
二.前言
Kubernetes(k8s)資料卷volumes型別眾多,本文介紹資料卷volumes之一hostPath資料卷。
使用資料卷volumes的前提是已經有一套可以正常執行的Kubernetes叢集,關於Kubernetes(k8s)叢集的安裝部署,可以檢視部落格《Centos7 安裝部署Kubernetes(k8s)叢集》https://www.cnblogs.com/renshengdezheli/p/16686769.html
三.hostPath資料卷
3.1 hostPath資料卷概覽
警告:HostPath 卷存在許多安全風險,最佳做法是儘可能避免使用 HostPath。 當必須使用 HostPath 卷時,它的範圍應僅限於所需的檔案或目錄,並以只讀方式掛載。如果通過 AdmissionPolicy 限制 HostPath 對特定目錄的訪問,則必須要求 volumeMounts 使用 readOnly 掛載以使策略生效。
hostPath 卷能將主機節點檔案系統上的檔案或目錄掛載到你的 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 |
在給定路徑上必須存在的塊裝置。 |
當使用這種型別的卷時要小心,因為:
HostPath 卷可能會暴露特權系統憑據(例如 Kubelet)或特權 API(例如容器執行時套接字),可用於容器逃逸或攻擊叢集的其他部分。
具有相同配置(例如基於同一 PodTemplate 建立)的多個 Pod 會由於節點上檔案的不同而在不同節點上有不同的行為。下層主機上建立的檔案或目錄只能由 root 使用者寫入。 你需要在特權容器中以 root 身份執行程序,或者修改主機上的檔案許可權以便容器能夠寫入 hostPath 卷。
注意:FileOrCreate 模式不會負責建立檔案的父目錄。 如果欲掛載的檔案的父目錄不存在,Pod 啟動會失敗。 為了確保這種模式能夠工作,可以嘗試把檔案和它對應的目錄分開掛載。
hostPath卷類似於docker run -v /data:/xx
3.2 建立有hostPath卷的pod
配置本地卷hostPath,把v1卷掛載到/xx目錄
[root@k8scloude1 volume]# vim hostpath.yaml
[root@k8scloude1 volume]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: hostpath
name: hostpath
spec:
terminationGracePeriodSeconds: 0
#指定卷
volumes:
#卷的名字
- name: v1
#卷的型別為hostPath
hostPath:
#宿主上目錄位置
path: /hostdir
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: h1
resources: {}
volumeMounts:
- name: v1
mountPath: /xx
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
建立pod
[root@k8scloude1 volume]# kubectl apply -f hostpath.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath 1/1 Running 0 6s 10.244.112.183 k8scloude2 <none> <none>
進入pod,/xx/hostpath.txt寫入資料
[root@k8scloude1 volume]# kubectl exec -it hostpath -- bash
root@hostpath:/# echo "hostPath" >/xx/hostpath.txt
root@hostpath:/#
root@hostpath:/# ls /xx/
hostpath.txt test.txt
root@hostpath:/#
root@hostpath:/# exit
exit
在對應的k8scloude2上檢視容器
[root@k8scloude2 ~]# docker ps | grep hostpath
6e4d959332d3 605c77e624dd "/docker-entrypoint.…" 33 seconds ago Up 33 seconds k8s_h1_hostpath_volume_9bbf4660-7e37-4c38-b2db-900246301329_0
f5e3d63fe676 registry.aliyuncs.com/google_containers/pause:3.4.1 "/pause" 34 seconds ago Up 33 seconds k8s_POD_hostpath_volume_9bbf4660-7e37-4c38-b2db-900246301329_0
檢視物理機目錄:/hostdir,容器目錄:/xx
[root@k8scloude2 ~]# docker inspect 6e4d959332d3 | grep -A10 Mounts
"Mounts": [
{
"Type": "bind",
"Source": "/hostdir",
"Destination": "/xx",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
pod裡建立了hostpath.txt,對應的物理機目錄也生成了檔案
[root@k8scloude2 ~]# cat /hostdir/hostpath.txt
hostPath
[root@k8scloude2 ~]# touch /hostdir/test.txt
[root@k8scloude2 ~]# ls /hostdir/
hostpath.txt test.txt
刪除pod
[root@k8scloude1 volume]# kubectl delete pod hostpath --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "hostpath" force deleted
pod刪除了之後,k8scloude2對應物理機上的檔案還存在
[root@k8scloude2 ~]# ls /hostdir/
hostpath.txt test.txt
再次建立pod,對應的/xx/下的檔案還在
[root@k8scloude1 volume]# kubectl apply -f hostpath.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl exec -it hostpath -- bash
root@hostpath:/# ls /xx/
hostpath.txt test.txt
root@hostpath:/# exit
exit
[root@k8scloude1 volume]# kubectl delete pod hostpath --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "hostpath" force deleted
Tps:假如hostpath.yaml檔案丟失了,就可kubectl get pod hostpath -o yaml >hostpathpodx.yaml使用這種方式進行備份yaml檔案,執行hostpathpodx.yaml檔案,生成一個一模一樣的pod
[root@k8scloude1 volume]# kubectl apply -f hostpath.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath 1/1 Running 0 5s 10.244.112.185 k8scloude2 <none> <none>
[root@k8scloude1 volume]# kubectl get pod hostpath -o yaml >hostpathpodx.yaml
[root@k8scloude1 volume]# vim hostpathpodx.yaml
[root@k8scloude1 volume]# kubectl delete pod hostpath --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "hostpath" force deleted
[root@k8scloude1 volume]# kubectl get pods -o wide
No resources found in volume namespace.
重新生成的pod和之前一模一樣
[root@k8scloude1 volume]# kubectl apply -f hostpathpodx.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath 1/1 Running 0 6s 10.244.112.186 k8scloude2 <none> <none>
[root@k8scloude1 volume]# kubectl exec -it hostpath -- bash
root@hostpath:/# ls /xx/
hostpath.txt test.txt
root@hostpath:/# exit
exit
[root@k8scloude1 volume]# kubectl delete pod hostpath --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "hostpath" force deleted
可以新增readOnly: true選項,使容器目錄只具有隻讀許可權
[root@k8scloude1 volume]# vim hostpath.yaml
[root@k8scloude1 volume]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: hostpath
name: hostpath
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: v1
hostPath:
path: /hostdir
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: h1
resources: {}
volumeMounts:
- name: v1
mountPath: /xx
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
建立pod
[root@k8scloude1 volume]# kubectl apply -f hostpath.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath 1/1 Running 0 10s 10.244.112.187 k8scloude2 <none> <none>
只讀許可權,不能建立檔案
[root@k8scloude1 volume]# kubectl exec -it hostpath -- bash
root@hostpath:/# ls /xx/
hostpath.txt test.txt
root@hostpath:/# touch /xx/ceshi.txt
touch: cannot touch '/xx/ceshi.txt': Read-only file system
root@hostpath:/# exit
exit
command terminated with exit code 1
刪除pod
[root@k8scloude1 volume]# kubectl delete pod hostpath --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "hostpath" force deleted
nodeName: k8scloude3,讓pod執行在k8scloude3上
[root@k8scloude1 volume]# vim hostpath.yaml
[root@k8scloude1 volume]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: hostpath
name: hostpath
spec:
nodeName: k8scloude3
terminationGracePeriodSeconds: 0
volumes:
- name: v1
hostPath:
path: /hostdir
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: h1
resources: {}
volumeMounts:
- name: v1
mountPath: /xx
readOnly: true
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
建立pod
[root@k8scloude1 volume]# kubectl apply -f hostpath.yaml
pod/hostpath created
[root@k8scloude1 volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath 1/1 Running 0 3s 10.244.251.250 k8scloude3 <none> <none>
對應的/xx/目錄下面沒檔案,因為剛才是在k8scloude2上建立的檔案,現在k8scloude3上沒檔案,所以/xx/下面沒檔案,由於k8scloude2和k8scloude3沒有共享儲存,所以k8scloude2上有的檔案,k8scloude3上沒有,可以使用共享儲存捲來解決此問題。共享儲存卷請檢視部落格《Kubernetes(k8s)儲存管理之資料卷volumes(三):NFS資料卷》
[root@k8scloude1 volume]# kubectl exec -it hostpath -- bash
root@hostpath:/# ls /xx/
root@hostpath:/#
root@hostpath:/# exit
exit