k8s學習筆記之持久化存儲
知識大綱
- 理解持久化卷(pv),並知道如何創建它們
- 理解卷(volumes)的access mode
- 理解持久化卷聲明(pvc)的原語
- 理解k8s的存儲對象(kubernetes storage objects)
- 知道如何為應用配置持久化存儲
三個概念: pv ,storageclass, pvc
- pv - 持久化卷, 支持本地存儲和網路存儲, 例如hostpath,ceph rbd, nfs等,只支持兩個屬性, capacity和accessModes。其中capacity只支持size的定義,不支持iops等參數的設定,accessModes有三種,ReadWriteOnce(被單個node讀寫), ReadOnlyMany(被多個nodes讀), ReadWriteMany(被多個nodes讀寫)
- storageclass-另外一種提供存儲資源的方式, 提供更多的層級選型, 如iops等參數。 但是具體的參數與提供方是綁定的。 如aws和gce它們提供的storageclass的參數可選項是有不同的。
- pvc - 對pv或者storageclass資源的請求, pvc 對 pv 類比於pod 對不同的cpu, mem的請求。
六個生命周期: Provisioning, Binding, Using, Releasing, Reclaiming, Recycling
k8s對pv和pvc之間的交互的生命周期進行管理。
- provisioning- 配置階段, 分為static, dynamic兩種方式。靜態的方式是創建一系列的pv,然後pvc從pv中請求。 動態的方式是基於storageclass的。
- Binding - 綁定階段, pvc根據請求的條件篩選並綁定對應的pv。 一定pvc綁定pv後, 就會排斥其它綁定,即其它pvc無法再綁定同一個pv,即使這個pv設定的access mode允許多個node讀寫。 此外 ,pvc 如何匹配不到相應條件的pv, 那麼就會顯示unbound狀態, 直到匹配為止。 需要注意的是,pvc請求100Gi大小的存儲,即使用戶創建了很多50Gi大小的存儲, 也是無法被匹配的。
- Using- 使用階段, pods 掛載存儲, 即在pod的template文件中定義volumn使用某個pvc。
- Releasing - 釋放階段, 當pvc對象被刪除後, 就處於釋放階段。 在這個階段, 使用的pv還不能被其它的pvc請求。 之前數據可能還會留存下來, 取決於用戶在pv中設定的policy, 見persistentVolumeReclaimPolicy。
- Reclaiming - 重聲明階段。 到這個階段, 會告訴cluster如何處理釋放的pv。 數據可能被保留(需要手工清除), 回收和刪除。動態分配的存儲總是會被刪除掉的。
- Recycling - 回收階段。回收階段會執行基本的遞歸刪除(取決於volumn plugins的支持),把pv上的數據刪除掉, 以使pv可以被新的pvc請求。 用戶也可以自定義一個 recycler pod , 對數據進行刪除。
三種PV的訪問模式
- ReadWriteOnce:是最基本的方式,可讀可寫,但只支持被單個Pod掛載。
- ReadOnlyMany:可以以只讀的方式被多個Pod掛載。
- ReadWriteMany:這種存儲可以以讀寫的方式被多個Pod共享。
不是每一種存儲都支持這三種方式,像共享方式,目前支持的還比較少,比較常用的是NFS。在PVC綁定PV時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是訪問模式。
九個PV Plugins
pv是以plugin的形式來提供支持的, 考慮到私有雲的使用場景, 排除掉azure, aws,gce等公有雲廠商綁定的plugin, 有9個插件值得關注。這些plugin所支持的accessmode是不同的。 分別是:
三個重聲明策略(reclaim policy)
- Retain – 手動重新使用
- Recycle – 基本的數據擦除 (「rm -rf /thevolume/*」)
- Delete – 相關聯的後端存儲卷刪除, 後端存儲比如AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder
需要特別注意的是只有本地盤和nfs支持數據盤Recycle 擦除回收, AWS EBS, GCE PD, Azure Disk, and Cinder 存儲卷支持Delete策略
四個階段(volumn phase)
一個存儲卷會處於下面幾個階段中的一個階段:
- Available –資源可用, 還沒有被聲明綁定
- Bound – 被聲明綁定
- Released – 綁定的聲明被刪除了,但是還沒有被集群重聲明
- Failed – 自動回收失敗
四個PV選擇器
在PVC中綁定一個PV,可以根據下面幾種條件組合選擇
- Access Modes, 按照訪問模式選擇pv
- Resources, 按照資源屬性選擇, 比如說請求存儲大小為8個G的pv
- Selector, 按照pv的label選擇
- Class, 根據StorageClass的class名稱選擇, 通過annotation指定了Storage Class的名字, 來綁定特定類型的後端存儲
關於根據class過濾出pv的說明:
所有的 PVC 都可以在不使用 StorageClass 註解的情況下,直接使用某個動態存儲。把一個StorageClass 對象標記為 「default」 就可以了。StorageClass 用註解http://storageclass.beta.kubernetes.io/is-default-class 就可以成為預設存儲。有了預設的 StorageClass,用戶創建 PVC 就不用 storage-class 的註解了,1.4 中新加入的DefaultStorageClass 准入控制器會自動把這個標註指向預設存儲類。PVC 指定特定storageClassName,如fast時, 綁定名稱為fast的storageClassPVC中指定storageClassName為「」時, 綁定no class的pv(pv中無class annotation, 或者其值為「」)PVC不指定storageClassName時, DefaultStorageClass admission plugin 開啟與否(在apiserver啟動時可以指定), 對default class的解析行為是不同的。當DefaultStorageClass admission plugin啟用時, 針對沒有storageClass annotation的pvc,DefaultStorageClass會分配一個默認的class, 這個默認的class需要用戶指定,比如在創建storageclass對象時加入annotation,如 http://storageclass.beta.kubernetes.io/is-default-class: 「true」 。如果有多個默認的class, 則pvc會被拒絕創建, 如果用戶沒有指定默認的class, 則這個DefaultStorageClass admission plugin不會起任何作用。 pvc會找那些no class的pv做綁定。當DefaultStorageClass admission plugin沒有啟用時, 針對沒有storageClass annotation的pvc, 會綁定no class的pv(pv中無class annotation, 或者其值為「」)
五個可移植性建議
- 把你的 pvc,和 其它一系列配置放一起, 比如說deployment,configmap
- 不要把你的pv放在其它配置里, 因為用戶可能沒有許可權創建pv
- 初始化pvc 模版的時候, 提供一個storageclass
- 在你的工具軟體中,watch那些沒有bound的pvc,並呈現給用戶
- 集群啟動的時候啟用DefaultStorageClass, 但是不要指定某一類特定的class, 因為不同provisioner的class,參數很難一致
如何創建和使用PV, PVC
pv示例:
apiVersion: v1nkind: PersistentVolumenmetadata:n name: pv0003nspec:n capacity:n storage: 5Gin accessModes:n - ReadWriteOncen persistentVolumeReclaimPolicy: Recyclen storageClassName: slown nfs:n path: /tmpn server: 172.17.0.2n
pvc示例:
kind: PersistentVolumeClaimnapiVersion: v1nmetadata:n name: myclaimnspec:n accessModes:n - ReadWriteOncen resources:n requests:n storage: 8Gin storageClassName: slown selector:n matchLabels:n release: "stable"n matchExpressions:n - {key: environment, operator: In, values: [dev]}n
在pod中使用pvc,示例
kind: PodnapiVersion: v1nmetadata:n name: mypodnspec:> n containers:n - name: myfrontendn image: dockerfile/nginxn volumeMounts:n - mountPath: "/var/www/html"n name: mypdn volumes:n - name: mypdn persistentVolumeClaim:n claimName: myclaimn
參考文獻
- 官方文檔之持久化存儲
推薦閱讀:
※容器編排之Kubernetes安裝與配置
※梁勝關於容器的年終總結,沒再提Docker
※Docker、Kubernetes 和 Apache Mesos 對比中的一些誤區
TAG:Kubernetes |