Kubernetes 存儲的基本概念

Kubernetes 存儲卷

根據(jù)應(yīng)用本身是否需要持久存儲數(shù)據(jù),以及每一次的請求跟此前的請求之間是否有關(guān)聯(lián)性囊蓝,可以分為四類應(yīng)用:

  • 有狀態(tài)、要存儲
  • 有狀態(tài)令蛉、無存儲
  • 無狀態(tài)聚霜、有存儲
  • 無狀態(tài)、無存儲

持久化數(shù)據(jù)的方式

節(jié)點級:節(jié)點提供存儲卷珠叔。此方式在k8s上蝎宇,不太適用。這是因為一旦Pod被刪除了祷安,Pod是要被Scheduler組件重新調(diào)度的姥芥,調(diào)度之后的Pod并不一定還能運行在原來的節(jié)點上。
脫離節(jié)點而存在的網(wǎng)絡(luò)共享存儲設(shè)備汇鞭。k8s使用這種方式凉唐。

Pod的特點:

同一個Pod內(nèi)的多個容器,可共享訪問同一個存儲卷霍骄。因為:對k8s來講台囱,存儲卷不屬于容器,而屬于Pod读整,可以在容器中掛在存儲卷簿训,所以,如果兩個容器掛在了同一個存儲卷米间,相當(dāng)于兩個容器共享數(shù)據(jù)了强品。
為什么Pod能有存儲卷Volume,也能有網(wǎng)絡(luò)命名空間Namespace呢屈糊?Pod其實底層有個基礎(chǔ)容器pause的榛。所有的網(wǎng)絡(luò)名稱空間,存儲卷的掛載另玖,都是分配給基礎(chǔ)容器pause的困曙。在Pod中運行的容器是共享基礎(chǔ)容器pause的命名空間、存儲卷的谦去。所以這就是為什么同一個Pod內(nèi)的所有容器都能使用同一個IP地址慷丽、共享同一個TCP/IP協(xié)議棧、使用同一個主機(jī)名的原因(因為ipc鳄哭、net要糊、uts名稱空間是共享的)。
如果在Pod上使用存儲卷:Pod的基礎(chǔ)架構(gòu)容器pause使用存儲卷——>容器的存儲卷就是容器的目錄與宿主機(jī)目錄建立關(guān)系——>如果宿主機(jī)的目錄就是宿主機(jī)本地的妆丘,那么就隨著宿主機(jī)的終結(jié)而終結(jié)锄俄,所以為了真正實現(xiàn)持久性,宿主機(jī)的目錄也不是宿主機(jī)本地的勺拣,而是宿主機(jī)掛載的外部存儲設(shè)備上的存儲卷奶赠。

k8s提供的存儲卷類型

empryDir

emptyDir類型的volume在pod分配到node上時被創(chuàng)建,kubernetes會在node上自動分配 一個目錄药有,因此無需指定宿主機(jī)node上對應(yīng)的目錄文件毅戈。這個目錄的初始內(nèi)容為空,當(dāng)Pod從node上移除時愤惰,emptyDir中的數(shù)據(jù)會被永久刪除苇经。不具備持久存儲性。

hostPath

hostPath Volume為pod掛載宿主機(jī)上的目錄或文件宦言,使得容器可以使用宿主機(jī)的高速文件系統(tǒng)進(jìn)行存儲扇单。缺點是,在k8s中奠旺,pod都是動態(tài)在各node節(jié)點上調(diào)度蜘澜。當(dāng)一個pod在當(dāng)前node節(jié)點上啟動并通過hostPath存儲了文件到本地以后,下次調(diào)度到另一個節(jié)點上啟動時响疚,就無法使用在之前節(jié)點上存儲的文件(如果調(diào)度到同一個節(jié)點兼都,還是可以繼續(xù)使用之前節(jié)點上存儲的文件的)。不具備持久存儲性稽寒。

使用 subPath

引用卷的時候扮碧,默認(rèn)會將卷的根目錄掛載到指定路徑中。
可以通過 subPath 掛載卷的子目錄杏糙,而不是根目錄慎王。
示例

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

