為何無法將非 root 使用者存取權新增至持續性儲存空間?
經典基礎架構
即使設定存取權限後,非根使用者仍無法寫入檔案儲存空間。
在您 新增非 root 使用者存取持久性儲存 或部署 Helm 圖表並指定非 root 使用者 ID 之後,使用者就無法寫入掛載的儲存。
您的應用程式部署或 Helm 圖配置會指定 Pod 的 fsGroup (群組 ID) 和 runAsUser (使用者 ID) 的 安全上下文。 通常,Pod 的預設安全環境定義會設定
runAsNonRoot,以便 Pod 無法以 root 使用者身分執行。 由於 fsGroup 設定並非專為共用儲存而設計,例如 NFS 檔案儲存,因此不支援 fsGroup 設定,而 runAsUser 設定會自動設定為 2020。 這些預設值不容許其他非 root 使用者寫入已裝載的儲存體。
解決問題
若要容許非 root 使用者對檔案儲存裝置的讀取及寫入權,您必須在儲存類別中配置 增補群組 ID,在 PVC 中參照此儲存類別,並使用自動新增至增補群組 ID 的 runAsUser 值來設定 Pod 的安全環境定義。 當您授與增補群組
ID 對檔案儲存空間的讀取及寫入權時,任何屬於該群組 ID 的非 root 使用者 (包括您的 Pod) 都會被授與檔案儲存空間的存取權。
您可以使用其中一個提供的 gid 儲存空間類別,或建立您自己的儲存空間類別來定義您自己的增補群組 ID。
僅單一區域叢集支援為檔案儲存裝置的非 root 使用者配置增補群組 ID,且無法在多區域叢集裡使用。
-
選取其中一個 提供的
gid儲存空間類別,以將預設群組 ID65531指派給您要讀取及寫入檔案儲存空間的非 root 使用者。 如果您要指派自訂群組 ID,請為自訂儲存空間類別建立 YAML 檔。 在自訂的儲存空間類別 YAML 檔案中,包括gidAllocate: "true"參數,並在gidFixed參數中定義群組 ID。指定預設群組 ID 的儲存類別範例
65531:ibmc-file-bronze-gidibmc-file-silver-gidibmc-file-gold-gid
範例自訂儲存類別,指定不同的群組 ID:
apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: ibmc-file-bronze-gid-custom labels: kubernetes.io/cluster-service: "true" provisioner: ibm.io/ibmc-file parameters: type: "Endurance" iopsPerGB: "2" sizeRange: "[1-12000]Gi" mountOptions: nfsvers=4.1,hard billingType: "hourly" reclaimPolicy: "Delete" classVersion: "2" gidAllocate: "true" gidFixed: "65165"若要在叢集裡建立儲存空間類別,請執行
kubectl apply -f storageclass.yaml。 -
為 PVC 建立使用您所建立儲存空間類別的 YAML 檔案。
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: gid-pvc labels: billingType: "monthly" spec: accessModes: - ReadWriteMany resources: requests: storage: 20Gi storageClassName: ibmc-file-bronze-gid -
在叢集裡建立 PVC。
kubectl apply -f pvc.yaml -
等待幾分鐘,讓檔案儲存空間佈建及 PVC 變更為
Bound狀態。如果您在多區群集中建立 PVC,則 PVC 會保持在
pending狀態。kubectl get pvc輸出範例:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE gid-pvc Bound pvc-5e4acab4-9b6f-4278-b53c-22e1d3ffa123 20Gi RWX ibmc-file-bronze-gid 2m54s -
為部署建立 YAML 檔案,以裝載您所建立的 PVC。 在
spec.template.spec.securityContext.runAsUser欄位中,指定您要使用的非 root 使用者 ID。 此使用者 ID 會自動新增至儲存類別中定義的增補群組 ID,以取得檔案儲存體的讀取及寫入權。建立
node-hello部署的範例:apiVersion: apps/v1 kind: Deployment metadata: name: gid-deployment labels: app: gid spec: selector: matchLabels: app: gid template: metadata: labels: app: gid spec: containers: - image: gcr.io/google-samples/node-hello:1.0 name: gid-container volumeMounts: - name: gid-vol mountPath: /myvol securityContext: runAsUser: 2020 volumes: - name: gid-vol persistentVolumeClaim: claimName: gid-pvc -
在叢集裡建立部署。
kubectl apply -f deployment.yaml -
確認您的 pod 處於 Running 狀態。
kubectl get pods輸出範例:
NAME READY STATUS RESTARTS AGE gid-deployment-5dc86db4c4-5hbts 2/2 Running 0 69s -
登入 Pod。
kubectl exec <pod_name> -it -- bash
驗證非 root 使用者的讀取及寫入權
-
列出 Pod 內現行使用者的使用者 ID 及群組 ID。 如果您的非 root 使用者 ID 列為
uid,且您在儲存類別中定義的增補群組 ID 列在groups下,則設定正確。id輸出範例:
uid=2020 gid=0(root) groups=0(root), 65531 -
列出您在部署中定義之磁區裝載目錄的許可權。 如果您在儲存空間類別中定義的增補群組 ID 在磁區裝載目錄中列出時具有讀取及寫入權,則設定正確。
ls -l /<volume_mount_path>輸出範例:
drwxrwxr-x 2 nobody 65531 4096 Dec 11 07:40 . drwxr-xr-x 1 root root 4096 Dec 11 07:30 .. -
在您的掛載目錄中建立一個檔案。
echo "Able to write to file storage with my non-root user." > /myvol/gidtest.txt -
列出磁區裝載目錄中檔案的許可權。
ls -al /myvol/輸出範例:
drwxrwxr-x 2 nobody 65531 4096 Dec 11 07:40 . drwxr-xr-x 1 root root 4096 Dec 11 07:30 .. -rw-r--r-- 1 2020 4294967294 42 Dec 11 07:40 gidtest.txt .在 CLI 輸出中,會列出非 root 使用者 ID,並具有您所建立檔案的讀取及寫入權。
-
結束 pod。
exit
如果您需要從 nobody 變更掛載路徑的擁有權,請參閱 當非 root 使用者擁有 NFS 檔案儲存掛載路徑時,App 會失敗。