配置 Pod 使用持久捲進行儲存

本頁面展示瞭如何配置 Pod 以使用 PersistentVolumeClaim 進行儲存。以下是此過程的摘要:

  1. 你作為叢集管理員,建立一個由物理儲存支援的 PersistentVolume。你不會將該卷與任何 Pod 關聯。

  2. 你現在扮演開發人員/叢集使用者的角色,建立一個 PersistentVolumeClaim,它會自動繫結到一個合適的 PersistentVolume。

  3. 你建立一個使用上述 PersistentVolumeClaim 進行儲存的 Pod。

準備工作

  • 你需要有一個只有單個節點的 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。如果你還沒有單節點叢集,可以使用 Minikube 建立一個。

  • 熟悉 持久卷 中的內容。

在你的節點上建立一個 index.html 檔案

開啟與叢集中單節點的 shell。如何開啟 shell 取決於你如何設定叢集。例如,如果你正在使用 Minikube,可以透過輸入 minikube ssh 開啟與節點的 shell。

在你的節點上的 shell 中,建立一個 /mnt/data 目錄

# This assumes that your Node uses "sudo" to run commands
# as the superuser
sudo mkdir /mnt/data

/mnt/data 目錄中,建立一個 index.html 檔案

# This again assumes that your Node uses "sudo" to run commands
# as the superuser
sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"

測試 index.html 檔案是否存在

cat /mnt/data/index.html

輸出應該是

Hello from Kubernetes storage

你現在可以關閉與節點的 shell。

建立 PersistentVolume

在本練習中,你將建立一個 hostPath PersistentVolume。Kubernetes 支援 hostPath 用於單節點叢集上的開發和測試。hostPath PersistentVolume 使用節點上的檔案或目錄來模擬網路附加儲存。

在生產叢集中,你不會使用 hostPath。相反,叢集管理員會配置網路資源,例如 Google Compute Engine 持久磁碟、NFS 共享或 Amazon Elastic Block Store 卷。叢集管理員還可以使用 StorageClasses 設定動態供應

以下是 hostPath PersistentVolume 的配置檔案

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

配置檔案指定卷位於叢集節點的 /mnt/data。配置還指定了 10 Gibibytes 的大小和 ReadWriteOnce 的訪問模式,這意味著該卷可以由單個節點以讀寫方式掛載。它為 PersistentVolume 定義了 StorageClass 名稱 manual,該名稱將用於將 PersistentVolumeClaim 請求繫結到此 PersistentVolume。

建立 PersistentVolume

kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml

檢視 PersistentVolume 的資訊

kubectl get pv task-pv-volume

輸出顯示 PersistentVolume 的 STATUSAvailable。這意味著它尚未繫結到 PersistentVolumeClaim。

NAME             CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
task-pv-volume   10Gi       RWO           Retain          Available             manual                   4s

建立 PersistentVolumeClaim

下一步是建立 PersistentVolumeClaim。Pod 使用 PersistentVolumeClaim 請求物理儲存。在本練習中,你將建立一個 PersistentVolumeClaim,該宣告請求至少 3 Gibibytes 的卷,該卷可以為最多一個節點提供讀寫訪問許可權。

以下是 PersistentVolumeClaim 的配置檔案

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

建立 PersistentVolumeClaim

kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml

建立 PersistentVolumeClaim 後,Kubernetes 控制平面會查詢滿足宣告要求的 PersistentVolume。如果控制平面找到具有相同 StorageClass 的合適 PersistentVolume,它會將宣告繫結到該卷。

再次檢視 PersistentVolume

kubectl get pv task-pv-volume

現在輸出顯示 STATUSBound

NAME             CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM                   STORAGECLASS   REASON    AGE
task-pv-volume   10Gi       RWO           Retain          Bound     default/task-pv-claim   manual                   2m

檢視 PersistentVolumeClaim

kubectl get pvc task-pv-claim

輸出顯示 PersistentVolumeClaim 已繫結到你的 PersistentVolume,即 task-pv-volume

NAME            STATUS    VOLUME           CAPACITY   ACCESSMODES   STORAGECLASS   AGE
task-pv-claim   Bound     task-pv-volume   10Gi       RWO           manual         30s

建立一個 Pod

下一步是建立使用你的 PersistentVolumeClaim 作為卷的 Pod。

以下是 Pod 的配置檔案:

apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage


請注意,Pod 的配置檔案指定了 PersistentVolumeClaim,但未指定 PersistentVolume。從 Pod 的角度來看,宣告就是一個卷。

建立 Pod

kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml

驗證 Pod 中的容器是否正在執行

kubectl get pod task-pv-pod

獲取 Pod 中執行的容器的 shell

kubectl exec -it task-pv-pod -- /bin/bash

在你的 shell 中,驗證 nginx 是否正在從 hostPath 卷提供 index.html 檔案

# Be sure to run these 3 commands inside the root shell that comes from
# running "kubectl exec" in the previous step
apt update
apt install curl
curl https:///

輸出顯示你寫入 hostPath 捲上的 index.html 檔案的文字

Hello from Kubernetes storage

如果你看到該訊息,則表示你已成功配置 Pod 以使用 PersistentVolumeClaim 中的儲存。

清理

刪除 Pod

kubectl delete pod task-pv-pod

在兩個位置掛載相同的 PersistentVolume