將掛載 site-data 卷的子目錄 mysql 到容器目錄 /var/lib/mysql 中

gitRepo

gitRepo—通過檢查git倉庫的內(nèi)容來初始化卷(實質(zhì)也是一個emptyDir,只不過預(yù)置了git倉庫內(nèi)容)
每次pod重新創(chuàng)建時宏侍,會自動拉取最新代碼

網(wǎng)絡(luò)存儲設(shè)備

無論P(yáng)od重啟后是否調(diào)度到原來的節(jié)點赖淤,存儲的文件可以繼續(xù)使用。

  • 傳統(tǒng)意義上的網(wǎng)絡(luò)存儲設(shè)備:SAN(存儲區(qū)域網(wǎng)絡(luò)的簡稱谅河,常見的有:iSCSI...)咱旱、NAS(網(wǎng)絡(luò)附屬存儲:常見的有:nfs确丢、cifs)...
    nfs 卷能將 NFS (網(wǎng)絡(luò)文件系統(tǒng)) 掛載到您的 Pod 中。
    不像 emptyDir 那樣會在刪除 Pod 的同時也會被刪除吐限,nfs 卷的內(nèi)容在刪除 Pod 時會被保存鲜侥,卷只是被卸載掉了。
    這意味著 nfs 卷可以被預(yù)先填充數(shù)據(jù)诸典,并且這些數(shù)據(jù)可以在 Pod 之間"傳遞"描函。

  • 分布式網(wǎng)絡(luò)存儲設(shè)備:glusterfs(文件系統(tǒng)級別存儲)、cephfs(文件系統(tǒng)級別存儲)狐粱、ceph rbd(塊級別存儲)...

  • 云網(wǎng)絡(luò)存儲設(shè)備:EBS(亞馬遜的)舀寓、Azure Disk(微軟的)、Azure File(微軟的)...

  • pvc和pv
    兩種特殊類型的存儲卷:目的不是給Pod提供存儲空間肌蜻,而是給管理員或用戶提供了互墓,從集群外部向Pod內(nèi)部的應(yīng)用,注入配置信息的

  • configmap
    ConfigMap 資源提供了向 Pod 注入配置數(shù)據(jù)的方法蒋搜。
    ConfigMap 對象中存儲的數(shù)據(jù)可以被 configMap 類型的卷引用轰豆,然后被應(yīng)用到 Pod 中運行的容器。
    可以在 volumes 字段中引用 configMap 名稱來生成一個卷齿诞。
    可以自定義 ConfigMap 中特定條目所要使用的路徑酸休。
    如果容器以 subPath 卷掛載方式使用 ConfigMap 時,將無法接收 ConfigMap 的更新祷杈。
    示例

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

ConfigMap 中 key log_level 中的內(nèi)容將被掛載到 Pod 路徑 /etc/config/log_level 中
路徑由 spec.containers 中參數(shù) volumeMounts.mountpath 和 volumes 中參數(shù) items.path 拼接而成

  • secret(方式)
    secret 卷用來給 Pod 傳遞敏感信息斑司,例如密碼。
    可以將 secret 存儲在 Kubernetes API 服務(wù)器上但汞,然后以文件的形式掛在到 Pod 中宿刮,實現(xiàn)與 Pod 解耦。
    secret 卷由 tmpfs(基于內(nèi)存的文件系統(tǒng))提供存儲私蕾,因此它們永遠(yuǎn)不會被寫入持久化的存儲器僵缺。
    容器以 subPath 卷的方式掛載 Secret 時,它將無法實時獲取 Secret 的更新

pvc的相關(guān)知識

pvc——>與當(dāng)前命名空間中的pvc資源建立關(guān)系——>與pv資源(真正提供存儲的資源)建立關(guān)系——>與存儲系統(tǒng)建立關(guān)系


image.png
  • 在pvc不被調(diào)用時踩叭,pvc和pv之間是沒有綁定的磕潮。
  • pv和pvc是一一對應(yīng)的,一旦某個pv被某個pvc綁定了容贝,這個pv就不能被其他pvc綁定自脯。
  • pvc究竟綁定哪個pv?取決于pvc的定義中所指定的dataSource的大小斤富。比如pvc指定存儲空間的大小為5G膏潮,那么存儲空間為2G的pv就不符合條件。
  • 還可以指定pvc的訪問模型(取決于pvc的定義中做指定的accessModes).


    image.png

    首先我們看下PV和PVC的生命周期過程:

image.png

資源供應(yīng) (Provisioning)

資源供應(yīng) 就是集群管理員(k8s集群)將volume虛擬化為很多個PV满力,目的就是創(chuàng)建合適的PV焕参,有靜態(tài)模式和動態(tài)模式轻纪。

靜態(tài)模式:集群管理員手工創(chuàng)建許多PV,在定義PV時需要將后端存儲的特性進(jìn)行設(shè)置
動態(tài)模式:集群管理員無須手工創(chuàng)建PV叠纷,而是通過StorageClass的設(shè)置對后端存儲進(jìn)行描述刻帚,標(biāo)記為某種 “類型(Class)”。此時要求PVC對存儲的類型進(jìn)行聲明讲岁,系統(tǒng)將自動完成PV的創(chuàng)建及PVC的綁定我擂。PVC可以聲明Class為””衬以,說明該P(yáng)VC禁止使用動態(tài)模式

資源綁定 (Binding)

用戶定義好PVC后缓艳,系統(tǒng)會根據(jù)PVC對存儲的請求選擇一個滿足PVC要求的PV(PV的存在可能比PVC請求的大),找到就綁定看峻,PV就被該P(yáng)VC獨占阶淘,不能和其他PVC綁定,如果沒找到就一直處于pending中互妓。如果資源供應(yīng)使用的是動態(tài)模式溪窒,則系統(tǒng)在PVC找到合適的StorageClass后,將會自動創(chuàng)建PV并完成PVC的綁定冯勉。

資源使用 (Using)

image.png

POD創(chuàng)建可以綁定PVC澈蚌,也可以多個POD掛載同一個PVC即共享多個實例共同訪問一塊存儲空間

資源釋放 (Releasing):

當(dāng)用戶對存儲資源使用哪個完畢后,用戶可以刪除PVC灼狰,與該P(yáng)VC綁定的PV將會被標(biāo)記為已釋放宛瞄,但還不能立刻與其他PVC進(jìn)行綁定。通過之前PVC寫入的數(shù)據(jù)可能還留在存儲設(shè)備上交胚,只有在清除之后該P(yáng)V才能繼續(xù)使用

資源回收 (Reclaiming)

對于PV份汗,管理員可以設(shè)定回收策略(Reclaim Policy)用于設(shè)置與之綁定的PVC釋放資源之后,對于遺留數(shù)據(jù)如何處理蝴簇。只有PV的存儲空間完成回收杯活,才能供新的PVC綁定和使用。

對于上述生命周期過程熬词,對于PV的不同狀態(tài):

  • Available (可用): 表示可用狀態(tài)旁钧,還未被任何PVC綁定 (資源供應(yīng)、資源釋放<數(shù)據(jù)清除完>)
  • Bound (已綁定):已經(jīng)綁定到某個PVC (資源綁定互拾、資源使用)
  • Released (已釋放):對應(yīng)的PVC已經(jīng)刪除,但資源還沒有被集群收回 (資源釋放<數(shù)據(jù)未清除>)
  • Failed:PV自動回收失敗

下面說下怎么創(chuàng)建PV:

首先要創(chuàng)建存儲服務(wù)均践,以NFS存儲為例:https://www.csdn.net/gather_26/MtjaggzsOTk0NTItYmxvZwO0O0OO0O0O.html

定義好PV模型及pv的yaml文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1         #pv名稱
spec:
  capacity:         #存儲能力,一個pv對象都要指定一個存儲能力摩幔,目前僅支持存儲空間的設(shè)置
    storage: 1Gi    #存儲空間
  accessModes:
  - ReadWriteOnce   #訪問模式
  persistentVolumeReclaimPolicy: Recycle     #回收策略
  nfs:              #服務(wù)模式 (nfs彤委、ceph、hostpath等)
    path: /data/k8s-volume     #共享數(shù)據(jù)目錄掛載點
    server: 192.168.1.4044         #nfs服務(wù)器地址

