設定 Pod 以使用 PersistentVolume 進行儲存
此頁面說明如何設定 Pod 以使用 PersistentVolumeClaim 進行儲存。以下是流程摘要
您,作為叢集管理員,建立由實體儲存支援的 PersistentVolume。您不會將磁碟區與任何 Pod 關聯。
您,現在扮演開發人員/叢集使用者的角色,建立 PersistentVolumeClaim,它會自動繫結到合適的 PersistentVolume。
您建立一個 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"
注意
如果您的節點使用sudo
以外的工具進行超級使用者存取,如果您將 sudo
替換為其他工具的名稱,通常可以使其運作。測試 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。
注意
此範例為了簡化起見,使用ReadWriteOnce
存取模式。對於生產用途,Kubernetes 專案建議改用 ReadWriteOncePod
存取模式。建立 PersistentVolume
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
檢視關於 PersistentVolume 的資訊
kubectl get pv task-pv-volume
輸出顯示 PersistentVolume 的 STATUS
為 Available
。這表示它尚未繫結到 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
現在輸出顯示 STATUS
為 Bound
。
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 的規格,都會套用於每個容器中執行的第一個程序。