在 K8S Volume 中使用 subPath

2023-01-11 12:00:17

使用 subPath

有時,在單個 Pod 中共用卷以供多方使用是很有用的。 volumeMounts.subPath 屬性可用於指定所參照的卷內的子路徑,而不是其根路徑。

下面是一個使用同一共用卷的、內含 LAMP 棧(Linux Apache Mysql PHP)的 Pod 的範例。 HTML 內容被對映到卷的 html 資料夾,資料庫將被儲存在卷的 mysql 資料夾中:

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      env:
      - name: MYSQL_ROOT_PASSWORD
        value: "rootpasswd"
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php:7.0-apache
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

對上面的設定進行說明:

  1. volumeMounts 下面的name, 就是分配給這個pod的volume的名字site-data, mysql和php的html分別使用了它的子路徑: mysqlhtml
  2. volumes 對於site-data這個volume, 是通過PVC的形式提供的, PVC的name為: my-lamp-site-data

使用帶有擴充套件環境變數的 subPath

FEATURE STATE: Kubernetes v1.15 feature-state-beta.txt

使用 subPathExpr 欄位從 Downward API 環境變數構造 subPath 目錄名。 在使用此特性之前,必須啟用 VolumeSubpathEnvExpansion 功能開關。 subPathsubPathExpr 屬性是互斥的。

在這個示例中,Pod 基於 Downward API 中的 Pod 名稱,使用 subPathExpr 在 hostPath 卷 /var/log/pods 中建立目錄 pod1。 主機目錄 /var/log/pods/pod1 掛載到了容器的 /logs 中。

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: container1
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    image: busybox
    command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
    volumeMounts:
    - name: workdir1
      mountPath: /logs
      subPathExpr: $(POD_NAME)
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods

說明:

  1. env中, 設定了POD_NAME這個環境變數, 這個變數的值來自於metadata.name, 即pod1
  2. subPathExpr: $(POD_NAME) 子路徑為$(POD_NAME)這個變數, 就是pod1
  3. volume用的是hostPath, 實際路徑為:/var/log/pods. 那麼完整的path就是/var/log/pods/pod1

總結

subPath 還是挺實用的, 是個小功能, 但是確實能提交效率. 比如我昨天搭建的禪道的容器. 就是典型的LAMP: Linux + Apache + Mysql + PHP.

這些元件中,

  • Apachewww/html需要掛載
  • mysql的資料庫需要掛載
  • php的應用資料需要掛載

如果沒用subPath, 那麼我得這麼操作: (以nfs為例)

  1. nfs下手動建立3個子目錄: html  mysql php
  2. 建立3個PV, 分別為: apache-volume mysql-volume php-volume
  3. 寫3個PVC, 分別是: apache-claim mysql-claim php-claim. 而且2和3這兩步最好一個pv+一個PVC來建. 避免bound亂了.
  4. 再修改Deployment 設定, 一個個掛載上去.

△ 算下來,10步.

用了subPath, 確實節省了工作量: (還是以nfs為例)

  1. 建立1個PV, 為: LAMP-volume
  2. 建立1個PVC, 為: LAMP-claim
  3. 再修改Deployment 設定, 掛載一個PVC, 用subPath區分.

△ 算下來, 3步.

三人行, 必有我師; 知識共用, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.