1. 程式人生 > >kubernetes Value:將磁碟掛載到容器,PV,PVC

kubernetes Value:將磁碟掛載到容器,PV,PVC

6.1.介紹卷

6.1.1.卷的型別

emptyDir-用於儲存臨時資料的簡單空目錄

hostPath-用於將目錄從工作節點的檔案系統掛載到pod

nfs-掛載到pod中的NFS共享卷。

還有其他的如gitRepo、gcepersistenDisk

 

6.2.通過卷在容器間共享資料

6.2.1.使用emptyDir卷

卷的生命週期與pod的生命週期項關聯,所以當刪除pod時,卷的內容就會丟失。

使用empty示例程式碼如下:

apiVersion: v1
kind: Pod
metadata:
  name: fortune
spec:
  containers:
  - image: luksa/fortune
    name: html-gener
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx
      readOnly: true
  - image: nginx/aplin
    name: web-service
    volumeMounts:
    - name: html
      mountPath: /usr/share
      readOnly: true
  volumes:
  - name: html                        //一個名為html的單獨emptyDir卷,掛載在上面的兩個容器中
    emptyDir: {}

  

6.3.訪問工作節點檔案系統上的檔案

6.3.1.hostPath卷

hostPath是永續性儲存,emptyDir卷的內容隨著pod的刪除而刪除。

使用hostPath會發現當刪除一個pod,並且下一個pod使用了指向主機上相同路徑的hostPath卷,則新pod將會發現上一個pod留下的資料,但前提是必須將其排程到與第一個pod相同的節點上。

所以當你使用hostPath時請務必考慮清楚,當重新起一個pod時候,必須要保證pod的節點與之前相同。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

 

6.4.使用持久化儲存

怎樣保證pod重新啟動後排程到任意一個節點都有相同的資料可用,這就需要做到持久化儲存。

因此必須要將資料儲存在某種型別的網路儲存(NAS)中。

各種支援的方式不盡相同,例如 GlusterFS 需要建立 Endpoint,Ceph/NFS 之流就沒這麼麻煩了。

6.4.1.使用NFS儲存

以NFS為例,yml程式碼如下:

 

 

 

6.4.2.configmap和secert

secret和configmap可以理解為特殊的儲存卷,但是它們不是給Pod提供儲存功能的,而是提供了從叢集外部向叢集內部的應用注入配置資訊的功能。ConfigMap扮演了K8S叢集中配置中心的角色。ConfigMap定義了Pod的配置資訊,可以以儲存卷的形式掛載至Pod中的應用程式配置檔案目錄,從configmap中讀取配置資訊;也可以基於環境變數的形式,從ConfigMap中獲取變數注入到Pod容器中使用。但是ConfigMap是明文儲存的,如果用來儲存資料庫賬號密碼這樣敏感資訊,就非常不安全。一般這樣的敏感資訊配置是通過secret

來儲存。secret的功能和ConfigMap一樣,不過secret是通過Base64的編碼機制儲存配置資訊。

從ConfigMap中獲取配置資訊的方法有兩種:

  • 一種是利用環境變數將配置資訊注入Pod容器中的方式,這種方式只在Pod建立的時候生效,這就意味著在ConfigMap中的修改配置資訊後,更新的配置不能被已經建立Pod容器所應用。
  • 另一種是將ConfigMap做為儲存卷掛載至Pod容器內,這樣在修改ConfigMap配置資訊後,Pod容器中的配置也會隨之更新,不過這個過程會有稍微的延遲。

ConfigMap當作儲存卷掛載至Pod中的用法:

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap-vol-2
  labels:
    name: pod-configmap-vol-2
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: my-cm-www
      mountPath: /etc/nginx/conf.d/       # 將名為my-www的configmap掛載至Pod容器的這個目錄下。
  volumes:
  - name: my-cm-www
    configMap:               # 儲存卷型別選configMap

  secert的方法類似,只是secert對資料進行了加密

 

6.5.從底層儲存技術解耦pod

6.5.1.介紹持久卷和持久卷宣告

  當叢集使用者需要在其pod中使用持久化儲存時,他們首先建立持久化宣告(PVC)清單,指定所需要的最低容量要求,和訪問模式,然後使用者將持久卷宣告清單提交給kubernetes API伺服器,kubernetes將找到可以匹配的持久卷並將其繫結到持久卷宣告。

  持久卷宣告可以當做pod中的一個捲來使用,其他使用者不能使用相同的持久卷,除非先通過刪除持久卷宣告繫結來釋放。

6.5.2.建立持久卷

下面建立一個 PV mypv1,配置檔案pv1.yml 如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: yh_pv1
spec:
  capacity:
    storage: 1Gi                //capacity 指定 PV 的容量為 1G
  accessModes:                 //accessModes 指定訪問模式為 ReadWriteOnce
    - ReadWriteOnce            
  persistentVolumeReclaimpolicy: Recycle  //persistentVolumeReclaimPolicy 指定當 PV 的回收策略為 Recycle
  storageClassName: nfs         //storageClassName 指定 PV 的 class 為 nfs。相當於為 PV 設定了一個分類,PVC 可以指定 class 申請相應 class 的 PV。
  nfs:
    path: /nfs/data             //指定 PV 在 NFS 伺服器上對應的目錄
    server: 10.10.0.11

1.accessModes 指定訪問模式為 ReadWriteOnce,支援的訪問模式有:

  ReadWriteOnce – PV 能以 read-write 模式 mount 到單個節點。
  ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節點。
  ReadWriteMany – PV 能以 read-write 模式 mount 到多個節點。

