k8s 卷存儲


應用場景

pod 中的容器的數據隨着pod 的重啟,刪除就會消失,有的應用場景需要持久化數據,這時就需要卷掛載。

Tips:

volumes  是 pod 的一個組成部分, 因此像容器一樣在 pod 的規范中就定義了。 它們不是獨立的 Kubernetes 資源對象, 也不能單獨創建或刪除。 pod 中的所有容器都可以使用卷, 但必須先將它掛載在每個需要訪問它的容器中。 在每個容器中, 都可以在其文件系統的任意位置掛載卷。

常見的類型

empty   一  用於存儲臨時數據的簡單空目錄。
 
hostPath — 用於將目錄從工作節點的文件系統掛載到pod中
 
gitRepo  一 通過檢出Git倉庫的內容來初始化的卷。
 
nfs  —  掛載到pod中的NFS共享卷。
 
configMap secret downwardAPI 一 用於將 Kubemetes 部分資源和集群信息公開給 pod 的特殊類型的卷

empty 配置

emptyDir類型的Volume在Pod分配到Node上時被創建,Kubernetes會在Node上自動分配一個目錄,因此無需指定宿主機Node上對應的目錄文件。 這個目錄的初始內容為空,當Pod從Node上移除時,emptyDir中的數據會被永久刪除。emptyDir Volume主要用於某些應用程序無需永久保存的臨時目錄,多個容器的共享目錄等。

在Pod中的定義

apiVersion: vl 
kind: Pod 
metadata: 
    name: fortune 
spec: 
  containers: 
- image: luksa/fortune                       #第一個容器名為 html-asdf
  name: html-asdf 
  volumeMounts: 
  - name: html                               #容器掛載的本地卷為 html
    mountPath: /var/htdocs                   #掛載到容器的此目錄
    
- image: nginx:alpine 
  name: web-server                           #第二個容器稱為 web-server
  volumeMounts : 
  - name: html                               #容器掛載的本地卷為 html
    mountPath: /usr/share/nginx/html         #設為只讀 
    readOnly: true 
  ports: 
  - containerPort: 80 
    protocol: TCP 

volumes 
- name: html                                 #命名為html
  emptyDir: {}                               #卷的類型為emptyDir
View Code
指定用於 EMPTYDIR 的介質
作為卷來使用的 emptyDir ,是在承載 pod 工作節點的實際磁盤上創建的,此其性能取決於節點的磁盤類型。 但我們可以通知 Kubemete tmfs 文件系統存在內存而非硬盤創建 emptyDir 。因 此,將emptyDir medium 設置為  Memory
volumes: 
- name: html
  emptyDir
    medium: Memory
View Code

使用 Git 倉庫作為存儲卷

gitRepo 卷基本上也是 emptyDir 卷,它通過克隆 Git 倉庫並在 pod啟動時(但在創建容器之前 檢出特定版本來填充數據)。gitRepo 容器就像 emptyDir 卷一樣, 基本上是一個專用目錄, 專門用於包含卷的容器並單獨使用。
 
當 pod 被刪除時, 卷及其內容被刪除。 然而, 其他類型的卷並不創建新目錄, 而是將現有的外部目錄掛載到 pod 的容器文件系統中。 該卷的內容可以保存多個 pod 實例化

 

Notice:

在創 gitRepo 卷后,它並不能和對應 repo 保持同步,當向Git 倉庫推送新增的提交時,卷中的文件將不會被更新。然而,如果所用 pod 是由 ReplicationController 管理的,刪除這個 pod 將觸發新建一個新的 pod ,而這個新 pod的卷中將包含最新的提交
apiVersion: vl 
kind: Pod 
metadata: 
  name: gitrepo-vol-pod
spec: 
  containers: 
  - image: nginx:alpine 
    name: web-server 
    volumeMounts : 
    - name : html
      mountPath: /usr/share/nginx/html 
      readOnly: true 
    ports: 
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html                                 #容器掛載的本地卷為 html
    gitRepo:
    repository: https://github.com/kzf/asdf-website-example.git
    revision: master 
    directory: . 
