設定 Pod 以使用 PersistentVolume 進行儲存

此頁面說明如何設定 Pod 以使用 PersistentVolumeClaim 進行儲存。以下是流程摘要

  1. 您,作為叢集管理員,建立由實體儲存支援的 PersistentVolume。您不會將磁碟區與任何 Pod 關聯。

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

  3. 您建立一個 Pod,該 Pod 使用上述 PersistentVolumeClaim 進行儲存。

開始之前

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

  • 熟悉 Persistent Volumes 中的資料。

在您的節點上建立 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 GiB 的大小和 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 GiB 的磁碟區,該磁碟區可以為最多一個節點提供讀寫存取權。

以下是 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

下一步是建立一個 Pod,將您的 PersistentVolumeClaim 用作磁碟區。

以下是 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 http://localhost/

輸出顯示您寫入到 hostPath 磁碟區上的 index.html 檔案的文字

Hello from Kubernetes storage

如果您看到該訊息,則表示您已成功設定 Pod 以使用來自 PersistentVolumeClaim 的儲存體。

清理

刪除 Pod、PersistentVolumeClaim 和 PersistentVolume

kubectl delete pod task-pv-pod
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/index.html
sudo rmdir /mnt/data

您現在可以關閉節點的 Shell。

在兩個位置掛載相同的 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: test-nfs-claim

您可以在您的 nginx 容器上執行 2 個磁碟區掛載

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

存取控制

使用群組 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 的規格,都會套用於每個容器中執行的第一個程序。

下一步

參考

上次修改時間:2023 年 10 月 10 日 早上 7:55 PST:Graduate ReadWriteOncePod to GA (c07ce392e4)