2.persistentVolumeReclaimPolicy 指定當 PV 的回收策略為 Recycle,支援的策略有:
  Retain – 需要管理員手工回收。
  Recycle – 清除 PV 中的資料,效果相當於執行 rm -rf /thevolume/*
  Delete – 刪除 Storage Provider 上的對應儲存資源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

 

建立 pv

# kubectl apply -f pv1.yml 
persistentvolume/yh-pv1 created

 

檢視pv:

# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
yh-pv1   1Gi        RWO            Recycle          Available           nfs                     17m

  

STATUS 為 Available,表示 yh-pv1就緒,可以被 PVC 申請。

6.5.3.通過持久卷宣告來獲取持久卷

 

接下來建立 PVC mypvc1,配置檔案 pvc1.yml 如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: yh-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs

  

PVC 就很簡單了,只需要指定 PV 的容量,訪問模式和 class。

執行命令建立 mypvc1

# kubectl apply -f pvc1.yml 
persistentvolumeclaim/yh-pvc created

檢視pvc

# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
yh-pvc   Bound    yh-pv1   1Gi        RWO            nfs            64s

 

從 kubectl get pvc 和 kubectl get pv 的輸出可以看到 yh-pvc1 已經 Bound 到yh- pv1,申請成功。

 

# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
yh-pv1   1Gi        RWO            Recycle          Bound    default/yh-pvc   nfs                     47m

  

6.5.4.在pod中使用持久卷宣告

上面已經建立好了pv和pvc,pod中直接使用這個pvc即可

與使用普通 Volume 的格式類似,在 volumes 中通過 persistentVolumeClaim 指定使用 mypvc1 申請的 Volume。

 通過命令建立mypod1

可見,在 Pod 中建立的檔案 /mydata/hello 確實已經儲存到了 NFS 伺服器目錄 /nfsdata中。

如果不再需要使用 PV,可用刪除 PVC 回收 PV。

 

6.5.5.回收持久卷

當 PV 不再需要時,可通過刪除 PVC 回收。

未刪除pvc之前  pv的狀態是Bound

刪除pvc之後pv的狀態變為Available,,此時解除繫結後則可以被新的 PVC 申請。

/nfsdata檔案中的檔案被刪除了

 

因為 PV 的回收策略設定為 Recycle,所以資料會被清除,但這可能不是我們想要的結果。如果我們希望保留資料,可以將策略設定為 Retain

通過 kubectl apply 更新 PV:

 

回收策略已經變為 Retain,通過下面步驟驗證其效果:

 

① 重新建立 mypvc1

② 在 mypv1 中建立檔案 hello

③ mypv1 狀態變為 Released

④ PV 中的資料被完整保留。

雖然 mypv1 中的資料得到了保留,但其 PV 狀態會一直處於 Released,不能被其他 PVC 申請。為了重新使用儲存資源,可以刪除並重新建立 mypv1。刪除操作只是刪除了 PV 物件,儲存空間中的資料並不會被刪除。

 

新建的 mypv1 狀態為 Available,已經可以被 PVC 申請。

PV 還支援 Delete 的回收策略,會刪除 PV 在 Storage Provider 上對應儲存空間。NFS 的 PV 不支援 Delete,支援 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

 

6.6.持久卷的動態配置

6.6.1.通過StorageClass資源定義可用儲存型別

前面的例子中,我們提前建立了 PV,然後通過 PVC 申請 PV 並在 Pod 中使用,這種方式叫做靜態供給(Static Provision)。

與之對應的是動態供給(Dynamical Provision),即如果沒有滿足 PVC 條件的 PV,會動態建立 PV。相比靜態供給,動態供給有明顯的優勢:不需要提前建立 PV,減少了管理員的工作量,效率高。

動態供給是通過 StorageClass 實現的,StorageClass 定義瞭如何建立 PV,下面是兩個例子。

StorageClass standard

StorageClass slow

這兩個 StorageClass 都會動態建立 AWS EBS,不同在於 standard 建立的是 gp2 型別的 EBS,而 slow 建立的是 io1 型別的 EBS。不同型別的 EBS 支援的引數可參考 AWS 官方文件。

StorageClass 支援 Delete 和 Retain 兩種 reclaimPolicy,預設是 Delete

與之前一樣,PVC 在申請 PV 時,只需要指定 StorageClass 和容量以及訪問模式,比如:

 

除了 AWS EBS,Kubernetes 支援其他多種動態供給 PV 的 Provisioner,完整列表請參考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

 

6.6.2.PV&&PVC在應用在mysql的持久化儲存

下面演示如何為 MySQL 資料庫提供持久化儲存,步驟為:

  1. 建立 PV 和 PVC。

  2. 部署 MySQL。

  3. 向 MySQL 新增資料。

  4. 模擬節點宕機故障,Kubernetes 將 MySQL 自動遷移到其他節點。

  5. 驗證資料一致性。

 

首先建立 PV 和 PVC,配置如下:

mysql-pv.yml

 

mysql-pvc.yml

建立 mysql-pv 和 mysql-pvc

 

接下來部署 MySQL,配置檔案如下:

 

 PVC mysql-pvc Bound 的 PV mysql-pv 將被 mount 到 MySQL 的資料目錄 var/lib/mysql

MySQL 被部署到 k8s-node2,下面通過客戶端訪問 Service mysql

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

 

更新資料庫:

① 切換到資料庫 mysql。

② 建立資料庫表 my_id。

③ 插入一條資料。

④ 確認資料已經寫入。

 關閉 k8s-node2,模擬節點宕機故障。

 

驗證資料的一致性:

 由於node2節點已經宕機,node1節點接管了這個任務。

通過kubectl run 命令 進入node1的這個pod裡,檢視資料是否依舊存在

 

MySQL 服務恢復,資料也完好無