View Code

Tips: 

為了實現pod  gitrepo 目錄與git 倉庫實時同步可以通過 sidecar 容器

hostPath卷

hostPath 卷是一種持久性類型的存儲。因為gitRepo 和 emptyDir 卷的內容都會在 pod 被刪除時被刪除, 而 hostPath 卷的內容則不會被刪除。 如果刪除了一個 pod, 並且下一個 pod 使用了指向主機上相同路徑的 hostPath 卷, 則新 pod 將會發現上一個 pod 留下的數據, 但前提是必須將其調度到與第一個 pod 相同的節點上。

應用場景

大多數情況下都使用這種類型的卷來訪問節點的日志文件、 kubeconfig (Kubemetes 配置文件)或CA 證書,有時會配合DaemonSet 使用。
正常情況沒有一個pod 使用 hostPath 卷來存儲自己的數據, 都是使用這種卷來訪問節點的數據。 

使用持久化存儲

當運行在一個 pod 中的應用程序需要將數據保存到磁盤上, 並且即使該 pod 重新調度到另 一個節點時也要求具有相同的數據可用。由於這些數據需要可以從任何集群節點訪問, 因此必須將其存
儲在某種類型的網絡存儲 (NAS) 中。

使用雲廠商的存儲

如果你的 Kubemetes 集群運行在 Google Kubemetes 引擎上所以需要創建 GCE persistent disk。當在其他地方運行 Kubemetes 集群時,應該根據不同的基礎設施使用其他類型的卷。
例如,如果你的 Kubemetes 集群運行在 Amazon 的 AWS EC2 上,就可以使用 awsElasticBlockStore卷給你的 pod 提供持久化存儲。如果集群在 Microsoft Azure 上運行,則可以使用 azureFile 或者 azureDisk卷。我們無法在這里詳細介紹如何去實現,實際上是一樣的。首先,需要創建實際的底層存儲,然后在卷定義中設置適當的屬性。
 
Amazon 的 AWS EC2 使用示例
apiVersion: vl 
kind: Pod 
metadata:
  name: mongodb 
spec: 
  volumes:
  - name: mongodb-data
    awsElasticBlockStore:
    volumeid: my-volume
    fsType: ext4
  containers:
  ...
View Code

使用NFS卷

如果集群是運行在自有的一組服務器上,那么就有大量其他可移植的選項用於在卷內掛載外部存儲。例如,要掛載一個簡單的NFS 共享,只需指定NFS服務器和共享路徑。
volumes:
  - name: vol-name
    nfs:
      server: 1.2.3.4
      path: /somewhere/path
View Code

使用其他存儲技術

其他的支持選項包括用於掛載ISCSI磁盤資源的iscsi, 用於掛載GlusterFS的glusterfs, 適用於RADOS塊設備的rbd 還有flexVolume、cinder、cephfs、flocker、fc(光纖通道)等。rbd 如果你不會使用到它們,就不需要知道所有的信息。這里提到是為了展示Kubernetes支持廣泛的存儲技術,並且可以使用喜歡和習慣的任何存儲技術。

從底層存儲技術解耦pod(持久卷和持久卷聲明)

到目前為止, 我們探索過的所有持久卷類型都要求 pod 的開發人員了解集群中可用的真實網絡存儲的基礎結構。 例如, 要創建支持 NFS 協議的卷, 開發人員必須知道 NFS 節點所在的實際服務器。 這違背了 Kubernetes 的基本理念, 這個理念旨在向應用程序及其開發人員隱藏真實的基礎設施, 使他們不必擔心基礎設施的具體狀態, 並使應用程序可在大量雲服務商和數據企業之間進行功能遷移。
 
