【k8s學(xué)習(xí)】Kubernetes Volume介紹

【本文目標(biāo)】

  • Kubernetes集群怎樣通過Volume做數(shù)據(jù)持久化的?
  • 持久卷組件 - Persistemt Volume
  • 使用持久卷,組件 - Persistent Volume Claim
  • 在使用持久卷中想要自動創(chuàng)建持久卷,組件 - Storage Class

【前置文章】


1. Volume使用場景

1.1 Use Case-1:mysql Pod需要Storage:

假設(shè)我們有個項(xiàng)目叫my-app,接連了另一個Pod叫mysql,如果mysql重啟了,那么里面存放的數(shù)據(jù)也會丟失,原因是Kubernetes并沒有提供在Pod之外的持久化,一旦Pod重啟了,數(shù)據(jù)就丟失了。

  • Storage that doesn't depend on the pod lifecycle:我們需要在Pod外有存儲數(shù)據(jù),以便不受Pod重啟的影響。
  • Storage must be available on all nodes:假設(shè)一個mysql Pod掛掉了,那么admin controller manager發(fā)現(xiàn)后,就會讓scheduler再找合適的Node重新創(chuàng)建一個Pod,所以新的Pod有可能創(chuàng)建在活著的Worker Node中的任一一個,即這個存儲要對所有的節(jié)點(diǎn)都可見。
  • Storage needs to survive even if cluster crashes:當(dāng)所有的節(jié)點(diǎn)都掛了,Storage里的數(shù)據(jù)也不能丟失。
1.2 Use Case-2:my-app本身可能也需要讀寫文件

比如一些session或是額外的配置等信息,my-app Pod本身,也可能會讀寫數(shù)據(jù),這時候我們就可以配置Persistent Volume,簡稱pv。

2. Persistent Volume

官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

2.1 介紹
  • a cluster resource:集群中的一種資源,比如ram內(nèi)存或是cpu。
  • created via YAML file:和別的組件一樣,可以通過YAML文件創(chuàng)建。
    • 創(chuàng)建的時候kind為PersistentVolume
    • spec中定義了一些自有的屬性,比如占有空間為多少?(spec.capacity.storage
  • Needs actual physical storage:持久化的地方必須是能支持存儲的地方,如集群里的某個存儲空間或是集群外的某臺Server或是云服務(wù)器。所以這里有個問題就是如何讓Kubernetes集群讀取到這些存儲。
  • what type of storage do you need? need to create & manage them by yourself:Persistent Volume更像是一個接口,它只提供了一些規(guī)范,至于存儲的類型以及創(chuàng)建和管理、備份,都在Kubernetes之外,并不歸K8s集群管理。
2.2 yaml配置示例

下述示例中的Storage的地方是NFS文件系統(tǒng):

apiVersion:
kind: persistentVolume
metadata:
  name: pv-name
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessMode:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.0
  nfs:
    path: /dir/path/on/nfs/server
    server: nfs-server-ip-address

上述spec中定義了三部分:

  • 存儲能力
  • 額外的信息比如進(jìn)入的模式
  • nfs參數(shù)

不同的存儲類型,配置可能會長不一樣。
從官網(wǎng)上可以看到,卷的類型超過了20種:https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

Persistent Volume并不從屬于某個命令空間,它是全局的組件。即所有的命名空間下的組件,都可引用到該pv組件。

2.3 Local Volume vs. Remote Volume

根據(jù)存放地點(diǎn)分類:

  • Local Volume(在Kubernetes集群內(nèi)),這種Storage就違反了1.1章的特點(diǎn)2和特點(diǎn)3,即它是跟集群中的某個Node綁定了,所以有可能會掛掉,以及如果集群down了,這個Storage也可能down掉。正因?yàn)榇?,像DB數(shù)據(jù)庫的持久化存儲,最好放在集群外,即Remove Volume中。
  • Remote Volume,即集群外部存儲,符合1.1章節(jié)的三個特點(diǎn)。

