為何無法將非 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,且無法在多區域叢集裡使用。

  1. 選取其中一個 提供的 gid 儲存空間類別,以將預設群組 ID 65531 指派給您要讀取及寫入檔案儲存空間的非 root 使用者。 如果您要指派自訂群組 ID,請為自訂儲存空間類別建立 YAML 檔。 在自訂的儲存空間類別 YAML 檔案中,包括 gidAllocate: "true" 參數,並在 gidFixed 參數中定義群組 ID。

    指定預設群組 ID 的儲存類別範例 65531

    • ibmc-file-bronze-gid
    • ibmc-file-silver-gid
    • ibmc-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

  2. 為 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
    
  3. 在叢集裡建立 PVC。

    kubectl apply -f pvc.yaml
    
  4. 等待幾分鐘,讓檔案儲存空間佈建及 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
    
  5. 為部署建立 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
    
  6. 在叢集裡建立部署。

    kubectl apply -f deployment.yaml
    
  7. 確認您的 pod 處於 Running 狀態。

    kubectl get pods
    

    輸出範例:

    NAME                              READY   STATUS    RESTARTS   AGE
    gid-deployment-5dc86db4c4-5hbts   2/2     Running   0          69s
    
  8. 登入 Pod。

    kubectl exec <pod_name> -it -- bash
    

驗證非 root 使用者的讀取及寫入權

  1. 列出 Pod 內現行使用者的使用者 ID 及群組 ID。 如果您的非 root 使用者 ID 列為 uid,且您在儲存類別中定義的增補群組 ID 列在 groups 下,則設定正確。

    id
    

    輸出範例:

    uid=2020 gid=0(root) groups=0(root), 65531
    
  2. 列出您在部署中定義之磁區裝載目錄的許可權。 如果您在儲存空間類別中定義的增補群組 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 ..
    
  3. 在您的掛載目錄中建立一個檔案。

    echo "Able to write to file storage with my non-root user." > /myvol/gidtest.txt
    
  4. 列出磁區裝載目錄中檔案的許可權。

    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,並具有您所建立檔案的讀取及寫入權。

  5. 結束 pod。

    exit
    

如果您需要從 nobody 變更掛載路徑的擁有權,請參閱 當非 root 使用者擁有 NFS 檔案儲存掛載路徑時,App 會失敗