其中訪問模式有三種:

  • ReadWriteOnce (RWO) 讀寫權(quán)限或衡,但是只能被單個節(jié)點掛載
  • ReadOnlyMany (ROX) 只讀權(quán)限焦影,可能被多個節(jié)點掛載
  • ReadWriteMany (RWX) 讀寫權(quán)限车遂,可以被多個節(jié)點掛載

回收策略也有三種:

  • Retain (保留) 保留數(shù)據(jù),需要管理員手動清理
  • Recycle (回收) 清除PV中的數(shù)據(jù)斯辰,效果相當(dāng)于執(zhí)行刪除命令
  • Delete (刪除) 與PV相連的后端存儲完成volume的刪除操作舶担,常見于云服務(wù)商的存儲服務(wù)

創(chuàng)建PV:

[root]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created

查看PV:

[root]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Available                                   5s

如果PV被PVC綁定,會有CLAIM信息:

創(chuàng)建PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
[root@harbor ~]# kubectl apply -f pv.yaml 
persistentvolume/pv1 created
 
[root@harbor ~]# kubectl get pvc -n default
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-nfs   Bound    pv1      1Gi        RWO                           71s
 
[root@harbor ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv1    1Gi        RWO            Recycle          Bound    default/pvc-nfs                           4m35s

這里我們可以看到彬呻,當(dāng)我們創(chuàng)建pvc之后衣陶,pv的狀態(tài)變成了Bound綁定狀態(tài),并且和pvc的狀態(tài)相同闸氮。并且可以看到pvc已經(jīng)綁定到名稱為pv1的volume上剪况,同時在pv上可以看到綁定到名稱為pvc-nfs的pvc中
其中查詢PVC信息要帶namespaces,因為PVC被POD使用必須歸屬某個命名空間

但是我們怎么通過創(chuàng)建PVC綁定我們需要的PV呢蒲跨,這邊就涉及l(fā)abel的使用了译断,在k8s中pod綁定node等都是通過label來的:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
  labels:           #這里將pv設(shè)置一個labels
    app: nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/k8s-volume
    server: 192.168.1.144
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2-nfs
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:         ##pvc匹配標(biāo)簽為app=nfs的pv
    matchLabels:
      app: nfs

下面我們創(chuàng)建deployment使用PVC:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pv-nfs-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: pv-nfs-nginx
  template:
    metadata:
      labels:
        app: pv-nfs-nginx
    spec:
      containers:
      - name: pv-nfs-nginx
        image: nginx
        ports:
        - containerPort: 801
        volumeMounts:           #掛載,首先添加需要掛載的目錄
        - name: pv-nginx        #掛載點的名稱
          mountPath: /usr/share/nginx/html   #掛載點的路徑
      volumes:    #綁定
      - name: pv-nginx
        persistentVolumeClaim:    #將鏡像中的nginx目錄掛載到下面名稱的pvc中
          claimName: pvc2-nfs   #pvc名稱
---
apiVersion: v1
kind: Service
metadata:
  name: nfs-pvc
  labels:
    app: pv-nfs-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 324
  selector:
    app: pv-nfs-nginx

deploy是replicaset上一層的控制器或悲,而service為deployment對外提供訪問服務(wù)的能力的孙咪,而本項目是沒有使用deployment而只使用了replicaset,且也沒有使用service

StorageClass

理論

在動態(tài)資源供應(yīng)模式下巡语,通過StorageClass和PVC完成資源動態(tài)綁定(系統(tǒng)自動生成PV)翎蹈,并供Pod使用的存儲管理機(jī)制。

image.png

volumeClaimTemplates實現(xiàn)了pvc的自動化男公,StorageClass實現(xiàn)了pv的自動化

什么是StorageClass

Kubernetes提供了一套可以自動創(chuàng)建PV的機(jī)制荤堪,即:Dynamic Provisioning。而這個機(jī)制的核心在于StorageClass這個API對象理澎。

StorageClass對象會定義下面兩部分內(nèi)容:

  1. PV的屬性逞力。比如,存儲類型糠爬,Volume的大小等寇荧。
  2. 創(chuàng)建這種PV需要用到的存儲插件,即存儲制備器执隧。
    有了這兩個信息之后揩抡,Kubernetes就能夠根據(jù)用戶提交的PVC,找到一個對應(yīng)的StorageClass镀琉,之后Kubernetes就會調(diào)用該StorageClass聲明的存儲插件峦嗤,進(jìn)而創(chuàng)建出需要的PV。

但是其實使用起來是一件很簡單的事情屋摔,你只需要根據(jù)自己的需求烁设,編寫YAML文件即可,然后使用kubectl create命令執(zhí)行即可钓试。

StorageClass 為管理員提供了描述存儲 “類” 的方法装黑。 不同的類型可能會映射到不同的服務(wù)質(zhì)量等級或備份策略副瀑,或是由集群管理員制定的任意策略。 Kubernetes 本身并不清楚各種類代表的什么恋谭。這個類的概念在其他存儲系統(tǒng)中有時被稱為 “配置文件”糠睡。

為什么需要StorageClass

在一個大規(guī)模的Kubernetes集群里,可能有成千上萬個PVC疚颊,這就意味著運維人員必須實現(xiàn)創(chuàng)建出這個多個PV狈孔,此外,隨著項目的需要材义,會有新的PVC不斷被提交均抽,那么運維人員就需要不斷的添加新的,滿足要求的PV母截,否則新的Pod就會因為PVC綁定不到PV而導(dǎo)致創(chuàng)建失敗到忽。而且通過 PVC 請求到一定的存儲空間也很有可能不足以滿足應(yīng)用對于存儲設(shè)備的各種需求橄教。

而且不同的應(yīng)用程序?qū)τ诖鎯π阅艿囊罂赡芤膊槐M相同清寇,比如讀寫速度、并發(fā)性能等护蝶,為了解決這一問題华烟,Kubernetes 又為我們引入了一個新的資源對象:StorageClass,通過 StorageClass 的定義持灰,管理員可以將存儲資源定義為某種類型的資源盔夜,比如快速存儲、慢速存儲等堤魁,用戶根據(jù) StorageClass 的描述就可以非常直觀的知道各種存儲資源的具體特性了喂链,這樣就可以根據(jù)應(yīng)用的特性去申請合適的存儲資源了。

