您好,登錄后才能下訂單哦!
前言:K8S是一個成熟的容器業(yè)務(wù)集群管理方案,但是目前來講,在存儲方面顯得過于復(fù)雜和繁瑣,更不要說中間穿插著資源訪問權(quán)限和認證的管理,盡管google在開源它之前有很多年的實戰(zhàn)經(jīng)驗,但是從目前官方的發(fā)布文檔來看,依然顯得學(xué)習(xí)成本略高,我們來看看這個學(xué)習(xí)流程:
1,最初,學(xué)習(xí)k8s發(fā)現(xiàn)它羅列了一系列存儲方案,無非就是對一系列本地和云存儲的廣泛支持:
看到這么多的存儲卷類型的確很唬人,但是沒有辦法,在目前存儲界沒有達到統(tǒng)一(也不可能統(tǒng)一)之前,為了保持自己的強大的生態(tài)兼容性,K8S作出了無奈之舉。
2,好在我們不需要學(xué)習(xí)每一種存儲類型,只要要針對需要的存儲卷類型進行了解和學(xué)習(xí),接著,為了讓Pod和存儲資源管理解耦,K8S又引入了PV和PVC的概念,于是集群管理員和研發(fā)人員各司其職,但是帶來了額外的PV和PVC的創(chuàng)建,刪除以及存儲卷的綁定和回收以及讀寫控制等資源管理工作。
3,當集群規(guī)模增長后,發(fā)現(xiàn)PV和PVC的管理開銷驚人的時候,K8S又引入StorageClass的動態(tài)卷以及基于storageClass 的CSI的概念,這是目前K8S存儲靈活分配的終極方案。
4,就在我們還沒有完全理解StorageClass和CSI的時候,我們在官網(wǎng)又看到相關(guān)的Clone和Snapshot已經(jīng)出來了。
?????? 說明一個問題,業(yè)務(wù)需求場景不斷升級,業(yè)務(wù)需求量不斷變大,解決方案也不斷更新和變更,僅僅一個存儲就前后涉及諸多概念,實在讓人有點無所適從,弱水三千,取一瓢飲,今天這個實驗是針對NFS的共享存儲展開的。
?????? 為什么圍繞NFS展開實驗?zāi)??因為從企業(yè)來講,NFS共享在企業(yè)私有云內(nèi)部非常容易取得,并且成本較低,一臺普通的四盤位的企業(yè)級NAS服務(wù)器出廠即攜帶穩(wěn)定可靠的NFS服務(wù),無需自己部署,和企業(yè)的文件共享服務(wù)器集成,無需另外的硬件和部署成本。
首先,我們驗證NAS服務(wù)器的NFS服務(wù)是否就位:
1,啟動NFS客戶端:
掛載前,請確保系統(tǒng)中已經(jīng)安裝了nfs-utils或nfs-common,安裝方法如下:
CentOS:
yum?install?nfs-utils?-y
注意:這一步是必須的,道理很簡單,即便是K8S也沒有什么神通,底層依然是通過nfs驅(qū)動去掛載文件系統(tǒng),如果連nfs套件都不安裝,哪怕K8S所有配置都正確無誤,在創(chuàng)建接口pod的時候,會提示報錯說NFS服務(wù)路徑無法連接,為了體驗這個錯誤,建議先不安裝,假設(shè)你的nfs服務(wù)正常,后面再安裝,就可以看到錯誤消失。
Ubuntu 或 Debian:
apt-get?install?nfs-common
創(chuàng)建掛載路徑:
mkdir??/nfs
確認遠端NAS服務(wù)器上面存在的NFS服務(wù)和共享路徑:
掛載NFS共享路徑:
mount?-t?nfs??NAS服務(wù)器的IP:/NAS-NFS
我們可以進入掛載路徑嘗試創(chuàng)建文件夾,看是否掛載成功并且讀寫正常;
容易出問題的是,掛載成功但是無法創(chuàng)建文件夾,提示文件系統(tǒng)只讀,但是ls命令顯示777,這是因為NAS服務(wù)器的NFS服務(wù)權(quán)限沒有開放匿名訪問的讀寫權(quán)限:
不同的NAS設(shè)備可能配置不太一樣,請根據(jù)自己的NFS服務(wù)器的配置開啟讀寫。
以上全部成功后進一步測試NFS共享存儲在PV,PVC中是否工作正常:
2,創(chuàng)建測試的靜態(tài)PV和PVC
pv.yml
apiVersion:?v1 kind:?PersistentVolume metadata: ??name:?mypv1 spec: ??capacity: ????storage:?4Gi ??accessModes: ????-?ReadWriteOnce ??persistentVolumeReclaimPolicy:?Recycle ??nfs: ????path:?/NAS-NFS ????server:?[NAS服務(wù)器IP或域名]
pvc.yml
kind:?PersistentVolumeClaim apiVersion:?v1 metadata: ??name:?mypvc1 spec: ??accessModes: ????-?ReadWriteOnce ??resources: ????requests: ??????storage:?100Mi
開始創(chuàng)建資源對象(為了簡化實驗,所有資源對象都是默認的命名空間default展開):
其實動態(tài)存儲的命名空間是任何一個都無所謂,因為動態(tài)創(chuàng)建的PV是集群級別的,可以被任何一個命名空間的pvc請求并綁定。
并且dashboard里面顯示,綁定成功:
以上實驗充分證明nfs系統(tǒng)工作正常,刪除以上測試的內(nèi)容,進行下一步。
注意:
如果不刪除PVC來解除資源的占用,是無法直接刪除PV并釋放資源,違反K8S的持久化原則:
具體操作表現(xiàn)在三個方面:
1,kubectl delete pv 命令一直停留在執(zhí)行狀態(tài)不顯示結(jié)果;
2,Dashboard資源對象一直正常顯示存在,無視刪除操作;
3,命令行強制退出刪除命令,但是并不代表撤銷刪除操作,而是掛起,一直等待PVC手工清除,系統(tǒng)隨即立即釋放PV.
想要動態(tài)生成PV,需要運行一個NFS-Provisioner服務(wù),將已配置好的NFS系統(tǒng)相關(guān)參數(shù)錄入,向用戶提供創(chuàng)建PV的服務(wù)。
官方推薦使用Deployment運行一個副本集來實現(xiàn),當然也可以使用Daemonset等其他方式,這些都在官方文檔中提供了。
編寫rbac.yaml文件如下:
apiVersion:?v1 kind:?ServiceAccount metadata: ??name:?nfs-provisioner --- kind:?ClusterRole apiVersion:?rbac.authorization.k8s.io/v1 metadata: ??name:?nfs-provisioner-runner rules: ??-?apiGroups:?[""] ????resources:?["persistentvolumes"] ????verbs:?["get",?"list",?"watch",?"create",?"delete"] ??-?apiGroups:?[""] ????resources:?["persistentvolumeclaims"] ????verbs:?["get",?"list",?"watch",?"update"] ??-?apiGroups:?["storage.k8s.io"] ????resources:?["storageclasses"] ????verbs:?["get",?"list",?"watch"] ??-?apiGroups:?[""] ????resources:?["events"] ????verbs:?["create",?"update",?"patch"] --- kind:?ClusterRoleBinding apiVersion:?rbac.authorization.k8s.io/v1 metadata: ??name:?run-nfs-provisioner subjects: ??-?kind:?ServiceAccount ????name:?nfs-provisioner ????namespace:?default roleRef: ??kind:?ClusterRole ??name:?nfs-provisioner-runner ??apiGroup:?rbac.authorization.k8s.io --- kind:?Role apiVersion:?rbac.authorization.k8s.io/v1 metadata: ??name:?leader-locking-nfs-provisioner rules: ??-?apiGroups:?[""] ????resources:?["endpoints"] ????verbs:?["get",?"list",?"watch",?"create",?"update",?"patch"] --- kind:?RoleBinding apiVersion:?rbac.authorization.k8s.io/v1 metadata: ??name:?leader-locking-nfs-provisioner subjects: ??-?kind:?ServiceAccount ????name:?nfs-provisioner ????#?replace?with?namespace?where?provisioner?is?deployed ????namespace:?default roleRef: ??kind:?Role ??name:?leader-locking-nfs-provisioner ??apiGroup:?rbac.authorization.k8s.io
kind:?Deployment apiVersion:?extensions/v1beta1 metadata: ??name:?nfs-provisioner spec: ??replicas:?1 ??strategy: ????type:?Recreate ??template: ????metadata: ??????labels: ????????app:?nfs-provisioner ????spec: ??????serviceAccount:?nfs-provisioner ??????containers: ????????-?name:?nfs-provisioner ??????????image:?registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner ???????????#官方鏡像:quay.io/external_storage/nfs-client-provisioner:latest?無法下載,使用上面阿里云鏡像代替 ??????????volumeMounts: ????????????-?name:?nfs-client-root ??????????????mountPath:?/persistentvolumes ??????????env: ????????????-?name:?PROVISIONER_NAME ??????????????value:?example.com/nfs ????????????-?name:?NFS_SERVER ??????????????value:?[NAS服務(wù)器的IP地址] ????????????-?name:?NFS_PATH ??????????????value:?/NAS-NFS???#NFS系統(tǒng)的掛載路徑 ??????volumes: ????????-?name:?nfs-client-root ??????????nfs: ????????????server:?[NAS服務(wù)器的IP地址] ????????????path:?/NAS-NFS???#NFS系統(tǒng)的掛載路徑
將以上文件通過kubectl命令創(chuàng)建完畢后,我們查看K8S部署結(jié)果:
我們得到一個副本集和這個副本集啟動一個Pod,來充當nfs-client-provisioner角色,這個角色用來響應(yīng)各種存儲資源請求,但是并不能直接使用,需要用StorageClass去觸發(fā)。
編寫并創(chuàng)建storageclass.yaml如下:
kind:?StorageClass apiVersion:?storage.k8s.io/v1 metadata: ??name:?nfs provisioner:?example.com/nfs
接下來要創(chuàng)建測試的PVC,以檢測StorageClass能否正常工作:
編寫并創(chuàng)建test-claim.yaml如下,注意storageClassName應(yīng)確保與上面創(chuàng)建的StorageClass名稱一致。
kind:?PersistentVolumeClaim apiVersion:?v1 metadata: ??name:?test-claim1 spec: ??accessModes: ????-?ReadWriteMany ??resources: ????requests: ??????storage:?1Mi ??storageClassName:?nfs???#這里和創(chuàng)建的SC名稱保持一致
創(chuàng)建后,用kubectl get pvc查看,觀察新創(chuàng)建的PVC能夠自動綁定PV。
創(chuàng)建一個測試的Pod使用這個PVC,編寫test-pod.yaml文件如下:
kind:?Pod apiVersion:?v1 metadata: ??name:?test-pod spec: ??containers: ??-?name:?test-pod ????image:?busybox ????command: ??????-?"/bin/sh" ????args: ??????-?"-c" ??????-?"touch?/mnt/SUCCESS?&&?exit?0?||?exit?1" ????volumeMounts: ??????-?name:?nfs-pvc ????????mountPath:?"/mnt" ??restartPolicy:?"Never" ??volumes: ????-?name:?nfs-pvc ??????persistentVolumeClaim: ????????claimName:?test-claim1
查看Pod狀態(tài)是否變?yōu)镃ompleted。如果是,則應(yīng)該能在NFS系統(tǒng)的共享路徑中看到一個SUCCESS文件。
這樣,StorageClass動態(tài)創(chuàng)建PV的功能就成功實現(xiàn)了。
普通的pod是在編排文件里面通過聲明預(yù)先手工創(chuàng)建PVC去請求storageclass來自動獲取動態(tài)卷,實際上這種自動由于PVC的存在也屬于半自動,還是不夠靈活,所以,官方推薦使用statefulset;
編寫statefulset.yaml文件如下:
apiVersion:?apps/v1beta1 kind:?StatefulSet metadata: ??name:?web spec: ??serviceName:?"nginx1" ??replicas:?2 ??volumeClaimTemplates: ??-?metadata: ??????name:?test ??????annotations: ????????volume.beta.kubernetes.io/storage-class:?"nfs"???#?nfs和前面定義的storageclass的名稱保持一致 ????spec: ??????accessModes:?[?"ReadWriteOnce"?] ??????resources: ????????requests: ??????????storage:?1Gi ??template: ????metadata: ??????labels: ????????app:?nginx1 ????spec: ??????serviceAccount:?nfs-provisioner?????#和前面創(chuàng)建的資源訪問角色保持一致 ??????containers: ??????-?name:?nginx1 ????????image:?nginx ????????imagePullPolicy:?IfNotPresent ????????volumeMounts: ????????-?mountPath:?"/my_dir"??#此掛載路徑可以任意指定 ??????????name:?test
查看執(zhí)行結(jié)果:
查看存儲資源創(chuàng)建結(jié)果:
打開nfs的文件系統(tǒng)目錄,發(fā)現(xiàn)和PV對應(yīng)的資源文件夾自動生成:
文件夾的自動命名規(guī)則為pod的各種資源名稱的集合。
進一步的,可以用kubectl exec -it 進入其中一個Pod中驗證,可以看到K8S也不是神仙,也是通過mount的方式將NFS路徑下生成一個臨時路徑掛載到容器內(nèi)的指定的編排路徑:
至此,實驗基本完成。
github有官方上傳的現(xiàn)成源碼,和上面基本一致,此教程只是將過程詳細證明出來:
https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。