在 Kubemetes 集群中為了使應用能夠正常請求存儲資源, 同時避免處理基礎設施細節, 引入了兩個新的資源, 分別是待久卷和持久卷聲明

創建持久卷

持久卷不屬於任何命名空間, 它跟節點一樣是集群層面的資源。

apiVersion: vl 
kind: PersistentVolume 
metadata: 
    name: fortune 
spec:
  capacity:
    storage: lGi  
  accessModes:
  - ReadWriteOnce                                        #可以被單個客戶端掛載為讀寫模
  - ReadOnlyMany                                         #式或者被多個客戶端掛載為只讀(這里指的是持久卷聲明)
  persistentVolumeReclaimPolicy: Retain        #當聲明被釋放后,PersistentVolume 將會被保留(不清理和刪除)
  gcePersistentDisk:                   #PersistentVolume指定支持之前創建的GCE持久磁盤
  pdName: asdf
  fsType: ext4
View Code

查看

$ kubectl get pv 
  NAME       CAPACITY  RECLAIMPOLICY ACCESSMODES   STATUS 
  mongodb-pv   lGi     Retain     RWO,ROX      Available 
View Code
 

通過創建持久卷聲明來獲取持久卷

持久卷聲明是屬於命名空間的資源對象,持久卷聲明只能被同一命名空間內的 pod 創建使用

apiVersion: vl 
kind: PersistentVolumeClaim 
metadata: 
    name: fortune-pvc
spec:
  resources:
    requests:
      storage: lGi                       #申請1G 的存儲空間
  accessModes:
  - ReadWriteOnce                        #可以被單個客戶端掛載為讀寫模
  storageClassName: ""                   #將空字符串指定為存儲類名可確保PVC 綁定到預先配置的 PV,而不是動態配置新的PV。關於動態配置pv 下文有介紹。
View Code

當創建好聲明, kubernetes 就會找到適當的持久卷並將其綁定到聲明 ,持久卷的容量必須足夠大以滿足聲明的需求,並且卷模式必須包含聲明中指定的訪問模式 。在該示例中,聲明請求 1GiB 的存儲空間和 ReadWriteOnce 訪問模式,之前創建的持久卷符合剛剛聲明中 的這兩個條件,所以它被綁定到對應的聲明中。 

 

列舉持久卷聲明

$ kubectl get pvc 
  NAME     STATUS   VOLUME     CAPACITY   ACCESSMODES   AGE 
  mongodb-pvc Bound    mongodb-pv   lGi     RWO,ROX      3s
View Code
PVC 狀態顯示己與持久卷的 mongodb pv 綁定。請留意訪問模式的簡寫:
  RWO ReadWriteOnce -- 僅允許單個節點掛載讀寫。
  ROM ReadOnlyMany  -- 僅允許多個節點掛載只讀。
  RWX ReadWriteMany -- 允許多個節點掛載讀寫這個卷。
View Code
注意:RWO ROX RWX 涉及可以同時使用卷的工作節點的數量而並非 pod 數量

 

pod 中使用持久卷聲明

持久卷現在已經可用了 ,除非先釋放掉卷,否則沒有人可以申明相同的卷。要pod 中使用持久卷,需要在pod 的卷中引用持久卷聲明名稱,如下面的代碼清單所示
apiVersion: vl 
kind: Pod 
metadata: 
  name: mongodb
spec: 
  containers: 
  - image: mongo 
    name: mongodb 
    volumeMounts: 
    - name : mogodb-data
      mountPath: /data/db 
    ports: 
    - containerPort: 27017 
      protocol: TCP 
  volumes: 
  - name: mongodb-data 
    persistentVolumeClaim: 
    claimName: mongodb-pvc
View Code

 針對持久卷的回收有兩種方式:自動回收,手動回收。

持久卷的動態卷配置