運行原理

要使用 StorageClass妥泉,我們就得安裝對應(yīng)的自動配置程序椭微,比如我們這里存儲后端使用的是 nfs,那么我們就需要使用到一個 nfs-client 的自動配置程序盲链,我們也叫它 Provisioner(制備器)蝇率,這個程序使用我們已經(jīng)配置好的 nfs 服務(wù)器,來自動創(chuàng)建持久卷刽沾,也就是自動幫我們創(chuàng)建 PV本慕。

  1. 自動創(chuàng)建的 PV 以{namespace}-{pvcName}-${pvName}這樣的命名格式創(chuàng)建在 NFS 服務(wù)器上的共享數(shù)據(jù)目錄中
  2. 而當(dāng)這個 PV 被回收后會以archieved-{namespace}-{pvcName}-${pvName}這樣的命名格式存在 NFS 服務(wù)器上。
    image.png

StorageClass 資源

每個 StorageClass 都包含 provisioner侧漓、parameters 和 reclaimPolicy 字段锅尘, 這些字段會在 StorageClass 需要動態(tài)分配 PersistentVolume 時會使用到。

StorageClass 對象的命名很重要布蔗,用戶使用這個命名來請求生成一個特定的類藤违。 當(dāng)創(chuàng)建 StorageClass 對象時忙菠,管理員設(shè)置 StorageClass 對象的命名和其他參數(shù),一旦創(chuàng)建了對象就不能再對其更新纺弊。

管理員可以為沒有申請綁定到特定 StorageClass 的 PVC 指定一個默認(rèn)的存儲類牛欢。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate

存儲制備器

每個 StorageClass 都有一個制備器(Provisioner),用來決定使用哪個卷插件制備 PV淆游。 該字段必須指定

表卷插件 內(nèi)置制備器 配置例子
AWSElasticBlockStore ? AWS EBS
AzureFile ? Azure File
AzureDisk ? Azure Disk
CephFS - -
Cinder ? OpenStack Cinder
FC - -
FlexVolume - -
Flocker ? -
GCEPersistentDisk ? GCE PD
Glusterfs ? Glusterfs
iSCSI - -
Quobyte ? Quobyte
NFS - -
RBD ? Ceph RBD
VsphereVolume ? vSphere
PortworxVolume ? Portworx Volume
ScaleIO ? ScaleIO
StorageOS ? StorageOS
Local - Local

你不限于指定此處列出的 “內(nèi)置” 制備器(其名稱前綴為 “kubernetes.io” 并打包在 Kubernetes 中)傍睹。 你還可以運行和指定外部制備器,這些獨立的程序遵循由 Kubernetes 定義的 規(guī)范犹菱。 外部供應(yīng)商的作者完全可以自由決定他們的代碼保存于何處拾稳、打包方式、運行方式腊脱、使用的插件(包括 Flex)等访得。 代碼倉庫 kubernetes-sigs/sig-storage-lib-external-provisioner 包含一個用于為外部制備器編寫功能實現(xiàn)的類庫。你可以訪問代碼倉庫 kubernetes-sigs/sig-storage-lib-external-provisioner 了解外部驅(qū)動列表陕凹。

例如悍抑,NFS 沒有內(nèi)部制備器,但可以使用外部制備器杜耙。 也有第三方存儲供應(yīng)商提供自己的外部制備器搜骡。

后面會演示NFS

回收策略

由 StorageClass 動態(tài)創(chuàng)建的 PersistentVolume 會在類的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain佑女。如果 StorageClass 對象被創(chuàng)建時沒有指定 reclaimPolicy记靡,它將默認(rèn)為 Delete。

通過 StorageClass 手動創(chuàng)建并管理的 PersistentVolume 會使用它們被創(chuàng)建時指定的回收政策团驱。

允許卷擴(kuò)展

PersistentVolume 可以配置為可擴(kuò)展摸吠。將此功能設(shè)置為 true 時,允許用戶通過編輯相應(yīng)的 PVC 對象來調(diào)整卷大小嚎花。

當(dāng)下層 StorageClass 的 allowVolumeExpansion 字段設(shè)置為 true 時寸痢,以下類型的卷支持卷擴(kuò)展。

卷類型 Kubernetes 版本要求
gcePersistentDisk 1.11
awsElasticBlockStore 1.11
Cinder 1.11
glusterfs 1.11
rbd 1.11
Azure File 1.11
Azure Disk 1.11
Portworx 1.11
FlexVolume 1.13
CSI 1.14 (alpha), 1.16 (beta)

說明: 此功能僅可用于擴(kuò)容卷贩幻,不能用于縮小卷轿腺。

掛載選項

由 StorageClass 動態(tài)創(chuàng)建的 PersistentVolume 將使用類中 mountOptions 字段指定的掛載選項。

如果卷插件不支持掛載選項丛楚,卻指定了該選項族壳,則制備操作會失敗。 掛載選項在 StorageClass 和 PV 上都不會做驗證趣些,所以如果掛載選項無效仿荆,那么這個 PV 就會失敗。

卷綁定模式

volumeBindingMode 字段控制了卷綁定和動態(tài)制備 應(yīng)該發(fā)生在什么時候。

默認(rèn)情況下拢操,Immediate 模式表示一旦創(chuàng)建了 PersistentVolumeClaim 也就完成了卷綁定和動態(tài)制備锦亦。 對于由于拓?fù)湎拗贫羌核泄?jié)點可達(dá)的存儲后端,PersistentVolume 會在不知道 Pod 調(diào)度要求的情況下綁定或者制備令境。

集群管理員可以通過指定 WaitForFirstConsumer 模式來解決此問題杠园。 該模式將延遲 PersistentVolume 的綁定和制備,直到使用該 PersistentVolumeClaim 的 Pod 被創(chuàng)建舔庶。 PersistentVolume 會根據(jù) Pod 調(diào)度約束指定的拓?fù)鋪磉x擇或制備抛蚁。這些包括但不限于 資源需求、 節(jié)點篩選器惕橙、 pod 親和性和互斥性瞧甩、 以及污點和容忍度。

