kubernetes 磁盤、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 服務恢復,數據也完好無損。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM