1. 程式人生 > 其它 >Kubernetes(k8s)儲存管理之資料卷volumes(二):hostPath資料卷

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