以下插件支持動態(tài)供應(yīng)的 WaitForFirstConsumer 模式:

  • AWSElasticBlockStore
  • GCEPersistentDisk
  • AzureDisk
    以下插件支持預(yù)創(chuàng)建綁定 PersistentVolume 的 WaitForFirstConsumer 模式:
  • 上述全部
  • Local
    動態(tài)配置和預(yù)先創(chuàng)建的 PV 也支持 CSI卷弥鹦, 但是你需要查看特定 CSI 驅(qū)動程序的文檔以查看其支持的拓?fù)滏I名和例子肚逸。

允許的拓?fù)浣Y(jié)構(gòu)

當(dāng)集群操作人員使用了 WaitForFirstConsumer 的卷綁定模式, 在大部分情況下就沒有必要將制備限制為特定的拓?fù)浣Y(jié)構(gòu)彬坏。 然而朦促,如果還有需要的話,可以使用 allowedTopologies苍鲜。

這個例子描述了如何將供應(yīng)卷的拓?fù)湎拗圃谔囟ǖ膮^(qū)域思灰,在使用時應(yīng)該根據(jù)插件 支持情況替換 zone 和 zones 參數(shù)玷犹。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
  - key: failure-domain.beta.kubernetes.io/zone
    values:
    - us-central1-a
    - us-central1-b

實戰(zhàn)演示

部署流程

搭建StorageClass + NFS混滔,大致有以下幾個步驟:

  1. 創(chuàng)建一個可用的NFS Server

  2. 創(chuàng)建Service Account,這是用來管控NFS Provisioner 在k8s集群中運行的權(quán)限

NFS provisioner是一個provisioner相關(guān)的插件歹颓,需要從網(wǎng)絡(luò)上下載坯屿,我們已經(jīng)下載下來放到鏡像庫中了
下載以后需要以pod方式運行通過deployment部署導(dǎo)入到本地環(huán)境中


image.png

創(chuàng)建StorageClass的時候需要指定provisioner

  1. 創(chuàng)建StorageClass,負(fù)責(zé)建立PVC并調(diào)用NFS provisioner進(jìn)行預(yù)定的工作巍扛,并讓PV與PVC建立關(guān)聯(lián)

  2. 創(chuàng)建NFS provisioner领跛,有兩個功能,一個是在NFS共享目錄下創(chuàng)建掛載點(volume)撤奸,另一個則是建了PV并將PV與NFS的掛載點建立關(guān)聯(lián)

創(chuàng)建Service Account

NFS Server在前面的章節(jié)中已經(jīng)安裝過了吠昭。
鑒權(quán)概述 官方文檔
使用 RBAC 鑒權(quán) 官方文檔


# rbac.yaml:#唯一需要修改的地方只有namespace,根據(jù)實際情況定義
apiVersion: v1
kind: ServiceAccount #  創(chuàng)建一個賬戶,主要用來管理NFS provisioner在k8s集群中運行的權(quán)限
metadata:
  name: nfs-client-provisioner
  namespace: default
---
kind: ClusterRole # 創(chuàng)建集群角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner # 角色名
rules: # 角色權(quán)限
  - apiGroups: [""]
    resources: ["persistentvolumes"] # 操作的資源
    verbs: ["get", "list", "watch", "create", "delete"] # 對該資源的操作權(quán)限
  - 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-client-provisioner
subjects: # 角色綁定對象
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole # 哪個角色
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role # 創(chuàng)建角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner # 角色名
  namespace: default # Role需要指定名稱空間胧瓜,ClusterRole 不需要
rules: # 角色權(quán)限
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding # 角色綁定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
subjects: # 角色綁定對象
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef: # 綁定哪個角色
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

創(chuàng)建StorageClass矢棚,指定provisioner

#創(chuàng)建NFS資源的StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass # 創(chuàng)建StorageClass
metadata:
  name: managed-nfs-storage