使用持久卷和持久卷聲明可以輕松獲得持久化存儲資源,無須研發人員處理下面實際使用的存儲技術,但這仍然需要一個集群管理員來支持實際的存儲。幸運的是, kubernetes 還可以通過動態配置持久卷來自動執行此任務。
與管理員預先提供一組持久卷不同的是,它們需要定義一個或兩個(或多個)StorageClass 並允許系統在每次通過持久卷聲明請求時自動創建1個新的持久卷。最重要的是,不可能耗盡持久卷(很明顯 ,你可以用完存儲空間)
 

StorageClass 資源定義

apiVersion: vl 
kind: StorageClass 
metadata: 
    name: fast
provisioner: kubernetes.io/gce-pd      #用於配置持久卷的插件
parameters:
  type:pd-ssd                  #傳遞給parameters的參數
  zone:europe-westl-b
View Code
Tips: kubernetes  包括最流行的雲服務提供商的置備程序 provisioner ,所以管理員並不總是需要創建一個置備程序。 但是如果 kubernetes 部署在本地,則需要配置定制的置備程序。
 
運行機制
StorageClass 資源指定當持久卷聲明請求此 StorageClass 時應使用哪個置備程序來提供持久卷 StorageClass 定義中定義的參數將傳遞給置備程序並具體到每個供應器插件。 StorageClass 使用 GCE 持久磁盤的預配置器,這意味着當 Kubernetes  在GCE 中運行時可供使用。對於其他雲提供商,需要使用其的置備程序
 

創建一個請求特定存儲類的 PVC 定義 

vi storageclass.yaml
  apiVersion: vl 
  kind: PersistentVolumeClaim 
  metadata: 
      name: mongodb-pvc
  spec:
    storageClassName:fast                #該pvc請求自定義存儲類
    resources:
      requests
        storage: lGi                        #申請1G 的存儲空間
    accessModes:
    - ReadWriteOnce                        #可以被單個客戶端掛載為讀寫模

隨后查看會發現自動生成了一個持久卷
$ kubectl get pv
  NAME      CAPACITY   ACCESSMODES  RECLAIMPOLICY   STATUS  STORAGECLASS
  pvc-le6bc048  lGi      RWO        Delete       Bound   fast
 
 
可以看到動態配置的持久卷其容量和訪問模式是在PVC中所要求的 。它的回收策略是 Delete,這意味着當PVC被刪除時,持久卷也將被刪除。
除了 PV置備程序還提供了真實的存儲空間,fast StorageClass 被配置為使用 kubernetes.io/gce-pd 從而提供了GCE 持久磁盤。
 
可以使用以下命令查看磁盤
  $ gcloud compute disks list  
    NAME                ZONE        SIZE_GB     TYPE        STATUS
    kekub-dy-pvc-le6bc04      europe-westl-d   1        pd-standard     READY
 
 
如上所示例 盤的名稱表明它是動態配置的, 同時 類型顯示為一個 SSD,正如在前面創建的存儲類中所指定的那樣。
 
View Code

注意 如果在 PVC 中引用一個不存在的存儲類, PV 的配直將失敗(在 PVC 上使用 kubectl describe 時,將會看到 ProvisioningFailed 事件)

 了解存儲類的使用

集群管理員可以創建具有不同性能或其他特性的多個存儲類,然后研發人員再決定對應每一個聲明最適合的存儲類。
StorageClasses 的好處在於,聲明是通過名稱引用它們的,因此只要 StorageClass名稱在所有這些名稱中相同, PVC 定義便可跨不同集群移植
 
列出存儲類
$ kubectl get sc 
  NAME           TYPE 
  fast            kubernetes.io/gce-pd 
  standard (default)   kubernetes.io/gce-pd
View Code

 Notice:

1、如果持久卷 明沒有明確指出要使用哪個存儲類, 默認存儲類會用於動態提供持久卷的內容。

2、如果尚未將 storageClassName 屬性設置為空字符串, 則盡管已存在適當的預配置持久卷,但動態卷置備程序仍將配置新的持久卷。

 

動態持久卷的配置圖

 

 


免責聲明!

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



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