iT邦幫忙

2021 iThome 鐵人賽

DAY 12
1
DevOps

k8s 入門學習 30天系列 第 12

IT 鐵人賽 k8s 入門30天 -- day12 Persisting Data in K8s with Volumes

  • 分享至 

  • xImage
  •  

前言

這篇文章主要介紹在 k8s 如何建立能夠保存資料的服務

當我們需要讓運行的服務資料狀態能夠在服務重開後也能保存

就需要以下 3種元件

Persistent Volume, Persistent Volume Claim, Storage Class

接下來的章節會更細部的去說明每個元件如何建立運作

Storage 在 k8s 的需求

在 k8s 叢集裡, 對於 storage 會有以下需求

1 Storage 不會被 Pod 的生命周期影響, 也就是與 Pod 不同生命周期

2 可以被所有結點都可以存取

3 需要能夠保存下來, 即使 k8s 叢集毀損

k8s 透過 PersistentVolume 元件來符合3個條件

Persistent Volume

Persistent Volume 是 k8s 設計來與實際 Storage 互動的介面

實體連接的類型可以是 k8s 叢集所在本機實體硬碟, 可以遠端的網路硬碟系統例如 nfs server, 或是雲端硬碟

使用 NFS storage 的設定檔案如下:

apiVersion: v1
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

使用 google cloud storage 設定如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-volume
  labels:
    failure-domain.beta.kubernetes.io/zone: us-central1-a__us-central1-b
spec:
  capacity:
    storage: 400Gi
  accessModes:
  - ReadWriteOnce
  gcePersistentDisk:
    pdName: my-data-disk
    fsType: ext4

而使用 local storage 的設定檔案如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node

可以看到, 關鍵在於 spec 部份

除了 capacity 設定是類似的

其他選項會根據實際連結的 Storage 不同而改變

k8s 支援的 Storage 可以在官網 查到

這邊不做細部解說

而關於 PersistentVolume 設定檔細節會鐵人30天後續的章節講到, 這邊只說概念性的講解

這邊要注意的是 PersistentVolume 不屬於 namespace 之內

所以基本上在 k8s 叢集, 所有 namespace 都可以存取的到 PersistentVolume 的資源

Local vs Remote Volume Types

把 k8s 支援的 Volume 類型把實連接的儲存實體是否在cluster本機來分

可分為 Local 跟 Remote

其中 Local 類的不符合一開始所說的 Storage 需求第2, 3項

因此如果要建制資料庫類的資料建議使用 Remote 類型較好

k8s Administrator & k8s User

k8s Administrator 負責架設 k8s 叢集, 並且負責維護 k8s 叢集的人

k8s User 指的是使用 k8s 叢集建立應用資源 ,發佈應用在 k8s 叢集上的人, 通常會是應用開發者

而 Storage 資源必須要在發佈應用之前就設定好, 因此建立 Storage 配置跟建制 PersistentVolume 是 k8s Administractor 的工作

PersistentVolumeClaim

這個元件是用來跟叢集宣告應用需要哪些 Storage 資源

以下是 PersistentVolumeClaim 的設定檔範例

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

一旦 PersistentVolumeClaim 設定好

k8s 叢集就會自動分配符合需求的 PersistentVolume 給那個使用對應 PersistentVolumeClaim 的 Pod

而在 Pod 設定檔裡可以指定要使用哪個 PersistentVolumeClaim

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

整個 Volume 對應流程如下圖:

特別要注意的是 Pod 跟 PersistentVolumeClaim 需要在同一個 Namespace

而 PersistentVolume 則是叢集內的全域物件

二階段的掛載

從以下的設定檔

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

可以知道掛載的部份

分為兩個階段

第一階段, 透過 PersistentVolumeClaim 的名稱 pvc-name

k8s 叢集會把 Volume 掛載到 Pod

第二階段, 在 Container 的 volumeMount 透過名稱 mypd

k8s 叢集會把掛載到 Pod 的 Volume 掛載到 Container 上

把 Volume 做抽象分層的好處

對開發應者來說, 可以專注在應用層的開發, 不需要去擔憂 Storage 的來源或是設定

只要在應用端寫出應用所需的 Storage 資源給 k8s 資源及可

ConfigMap 以及 Secret

在前面有提過這兩個元件

這兩個元件屬於 Local Volume

而不是透過 PersistentVolume 與 PersistentVolumeClaim 產生出來的

由 k8s 叢集自行管理

對於 prometheus 這類需要設定檔跟機敏資料檔的應用

假設需要一個在運行去時去存取

就是使用 ConfigMap 跟 Secret

然後掛載到 Pod 跟 Container 內

而掛載範例如下:

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

另外, 可以同時在一個同時使用多種類型的 Volume

Storage Class

如前面所述, 每當 k8s User 需要 Storage

需要跟 k8s Administractor 去要求開出需要的 PersistentVolume

給次都要這樣做會變成很煩瑣的過程

因此, k8s 提供一個選項 Storage Class

讓 PersistentVolume 能夠動態新增當 k8s User 發出 PersistentVolumeClaim 時

以下是 StorageClass 的範例

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: storage-class-name
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4

注意的是 provisioner 是代表 Storage 的後台伺服器

每個 Storage 後台服務都有屬於自己的 provisioner, 可以查詢k8s 官網文件

當有 PersistentVolumeClaim 發出時, StorageClass 就會跟 provisioner 發請求新增 PersistentVolume

provisioner 分為兩種一種是 internal provisioner(只要是 kubernete.io 開頭的)

另一種則是 external provisioner

parameter 部份則是對於 storage 的一些需求規格

StorageClass 使用範例

基本上會在 PersistentVolumeClaim 宣告

範例如下:

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

實際運作flow 如下圖:


上一篇
IT 鐵人賽 k8s 入門30天 -- day11 Helm - Package Manager
下一篇
IT 鐵人賽 k8s 入門30天 -- day13 Deploying Stateful Apps with StatefulSet
系列文
k8s 入門學習 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言