什么時候創(chuàng)建Persistent Volume?
如果某個Pod依賴于pv,那么這個pv需要在Pod被創(chuàng)建之前創(chuàng)建。

誰來創(chuàng)建?
一般來說,開發(fā)人員需要告訴admin(可能是DevOps Team)某個項(xiàng)目需要用到Persistent Volume,然后DevOps人員根據(jù)開發(fā)人員的需求,在Kubernetes集群中幫忙定義并創(chuàng)建好了該pv。

在定義好之后,開發(fā)人員則需要在具體的Pod的yaml中定義引用該pv,在yaml中聲明需要用到某個pv,這時候需要另一個組件,叫Persistent Volume Claim,簡稱pvc。

3. Persistent Volume Claim

官網(wǎng):

3.1 Persistent Volume Claim yaml示例

pvc如何找到pv?通過屬性例如大小等找到合適的pv:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-name
spec:
  storageClassName: manual
  volumeMode: Filesystem
  accessMode:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

定義了pvc后,怎么在Pod中引用呢?即通過spec.volumes.persistenceVolumeClaim.claimName進(jìn)行關(guān)聯(lián):

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: pvc-name

【整個過程】
Pod通過pv claim請求volume --> pv claim嘗試在集群中找到合適的volume --> 找到的volume才是真正擁有存儲空間的地方。 --> 這時候volume會被mounted(掛載)到這個Pod --> 然后才被掛載到Pod中的Container(這也是為什么上述Container中定義了volumeMounts屬性) --> 至此,具體的app應(yīng)用才能讀寫該volume

pvc并不是全局的組件,它可以被創(chuàng)建到某個namespace下,pvc所屬的namespace必須要和Pod相同(因?yàn)镻od定義中需要引用到pvc組件)。

3.2 思考:為什么需要這么多層抽像?
  • DevOps人員聲明并創(chuàng)建全局組件pv。
  • 開發(fā)人員聲明并創(chuàng)建pvc,并在Pod中使用。

這樣設(shè)計(jì)的主要好處是開發(fā)人員友好,因?yàn)殚_發(fā)人員并不需要具體知道Storage存放地點(diǎn)(解藕),而只需要使用即可。

3.3 通過spec.volumes引用ConfigMap和Secret

ConfigMap組件和Secret組件:

  • local volumes:這兩個組件都是本地存儲卷。
  • not created via pv and pvc:不是通過pv和pvc聲明創(chuàng)建的。
  • managed by Kubernetes

我們也可以通過volume屬性定義這兩個組件,然后在container中mounts,以下是示例:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: busybox-container
      image: busybox
      volumeMounts:
        - name: config-dir
          mountPath: /etc/config
  volumes:
    - name: config-dir
      configMap:
        name: bb-configmap

注:一個Pod可以有多個volume claim。

4. Storage Class

官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

為了讓pv創(chuàng)建以及pvc創(chuàng)建更加高效,則需要第三個組件,叫Storage Class,簡稱sc。

sc可以根據(jù)PersistentVolumeClaim的定義,動態(tài)的生成pv。

示例:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: storage-class-name
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4
  • via "provisioner" attribute:provisioner意思為供應(yīng)方,聲明了pv的具體提供商,每個Storage類型都有自己的provisioner,在需要的時候查閱官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner
  • configure "parameters" for storage we want to request for Persistent Volume:parameters屬性定義了pv所需要的信息,例如類型,空間大小等。

sc主要是為了減少DevOps的工具,即可以動態(tài)的生成pv,那么誰來引入sc組件呢?答案很明顯,是pvc。即開發(fā)人員不需要每次讓DevOps的人手動創(chuàng)建pv,而是通過Storage Class來自動創(chuàng)建pv。

在pvc中使用:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessMode:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
    storageClassName: storage-class-name

【整個過程】

  1. Pod通過pvc請求存儲。
  2. pvc通過sc請求存儲。
  3. sc自動創(chuàng)建可以滿足要求的pv。

參考:
https://www.youtube.com/watch?v=X48VuDVv0do

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容