provisioner: qgg-nfs-storage #這里的名稱要和provisioner配置文件中的環(huán)境變量PROVISIONER_NAME保持一致
parameters:  
   archiveOnDelete: "false"

# 創(chuàng)建NFS provisioner
apiVersion: apps/v1
kind: Deployment # 部署nfs-client-provisioner
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: default #與RBAC文件中的namespace保持一致
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner # 指定serviceAccount!
      containers:
        - name: nfs-client-provisioner
          image: hub.kaikeba.com/java12/nfs-client-provisioner:v1 #鏡像地址
          volumeMounts: # 掛載數(shù)據(jù)卷到容器指定目錄
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME # 配置provisioner的Name
              value: qgg-nfs-storage # 確保該名稱與 StorageClass 資源中的provisioner名稱保持一致
            - name: NFS_SERVER #綁定的nfs服務(wù)器
              value: 192.168.66.13
            - name: NFS_PATH   #綁定的nfs服務(wù)器目錄
              value: /opt/k8s
      volumes: # 申明nfs數(shù)據(jù)卷
        - name: nfs-client-root
          nfs:
            server: 192.168.66.13
            path: /opt/k8s

創(chuàng)建pod測試

創(chuàng)建pod,申明PVC進(jìn)行測試

# 申明一個PVC府喳,指定StorageClass
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations: 
    # 通過annotations注解蒲肋,和storage-class進(jìn)行關(guān)聯(lián),為什么不使用storageClassName,因為版本比較低
    # 這里指定的名字就是上面創(chuàng)建的StorageClass的名字兜粘,讓它幫我們創(chuàng)建PV
    volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
---
# 創(chuàng)建測試pod,查看是否可以正常掛載    
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: busybox:1.24
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && exit 0 || exit 1"   #創(chuàng)建一個SUCCESS文件后退出
    volumeMounts:
      - name: nfs-pvc # 掛載數(shù)據(jù)卷
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim: # 數(shù)據(jù)卷掛載的是pvc
        claimName: test-claim  #與PVC名稱保持一致

測試是否會幫我自動創(chuàng)建pv:


image.png

看到自動創(chuàng)建了一個PV與PVC進(jìn)行綁定申窘。

清除環(huán)境


image.png

集合StatefulSet測試

StatefulSet+volumeClaimTemplates自動創(chuàng)建PV:

# StateFulDet+volumeClaimTemplates自動創(chuàng)建PV
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None 
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates: # 通過模板化方式綁定
  - metadata:
      name: www # 指定pvc的名字
      annotations:
        volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" #只指定了storageClass
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

看到是有序依次創(chuàng)建:


image.png

看到pvc是自動創(chuàng)建的,pv也是:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孔轴,一起剝皮案震驚了整個濱河市剃法,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌路鹰,老刑警劉巖玄窝,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悍引,居然都是意外死亡恩脂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門趣斤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俩块,“玉大人,你說我怎么就攤上這事浓领∮窨” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵联贩,是天一觀的道長漫仆。 經(jīng)常有香客問我,道長泪幌,這世上最難降的妖魔是什么盲厌? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮祸泪,結(jié)果婚禮上吗浩,老公的妹妹穿的比我還像新娘。我一直安慰自己没隘,他們只是感情好懂扼,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著右蒲,像睡著了一般阀湿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瑰妄,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天陷嘴,我揣著相機(jī)與錄音,去河邊找鬼翰撑。 笑死罩旋,一個胖子當(dāng)著我的面吹牛啊央,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涨醋,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瓜饥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浴骂?” 一聲冷哼從身側(cè)響起乓土,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎溯警,沒想到半個月后趣苏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡梯轻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年食磕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喳挑。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡彬伦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伊诵,到底是詐尸還是另有隱情单绑,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響旦装,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜区转,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弯屈。 院中可真熱鬧蜗帜,春花似錦、人聲如沸资厉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宴偿。三九已至,卻和暖如春诀豁,著一層夾襖步出監(jiān)牢的瞬間窄刘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工舷胜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留娩践,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像翻伺,于是被迫代替她去往敵國和親材泄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容