iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
DevOps

今天不學遺傳學,跟著Kubernetes種豌豆系列 第 11

Day11. 資料不能亡,持久性儲存- Volume(上)

  • 分享至 

  • xImage
  •  

📂 容器的文件僅暫存在磁碟,與容器共進退,kubelet重啟容器時,總會是全新狀態 (把先前的事忘光);而且容器之間的資料共享也不好處理,此時,數據卷 (Volume)出現了,專門解決持久性及集中儲存的問題

Volume設計可以給pod內的所有容器存取,並且能同時使用多種類型的volume,如可以使用臨時性卷 (Ephemeral volume)類型,資料將隨著pod的生命週期生滅,或是使用持久性卷 (persistent volume)類型,則資料能持久保存,但不管是哪一種volume,即使容器重啟,資料都還是會被留存下來,Volume的寫法如下示:

apiVersion: v1
kind: Pod
metadata:
  name: random-number-generator
spec:
  containers:
  - image: alpine
    name: alpine
    command: ["/bin/sh","-c"]
    args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
    # volume要從容器的此位置接資料
    volumeMounts:
    - mountPath: /var/www/html
      # 取用的volume
      name: data-volume
      # 進一步指定子路徑
      subPath: html
  # 使用的volume
  volumes:
   - name: data-volume
     hostPath:
       path: /data
       type: Directory

volume的種類(列舉部分)

  • configMap: 儲存參數,資料能被引用於volume,讓pod內運行的容器使用,注意須先建立configmap,並為readOnly
  • secret: 同上,不過是敏感性的參數
  • emptyDir: 當pod被分配到node的時候,將建立volume,顧名思義在最開始內容為empty,在pod當中,volume可以錨定於各自容器的不同位置,當pod移除,資料就會移除
    • 屬於Ephemeral volume類型,用在暫時性儲存的情境
    • emptyDir.medium: 指定儲存的位置,像是磁碟或SSD,設定為Memory時,則會錨定在tmpfs (RAM-backed filesystem),速度優先
    • emptyDir.sizeLimit: 使用預設medium時設定限制用量
    • # 取自官網文件
      apiVersion: v1
      kind: Pod
      metadata:
        name: test-pd
      spec:
        containers:
        - image: registry.k8s.io/test-webserver
          name: test-container
          # 錨定於容器當中的路徑
          volumeMounts:
          - mountPath: /cache
            name: cache-volume
        # volumes及其類型設定
        volumes:
        - name: cache-volume
          emptyDir:
            sizeLimit: 500Mi
      
  • hostPath: 錨定host node的檔案系統到pod,非最推薦的解法,不過至少能和容器端的data的儲存解耦合,由於安全性問題,像是系統權限、不同node的檔案內容不同 (但預期相同...),而且非暫存性質,可能導致資源壓力,應避免使用
    • 使用情境像是容器需存取node-level的資訊或像static pod不能使用configmap,就要從node這邊拿配置檔案
    • hostPath volume types (列舉部分)
      • "" (預設): 在錨定前不做檢查
      • Directory: 目錄必須存在於指定path
      • DirectoryOrCreate: 不存在的話就自己建,權限設定為0755 (使用者讀寫執行、群組及其它用戶讀寫,和kubelet的group和所有權 (ownership)相同
      • File: 檔案必須存在於指定path
    • # 取自官網文件
      apiVersion: v1
      kind: Pod
      metadata:
        name: hostpath-example-linux
      spec:
        os: { name: linux }
        nodeSelector:
          kubernetes.io/os: linux
        containers:
        - name: example-container
          image: registry.k8s.io/test-webserver
          # 錨定於容器當中的路徑
          volumeMounts:
          - mountPath: /foo
            name: example-volume
            # 設定容器不可做write (非讓volume本身只能讀)
            readOnly: true
        # volumes及其類型設定
        volumes:
        - name: example-volume
          hostPath:
            path: /data/foo
            type: Directory
      
  • local: 錨定於本機的儲存裝置,像是磁碟、分割區或工作目錄,只能是靜態建立的PersistentVolume,不支援動態配置,相較於hostPath,為更加便攜的方案,不過這種類型的volume會受到node狀態影響而降低可用性
  • nfs: 錨定已存的NFS (network file system)到pod當中,資料可於不同的pods共享,並能被錨定到多個執行寫入者(writers)上,
    • 屬於persistent volume類型
    • 資料可以在錨定前事先存入
    • # 取自官網文件
      apiVersion: v1
      kind: Pod
      metadata:
        name: test-pd
      spec:
        containers:
        - image: registry.k8s.io/test-webserver
          name: test-container
          volumeMounts:
          - mountPath: /my-nfs-data
            name: test-volume
        volumes:
        - name: test-volume
          nfs:
            server: my-nfs-server.example.com
            path: /my-nfs-volume
            readOnly: true
      
  • persistentVolumeClaim: 下篇待續

有關Docker內儲存的小複習

多層結構及寫入時複製機制 layered architecture && copy on write
從image(1.)建立成container(+2.),若要修改image層的內容 (例如source code)時,Docker會在容器層建立副本,達成編輯功能,這些data非持久化保存,跟著容器的生命週期離去

  1. Read Only基底的映像檔層 (image layer)為共用不可變
  2. Read Write容器層 (container layer)為可讀寫

https://ithelp.ithome.com.tw/upload/images/20240815/20168178oStaoZcMtF.png

持久化儲存的錨定,於本機做Volume為例

  1. Docker於本機的檔案系統(file system)位於目錄 /var/lib/docker
  2. 建立Volume: docker volume create <名稱data-volume> 或直接在目錄下建立/var/lib/docker/volumes/<名稱data-volume>
  3. 錨定的方式
  • Volume mount: 以volume的目錄對接容器的目錄,存於檔案系統的Docker area,啟用容器時,<指定volume>:<容器檔案目錄>
    • 原寫法: docker run -v data_volume:/var/lib/mysql mysql
    • 新寫法(可讀性++): docker run --mount type-bind, source=/data/mysql,target=/var/lib/mysql mysql --volume-driver rexray/ebs
  • Bind mount: 以host任意的目錄對接容器的目錄,資料存於檔案系統
    • docker run -v /data/mysql:/var/lib/mysql mysql

上一篇
Day10. 集中管理配置參數,公開與不公開的秘密
下一篇
Day12. 資料不能亡,持久性儲存- PV與PVC(中)
系列文
今天不學遺傳學,跟著Kubernetes種豌豆30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言