你已經瞭解瞭如何建立 PersistentVolume 和 PersistentVolumeClaim,以及如何將卷掛載到容器中的單個位置。接下來我們來探討如何將同一個 PersistentVolume 掛載到容器中的兩個不同位置。以下是一個示例


apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test
      image: nginx
      volumeMounts:
        # a mount for site-data
        - name: config
          mountPath: /usr/share/nginx/html
          subPath: html
        # another mount for nginx config
        - name: config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
  volumes:
    - name: config
      persistentVolumeClaim:
        claimName: task-pv-storage

這裡

  • subPath:此欄位允許將掛載的 PersistentVolume 中的特定檔案或目錄公開到容器內的不同位置。在此示例中
    • subPath: html 掛載 html 目錄。
    • subPath: nginx.conf 掛載一個特定檔案,nginx.conf。

由於第一個 subPath 是 html,因此必須在節點上的 /mnt/data/ 中建立 html 目錄。

第二個 subPath nginx.conf 意味著將使用 /mnt/data/ 目錄中的檔案。無需建立其他目錄。

你的 nginx 容器將進行兩個卷掛載

  • /usr/share/nginx/html 用於靜態網站
  • /etc/nginx/nginx.conf 用於預設配置

將節點上的 index.html 檔案移動到一個新資料夾中

這裡提到的 index.html 檔案是指在“在你的節點上建立一個 index.html 檔案”部分建立的檔案。

開啟與叢集中單節點的 shell。如何開啟 shell 取決於你如何設定叢集。例如,如果你正在使用 Minikube,可以透過輸入 minikube ssh 開啟與節點的 shell。

建立一個 /mnt/data/html 目錄

# This assumes that your Node uses "sudo" to run commands
# as the superuser
sudo mkdir /mnt/data/html

將 index.html 移動到該目錄中

# Move index.html from its current location to the html sub-directory
sudo mv /mnt/data/index.html html

建立一個新的 nginx.conf 檔案

user  nginx;
worker_processes  auto;

error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;

events { worker_connections 1024; }

http { include /etc/nginx/mime.types; default_type application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
#tcp_nopush     on;

keepalive_timeout  60;

#gzip  on;

include /etc/nginx/conf.d/*.conf;

}

這是預設 nginx.conf 檔案的修改版本。在這裡,預設的 keepalive_timeout 已修改為 60

建立 nginx.conf 檔案

cat <<EOF > /mnt/data/nginx.conf
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  60;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
EOF

建立一個 Pod

在這裡,我們將建立一個使用現有 persistentVolume 和 persistentVolumeClaim 的 Pod。但是,Pod 只將特定檔案 nginx.conf 和目錄 html 掛載到容器。

建立 Pod

kubectl apply -f https://k8s.io/examples/pods/storage/pv-duplicate.yaml

驗證 Pod 中的容器是否正在執行

kubectl get pod test

獲取 Pod 中執行的容器的 shell

kubectl exec -it test -- /bin/bash

在你的 shell 中,驗證 nginx 是否正在從 hostPath 卷提供 index.html 檔案

# Be sure to run these 3 commands inside the root shell that comes from
# running "kubectl exec" in the previous step
apt update
apt install curl
curl https:///

輸出顯示你寫入 hostPath 捲上的 index.html 檔案的文字

Hello from Kubernetes storage

在你的 shell 中,還要驗證 nginx 是否正在從 hostPath 卷提供 nginx.conf 檔案

# Be sure to run these commands inside the root shell that comes from
# running "kubectl exec" in the previous step
cat /etc/nginx/nginx.conf | grep keepalive_timeout

輸出顯示你寫入 hostPath 捲上的 nginx.conf 檔案的修改文字

keepalive_timeout  60;

如果你看到這些訊息,則表示你已成功配置 Pod 以使用 PersistentVolumeClaim 中的特定檔案和目錄進行儲存。

清理

刪除 Pod

kubectl delete pod test
kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume

如果你還沒有開啟與叢集中節點的 shell,請按照之前的方式開啟一個新的 shell。

在節點上的 shell 中,刪除你建立的檔案和目錄

# This assumes that your Node uses "sudo" to run commands
# as the superuser
sudo rm /mnt/data/html/index.html
sudo rm /mnt/data/nginx.conf
sudo rmdir /mnt/data

你現在可以關閉與節點的 shell。

訪問控制

配置了組 ID(GID)的儲存僅允許使用相同 GID 的 Pod 進行寫入。GID 不匹配或缺失會導致許可權拒絕錯誤。為了減少與使用者協調的需要,管理員可以使用 GID 註釋 PersistentVolume。然後,GID 會自動新增到使用該 PersistentVolume 的任何 Pod 中。

按如下方式使用 pv.beta.kubernetes.io/gid 註釋

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
  annotations:
    pv.beta.kubernetes.io/gid: "1234"

當 Pod 使用具有 GID 註釋的 PersistentVolume 時,註釋的 GID 將以與 Pod 的安全上下文中指定的 GID 相同的方式應用於 Pod 中的所有容器。每個 GID,無論是來自 PersistentVolume 註釋還是 Pod 規範,都將應用於每個容器中執行的第一個程序。

下一步

參考

上次修改時間:2024 年 12 月 17 日太平洋標準時間上午 5:46:改進 PV 儲存任務 (f31a75226e)