從1.8版開始,Kubernetes Storage SIG停止接受樹內卷外掛程式,並建議所有儲存供應商實施樹外外掛程式。目前有兩種推薦的實現方式:容器儲存介面(CSI)和Flexvolume。 Flexvolume 介紹
lexvolume使使用者能夠編寫自己的驅動程式並在Kubernetes中添加對卷的支援。如果–enable-controller-attach-detach啟用Kubelet選項,則供應商驅動程式應安裝在每個Kubelet節點和主節點上的卷外掛程式路徑中。
Flexvolume是Kubernetes 1.8版本以後的GA特性。 先決條件
在外掛程式路徑中的所有節點上安裝供應商驅動程式,–enable-controller-attach-detach設定為true,
安裝外掛程式的路徑:\ 動態外掛程式發現
Flexvolume從v1.8開始支援動態檢測驅動程式的能力。
系統初始化時不需要存在驅動程式,或者需要重新啟動kubelet或控制器管理器,
則可以在系統運行時安裝,升級/降級和卸載驅動程式。有關更多資訊,請參閱設計文檔 自動外掛程式安裝/升級
安裝和升級Flexvolume驅動程式的一種可能方式是使用DaemonSet。見推薦驅動程式部署方法的詳細資料。 外掛程式詳細資料
該外掛程式希望為後端驅動程式實現以下調用。有些標註是可選的。
調用是從Kubelet和Controller管理器節點調用的。
只有當啟用了“–enable-controller-attach-detach”Kubelet選項時,
才會從Controller-manager調用調用。 驅動程式調用模型 init
初始化驅動程式。在Kubelet&Controller manager初始化期間調用。
成功時,該函數返回一個功能映射,顯示驅動程式是否支援每個Flexvolume功能。當前功能: attach - 指示驅動是否需要附加和分離操作的布爾欄位。
該欄位是必需的,但為了向後相容,預設值設定為true,即需要附加和分離。
有關功能圖格式,請參閱驅動程式輸出。
<driver executable> init
attach
在給定主機上附加給定規範指定的卷。成功時,返回裝置串連到節點的裝置路徑。
如果啟用了“–enable-controller-attach-detach”Kubelet選項,
則Nodename參數才是有效/相關的。來自Kubelet&Controllermanager。
此調出不會傳遞Flexvolume規範中指定的“secrets”。如果您的驅動程式需要secrets,
請不要執行此調出,而是使用“mount”調出並在該調出中執行attach和調用。
<driver executable> attach <json options> <node name>
Detach
從Kubelet節點分離卷。只有在啟用啟用了“–enable-controller-attach-detach”Kubelet選項時
Nodename參數才是有效/相關的。Kubelet & Controller manager進行調用
<driver executable> detach <mount device> <node name>
Wait for attach
等待卷串連到遠程節點上。成功後,返回裝置的路徑。從Kubelet & Controller manager進行調用,逾時時間為10毫秒(代碼),
<driver executable> waitforattach <mount device> <json options>
Volume is Attached
檢查節點上是否串連了卷。從Kubelet & Controller manager進行調用.
<driver executable> isattached <json options> <node name>
Mount device
掛載裝置將裝置掛載到全域路徑,然後各個容器可以動態綁定,只能從kubelet調用。
此調出不會傳遞Flexvolume規範中指定的“secrets”。如果您的驅動程式需要secrets,
請不要執行此調出,而是使用“mount”調出並在該調出中執行attach和調用。
<driver executable> mountdevice <mount dir> <mount device> <json options>
Unmount device
取消所有掛載,一旦所有綁定掛載已被卸載,就會調用它。只能從Kubelet中調用。
<driver executable> unmountdevice <mount device>
Mount
將卷掛載到掛載目錄。此調出預設為綁定掛載實現attach和mount-device調出的驅動程式。只能從Kubelet中調用。
<driver executable> mount <mount dir> <json options>
Unmount
卸載卷,此調出預設為綁定掛載實現附加和掛載裝置調出的驅動程式。只能從Kubelet中調用。
<driver executable> unmount <mount dir>
有關如何編寫簡單的flexvolume驅動程式的簡單樣本,請參閱lvm&nfs。 驅動輸出
Flexvolume希望驅動程式以下列格式返回操作狀態。
{ "status": "<Success/Failure/Not supported>", "message": "<Reason for success/failure>", "device": "<Path to the device attached. This field is valid only for attach & waitforattach call-outs>" "volumeName": "<Cluster wide unique name of the volume. Valid only for getvolumename call-out>" "attached": <True/False (Return true if volume is attached on the node. Valid only for isattached call-out)> "capabilities": <Only included as part of the Init response> { "attach": <True/False (Return true if the driver implements attach and detach)> }} 預設json選項
除了使用者在FlexVolumeSource的Options欄位中指定的標誌之外,還將以下標誌傳遞給可執行檔。注意:秘密只傳遞給“mount/umount”調出 Flexvolume的樣本
有關如何在pod中使用Flexvolume的快速樣本,請參見nginx.yaml&nginx-nfs.yaml。
https://github.com/sigma/cifs_k8s_plugin
https://github.com/kubernetes/kubernetes/blob/master/examples/volumes/flexvolume/lvm
https://github.com/kubernetes/kubernetes/blob/master/examples/volumes/flexvolume/nfs CSI 介紹
CSI提供了一個單一的介面,儲存供應商可以實現它們的儲存解決方案,以跨多個不同的容器編排器工作,並且卷外掛程式被設計為out-of-tree。這是一項巨大的努力,CSI的全面實施需要幾個季度的時間,並且需要立即為儲存供應商提供解決方案,以繼續添加卷外掛程式。
它使許多不同類型的儲存系統能夠:
- 在需要時自動建立儲存。
- 使儲存在任何計劃的地方都可用。
- 不再需要時自動刪除儲存。 建立csi的原因
Kubernetes卷外掛程式目前是“in-tree”,意味著它們與核心kubernetes二進位檔案進行連結,編譯,構建和發布。
為Kubernetes(卷外掛程式)添加對新儲存系統的支援需要將代碼檢入核心Kubernetes存放庫。
但是與Kubernetes發布流程對許多外掛程式開發人員來說是痛苦的。
現有的Flex Volume外掛程式試圖通過暴露外部卷外掛程式的基於exec的API來解決這個問題。
儘管它使第三方儲存供應商能夠在樹外編寫驅動程式,但為了部署第三方驅動程式檔案,
它需要訪問節點和主機的根檔案系統。
除了難以部署之外,Flex並沒有解決外掛程式依賴的痛苦:外掛程式往往有很多外部需求(例如,在掛載和檔案系統工具上)。
假定這些依賴關係在底層主機作業系統上可用,而這往往不是這種情況(並且安裝它們需要訪問節點機器的根檔案系統)。
CSI解決了所有這些問題,使儲存外掛程式能夠通過標準的Kubernetes基元進行樹外,容器化,部署,
並通過使用者所熟悉並喜愛的Kubernetes儲存原語(PersistentVolumeClaims,PersistentVolumes,StorageClasses)進行使用。 csi驅動
https://kubernetes-csi.github.io/docs/Drivers.html 用法 啟用csi
csi在1.9是alpha版本,要想使用它,設定以下參數:
API server binary: –feature-gates=CSIPersistentVolume=true –runtime-config=storage.k8s.io/v1alpha1=true
API server binary and kubelet binaries: –feature-gates=MountPropagation=true –allow-privileged=true 預配置volume
預先配置的驅動程式的工作方式與之前一樣,管理員將建立一個PersistentVolume規範,該規範將描述要使用的卷。PersistentVolume規範需要根據你的驅動程式進行設定,這裡的區別在於有一個叫做csi的新部分需要相應地設定。請參閱Kubernetes關於CSI卷的文檔(LINK TBD)。
以下是由CSI驅動程式管理的預配置卷的PersistentVolume規範樣本:
apiVersion: v1kind: PersistentVolumemetadata: name: manually-created-pvspec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain csi: driver: com.example.team/csi-driver volumeHandle: existingVolumeName readOnly: false
動態預配
為了設定系統進行動態配置,管理員需要設定StorageClass指向CSI驅動程式的外部配置器並指定驅動程式所需的任何參數。這是一個StorageClass的例子:
kind: StorageClassapiVersion: storage.k8s.io/v1metadata: name: fast-storageprovisioner: com.example.team/csi-driverparameters: type: pd-ssd
提供者:必須設定為CSI驅動程式的名稱
參數:必須包含特定於CSI驅動程式的任何參數。
然後使用者可以使用這個StorageClass 建立一個PersistentVolumeClaim,如下所示:
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: request-for-storagespec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: fast-storage
在k8s中使用
本節介紹如何部署csi驅動程式到k8s 1.9叢集
在Kubernetes 1.9中,有三個新的組件加上kubelet使CSI驅動為Kubernetes提供儲存。
新組件是邊車容器,負責與Kubernetes和CSI驅動溝通,監控events從而適時調用csi介面。 external-attacher
external-attacher是一個邊車容器,用於監視Kubernetes VolumeAttachment對象並觸發針對驅動程式端點的CSI ControllerPublish和ControllerUnpublish操作。在撰寫本文時,外部助理不支援領導者選舉,因此每個CSI車手只能運行一次。欲瞭解更多資訊,請閱讀附加和分離。
請注意,即使這稱為外部附件,它的功能是調用CSI API調用ControllerPublish和ControllerUnpublish。這些調用很可能發生在不是將要安裝卷的節點中。因此,許多CSI驅動程式不支援這些調用,而是在要安裝的節點上的kubelet所完成的CSI NodePublish和NodeUnpublish調用中執行attach / detach和mount / unmount 。 external-provisioner
external-provisioner是一個Sidecar容器,用於監視Kubernetes PersistentVolumeClaim對象並觸發針對驅動程式端點的CSI CreateVolume和DeleteVolume操作。有關更多資訊,請閱讀供應和刪除。 driver-registrar
driver-registrar是一個邊車容器,它用kubelet註冊CSI驅動程式,並將驅動程式自訂NodeId添加到Kubernetes Node API對象上的標籤。它通過與CSI驅動程式上的身份服務進行通訊並調用CSI GetNodeId操作來完成此操作。驅動程式註冊器必須具有通過環境變數設定的節點的Kubernetes名稱,KUBE_NODE_NAME如下所示:
- name: csi-driver-registrar imagePullPolicy: Always image: docker.io/k8scsi/driver-registrar args: - "--v=5" - "--csi-address=$(ADDRESS)" env: - name: ADDRESS value: /csi/csi.sock - name: KUBE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: socket-dir mountPath: /csi
pod配置
volumeMounts: - name: socket-dir mountPath: /csi - name: mountpoint-dir mountPath: /var/lib/kubelet/pods mountPropagation: "Bidirectional" volumes: - name: socket-dir hostPath: path: /var/lib/kubelet/plugins/csi-hostpath type: DirectoryOrCreate - name: mountpoint-dir hostPath: path: /var/lib/kubelet/pods type: Directory
rbac配置
kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: csi-hostpath-rolerules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["create", "delete", "get", "list", "watch", "update"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: ["storage.k8s.io"] resources: ["volumeattachments"] verbs: ["get", "list", "watch", "update"]
參考
https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/flexvolume-deployment.md
https://github.com/container-storage-interface/spec/blob/master/spec.md
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md
http://blog.kubernetes.io/2018/01/introducing-container-storage-interface.html
https://github.com/container-storage-interface
https://kubernetes-csi.github.io/docs/
歡迎加入QQ群:k8s開發與實踐(482956822)一起交流k8s技術