Kubernetes手記(10)- POD 存儲卷

      網(wǎng)友投稿 891 2025-04-04

      十 POD 存儲卷

      大部分有狀態(tài)的應(yīng)用都有持久存儲,在 Docker 上我們將容器所需要的存儲卷放在宿主機上,但是 k8s 上不行,因為 POD 會被在不同的 node 節(jié)點上創(chuàng)建刪除,所以 k8s 需要一套另外的存儲卷機制,它能脫離節(jié)點為整個集群提供持久存儲。

      k8s 提供了多種不同的存儲卷,k8s 中存儲卷屬于 POD 而不是容器,POD 可以掛載,POD 為什么能有存儲卷呢?這是因為在所有節(jié)點上運行了一個 Pause 的鏡像,它是 POD 的基礎(chǔ)架構(gòu)容器,它擁有存儲卷,同一個 POD 內(nèi)的所有容器是一個網(wǎng)絡(luò)名稱空間的。

      10.1 卷的類型

      查看 POD 支持的存儲類型:kubectl explain pods.spec.volumes

      HostPath:在節(jié)點本地新建一個路徑,與容器建立關(guān)聯(lián)關(guān)系,但節(jié)點掛了的數(shù)據(jù)也不存在了,所以也不具有持久性,容器被調(diào)度到別的 node 時候不能跨節(jié)點使用HostPath。

      Local:直接使用節(jié)點的設(shè)備、也支持一個目錄類似于 HostPath。

      EmptyDir:只在節(jié)點本地使用,一旦 POD 刪除,存儲卷也會刪除,它不具有持久性,當臨時目錄或者緩存。

      網(wǎng)絡(luò)存儲:iSCSI、NFS、Cifs、glusterfs、cephfs、EBS(AWS)、Disk(Azone)

      10.2 容器掛載選項

      在 K8S 中卷是屬于 POD 的,而不是容器,所以卷的定義在 POD 中,一個 POD 中可以定義多個卷。

      在 POD 中掛載使用,kubectl explain pods.spec.containers.volumeMounts

      apiVersion: v1 kind: Pod metadata: name: myapp namespace: default labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts <[]Object> # 卷掛載對象 mountPath # 掛載路徑 mountPropagation # 確定掛載如何從主機傳播到容器 name # 掛載哪個卷 readOnly # 是否只讀掛載 subPath # 掛載在子路徑下 subPathExpr # 與 subPath 類似,掛載在子路徑下,不同的是可以使用 $(VAR_NAME) 表示容器擴展這個變量

      10.3 節(jié)點存儲

      10.3.1 hostpath存儲卷

      在宿主機的路徑掛載到 POD 上,POD 刪除后,卷數(shù)據(jù)是不會隨之刪除的,但如果 node 節(jié)點掛掉,那么數(shù)據(jù)有可能丟失,如果 POD 被調(diào)度到其他的節(jié)點,那么原來卷的數(shù)據(jù)就訪問不到了。

      https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

      定義參數(shù),kubectl explain pods.spec.volumes.hostPath

      path # 主機上目錄的路徑。 如果路徑是符號鏈接,則會跟隨真實路徑的鏈接。 type # 見下表

      示例

      apiVersion: v1 kind: Pod metadata: name: myapp namespace: default labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: # 容器掛載哪些卷 - name: webstore # 掛載哪個卷 mountPath: /usr/share/nginx/html # 掛載到容器內(nèi)哪個目錄 readOnly: false # 是否只讀 volumes: # 存儲卷屬于POD的(不屬于容器) - name: webstore # 存儲卷對象名字 hostPath: # hostpath 類型的存儲卷對象 path: /data/myapp # 處于宿主機的目錄 type: DirectoryOrCreate # 不存在則創(chuàng)建

      10.3.2 gitRepo卷

      將 git 倉庫的內(nèi)容當作存儲使用,在 POD 創(chuàng)建時候連接到倉庫,并拉取倉庫,并將它掛載到容器內(nèi)當作一個存儲卷。

      它其實是建立在 emptyDir 的基礎(chǔ)上,但是對卷的操作不會同步到 gitrepo 上。

      注意:需要在各運行pod的node節(jié)點上安裝git工具,用于git的拉取

      apiVersion: v1 kind: Pod metadata: labels: run: gitrepo name: gitrepo spec: containers: - image: nginx:latest name: gitrepo volumeMounts: - name: gitrepo mountPath: /usr/share/nginx/html volumes: - name: gitrepo gitRepo: repository: "https://gitee.com/rocket049/mysync.git" revision: "master"

      10.3.3 emptyDir緩存卷

      它使用宿主機一個目錄作為掛載點,隨著 POD 生命周期的結(jié)束,其中的數(shù)據(jù)也會丟失,但是它有一個非常大的優(yōu)點就是可以使用內(nèi)存當作存儲空間掛載使用。

      它可以用在 POD 中兩個容器中有一些數(shù)據(jù)需要共享時候選用。

      定義 emptyDir 參數(shù),kubectl explain pods.spec.volumes.emptyDir

      medium # 使用 "" 表示使用 Disk 來存儲,使用 Memory 表示使用內(nèi)存 sizeLimit # 限制存儲空間的大小

      使用示例

      apiVersion: v1 kind: Pod metadata: name: pod-volume-demo namespace: default labels: app: myapp tier: frontend spec: volumes: - name: html emptyDir: {} # 使用磁盤,且沒有容量限制 containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /usr/share/nginx/html/ ports: - name: http containerPort: 80 - name: https containerPort: 443 - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: - "/bin/sh" - "-c" - "while true; do date >> /data/index.html; sleep 10; done"

      使用示例

      apiVersion: v1 kind: Pod metadata: name: pod-volume-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /usr/share/nginx/html/ ports: - name: http containerPort: 80 - name: https containerPort: 443 - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: - "/bin/sh" - "-c" - "while true; do date >> /data/index.html; sleep 10; done" volumes: - name: html emptyDir: medium: "" sizeLimit: 1536Mi

      10.4 網(wǎng)絡(luò)存儲

      網(wǎng)絡(luò)存儲,就是脫離了節(jié)點生命周期的存儲設(shè)備,即使 pod 被調(diào)度到別的 node 節(jié)點上,仍然可以掛載使用其中的數(shù)據(jù)。

      10.4.1 nfs

      nfs 服務(wù)器是存在于集群之外的服務(wù)器,它不受 node 節(jié)點的影響,因而在 node 節(jié)點宕機后仍然能夠提供持久存儲給其他 POD。

      在 k8s 的 node 找一個主機,安裝配置 nfs 服務(wù)器并啟動

      $ yum install nfs-utils # 安裝 nfs 服務(wù) $ mkdir -p /data/volumes # 創(chuàng)建 volume 卷目錄 echo '/data/volumes 172.16.100.0/16(rw,no_root_squash)' >> /etc/exports # 配置 nfs 服務(wù)器 $ systemctl start nfs # 啟動 nfs 服務(wù)器 $ ss -tnl # 確認監(jiān)聽端口,nfs 監(jiān)聽 TCP 2049 端口

      在 k8s 集群的 node 節(jié)點安裝 nfs 驅(qū)動,測試掛載是否正常

      $ yum install nfs-utils $ mount -t nfs 172.16.100.104:/data/volumes /mnt

      定義 nfs 參數(shù),kubectl explain pods.spec.volumes.nfs

      path # nfs 服務(wù)器的路徑 readOnly # 是否只讀 server # nfs 服務(wù)器地址

      使用示例

      apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs-demo namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html nfs: path: /data/volumes server: 172.16.100.104

      注意??:各個node節(jié)點也需要安裝yum install nfs-utils,不讓在掛載的時候會出現(xiàn)異常。

      10.5 分布式存儲

      分布式存儲能提供脫離節(jié)點生命周期的存儲,又比網(wǎng)絡(luò)存儲更加健壯,它是分布式的,有很強的高可用性,但是分布式存儲配置復雜,在由 NFS 提供的網(wǎng)絡(luò)儲存中,用戶需要知道分配給 POD 的 NFS 存儲的地址才能使用,而在由分布式提供的存儲能力的存儲上,用戶需要充分了解該分布式存儲的配置參數(shù),才能夠使用這個分布式存儲。

      由此 K8S 提供了 PV、PVC 兩種機制,讓普通用戶無需關(guān)心底層存儲參數(shù)的配置,只需要說明需要使用多大的持久存儲,就可以了。

      一般 PV 與 PVC 是一對綁定的,PV屬于全局,PVC 屬于某個名稱空間,當一個 PV 被一個 PVC 綁定,別的名稱空間 PVC 就不可以再綁定了。請求綁定某個 PV 就是由 PVC 來完成的,被 PVC 綁定的 PV 稱作 PV 的綁定狀態(tài)。

      PVC 綁定了一個 PV,那么 PVC 所處名稱空間定義的 POD 就可以使用 persistentVolumeClaim 類型的 volumes 了,然后容器就可以通過 volumeMounts 掛載 PVC 類型的卷了。

      persistentVolumeClaim 卷是否允許多路讀寫,這取決于 PV 定義時候的讀寫特性:單路讀寫、多路讀寫、多路只讀。

      如果某個 POD 不在需要了,我們把它刪除了、同時也刪除了 PVC、那么此時 PV 還可以有自己的回收策略: delete刪除PV、Retain什么都不做。

      10.5.1 PersistentVolume

      由管理員添加的的一個存儲的描述,是一個集群級別的全局資源,包含存儲的類型,存儲的大小和訪問模式等。它的生命周期獨立于Pod,例如當使用它的 Pod 銷毀時對 PV 沒有影響。

      見:kubectl explain PersistentVolume.spec

      在 nfs 上定義存儲,/etc/exports,并且導出 nfs 定義

      /data/volumes/v1 172.16.100.0/16(rw,no_root_squash) /data/volumes/v2 172.16.100.0/16(rw,no_root_squash) /data/volumes/v3 172.16.100.0/16(rw,no_root_squash) /data/volumes/v4 172.16.100.0/16(rw,no_root_squash) /data/volumes/v5 172.16.100.0/16(rw,no_root_squash)

      exportfs -arv

      將 nfs 在 k8s 中定義為 PersistentVolume,詳見:kubectl explain PersistentVolume.spec.nfs

      apiVersion: v1 kind: PersistentVolume metadata: name: pv-001 labels: name: pv001 spec: accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 1Gi nfs: path: /data/volumes/v1 server: 172.16.100.104 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-002 labels: name: pv003 spec: accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 2Gi nfs: path: /data/volumes/v2 server: 172.16.100.104 --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-003 labels: name: pv003 spec: accessModes: - ReadWriteMany - ReadWriteOnce capacity: storage: 3Gi nfs: path: /data/volumes/v3 server: 172.16.100.104

      kubectl get persistentvolume NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-001 1Gi RWO,RWX Retain Available 3m38s pv-002 2Gi RWO,RWX Retain Available 3m38s pv-003 3Gi RWO,RWX Retain Available 3m38s

      10.5.2. PersistentVolumeClaim

      是 Namespace 級別的資源,描述對 PV 的一個請求。請求信息包含存儲大小,訪問模式等。

      定義 PVC,kubectl explain PersistentVolumeClaim.spec

      accessModes <[]string> # 設(shè)置訪問模式 ReadWriteOnce # 單個節(jié)點以讀寫方式掛載 ReadOnlyMany # - 多節(jié)點以只讀方式掛載 ReadWriteMany # - 多節(jié)點以讀寫方式掛載 dataSource # 如果配置程序可以支持 Volume Snapshot 數(shù)據(jù)源,它將創(chuàng)建一個新卷,并且數(shù)據(jù)將同時還原到該卷。 resources # 資源表示 PersistentVolume 應(yīng)具有的最小資源 selector # 選擇哪個 PersistentVolume storageClassName # 存儲類名稱 volumeMode # 定義聲明所需的 PersistentVolume 類型才能被選中 volumeName # 后端 PersistentVolume ,就是精確選擇 PersistentVolume ,而不是使用 selector 來選定

      在 volumes 中使用 PVC,kubectl explain pods.spec.volumes.persistentVolumeClaim

      persistentVolumeClaim claimName # 在當前名稱空間已經(jīng)創(chuàng)建號的 PVC 名稱 readOnly # 是否只讀

      定義 PersistentVolumeClaim,詳見:kubectl explain PersistentVolumeClaim.spec

      apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc namespace: default spec: accessModes: - ReadWriteMany # 訪問模式 resources: # 資源條件 requests: # 挑選 PV 時候必須滿足的條件,不滿足則一直等待 storage: 2Gi # 存儲大小

      在 pod 清單中定義 persistentVolumeClaim 類型的 volumes ,并在容器中掛載 volumeMounts。

      apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs-demo namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html persistentVolumeClaim: claimName: my-pvc # 使用的 PVC 的名稱

      10.5.3 StorageClass

      PVC 申請 PV 的時候,未必有符合條件的 PV,k8s 為我們準備了 StorageClass 可以在 PVC 申請 PV 的時候通過 StorageClass 動態(tài)生成 PV。

      StorageClass 可以動態(tài)的到 CephFS 、NFS 等存儲(或者云端存儲)產(chǎn)生一個 PV,要求存儲設(shè)備必須支持 RESTfull 風格的接口。

      10.6 StorageClass Ceph RBD

      10.6.1 配置 Ceph 儲存池

      創(chuàng)建 ceph 存儲池

      yum install -y ceph-common # 在所有節(jié)點安裝 ceph-common

      ceph osd pool create kube 4096 # 創(chuàng)建 pool ceph osd pool ls # 查看 pool ceph auth get-or-create client.kube mon 'allow r' osd 'allow rwx pool=kube' -o /etc/ceph/ceph.client.kube.keyring ceph auth list # 授權(quán) client.kube 用戶訪問 kube 這個 pool scp /etc/ceph/ceph.client.kube.keyring node1:/etc/ceph/ # 將用戶 keyring 文件拷貝到各個 ceph 節(jié)點 scp /etc/ceph/ceph.client.kube.keyring node1:/etc/ceph/

      10.6.2 安裝 rbd-provisioner

      1.12 版本后 kube-controller-manager 不再內(nèi)置 rbd 命令,所以 StorageClass 的 provisioner 而是通過外部的插件來實現(xiàn)

      https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd/deploy/rbac # rbd-provisioner

      $ git clone https://github.com/kubernetes-incubator/external-storage.git # 下載 rbd-provisioner $ cat >>external-storage/ceph/rbd/deploy/rbac/clusterrole.yaml<

      10.6.3 使用 StorageClass

      創(chuàng)建 CephX 驗證 secret

      https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd/examples # rbd-provisioner 使用 ceph rbd 的示例

      --- apiVersion: v1 kind: Secret metadata: name: ceph-admin-secret namespace: kube-system type: "kubernetes.io/rbd" data: # ceph auth get-key client.admin | base64 # 從這個命令中取得 keyring 認證的 base64 密鑰串復制到下面 key: QVFER3U5TmM1NXQ4SlJBQXhHMGltdXZlNFZkUXRvN2tTZ1BENGc9PQ== --- apiVersion: v1 kind: Secret metadata: name: ceph-secret namespace: kube-system type: "kubernetes.io/rbd" data: # ceph auth get-key client.kube | base64 # 從這個命令中取得 keyring 認證的 base64 密鑰串復制到下面 key: QVFCcUM5VmNWVDdQRlJBQWR1NUxFNzVKeThiazdUWVhOa3N2UWc9PQ==

      創(chuàng)建 StorageClass 指向 rbd-provisioner,

      --- kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: ceph-rbd provisioner: ceph.com/rbd reclaimPolicy: Retain parameters: monitors: 172.16.100.9:6789 pool: kube adminId: admin adminSecretName: ceph-admin-secret adminSecretNamespace: kube-system userId: kube userSecretName: ceph-secret userSecretNamespace: kube-system fsType: ext4 imageFormat: "2" imageFeatures: "layering"

      創(chuàng)建 PersistentVolumeClaim

      --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: ceph-rbd-pvc data-kong-postgresql-0 spec: storageClassName: ceph-rbd accessModes: - ReadWriteOnce resources: requests: storage: 1Gi

      在 POD 中使用 PVC,最后在容器中掛載 PVC。

      --- apiVersion: v1 kind: Pod metadata: name: ceph-sc-pvc-demo namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: pvc-volume mountPath: /usr/share/nginx/html/ volumes: - name: pvc-volume persistentVolumeClaim: claimName: ceph-rbd-pvc

      其他

      自己將手記發(fā)在:https://github.com/redhatxl/awesome-kubernetes-notes

      Kubernetes手記(10)- POD 存儲卷

      歡迎一鍵三連

      Kubernetes

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:如何團隊共享文件(如何資源共享,團隊共建)
      下一篇:Excel數(shù)列中存在英文字母時不能與全是數(shù)字的數(shù)列進行排序(excel中不可以按文本數(shù)字進行排序)
      相關(guān)文章
      亚洲精品福利视频| 久久精品亚洲日本波多野结衣| 国产精品亚洲精品爽爽| 亚洲香蕉久久一区二区三区四区| 99久久精品国产亚洲| 亚洲免费无码在线| 亚洲乱码国产一区网址| 亚洲狠狠成人综合网| 亚洲精品福利你懂| 亚洲无mate20pro麻豆| 亚洲sss综合天堂久久久| 国产成人亚洲精品| 亚洲一本到无码av中文字幕| 亚洲综合小说另类图片动图| 亚洲自偷自偷在线成人网站传媒| 在线观看亚洲AV日韩A∨| 亚洲制服中文字幕第一区| 国产亚洲精品久久久久秋霞| 亚洲第一区二区快射影院| 亚洲精品一二三区| 亚洲国产精品免费在线观看| 亚洲一区二区三区91| 亚洲老熟女五十路老熟女bbw| 精品国产日韩亚洲一区| 国产AⅤ无码专区亚洲AV| 久久精品国产亚洲Aⅴ香蕉| 亚洲色大成网站www永久男同| 亚洲依依成人亚洲社区| 亚洲欧洲专线一区| 九月婷婷亚洲综合在线| 女bbbbxxxx另类亚洲| 奇米影视亚洲春色| 亚洲中文字幕在线第六区| 亚洲?V无码成人精品区日韩| 久久综合亚洲色HEZYO国产| 国产成人毛片亚洲精品| 亚洲AV无码乱码在线观看裸奔| 久久亚洲欧洲国产综合| 亚洲免费视频网站| 亚洲中文字幕久久精品无码喷水 | 亚洲JIZZJIZZ妇女|