¿Por qué no puedo añadir acceso de usuario no root al almacenamiento persistente?

Infraestructura clásica

Los usuarios no root no pueden escribir en el almacenamiento de archivos incluso después de configurar los permisos de acceso.

Si añade un acceso de usuario no root al almacenamiento persistente o despliega un diagrama de Helm con un ID de usuario no root especificado, el usuario no puede escribir en el almacenamiento montado.

La configuración del despliegue de su aplicación o del gráfico Helm especifica el contexto de seguridad para los pods fsGroup (ID de grupo) y runAsUser (ID de usuario). Generalmente, el contexto de seguridad predeterminado de un pod establece runAsNonRoot para que el pod no pueda ejecutarse como el usuario root. Como el valor fsGroup no está diseñado para almacenamiento compartido, como el almacenamiento de archivos NFS, el valor fsGroup no recibe soporte y el valor runAsUser se establece automáticamente en 2020. Estos valores predeterminados no permiten que otros usuarios no root escriban en el almacenamiento montado.

Resolución del problema

Para permitir a un usuario no root el acceso de lectura y escritura a un dispositivo de almacenamiento de archivos, debe asignar un ID de grupo suplementario en una clase de almacenamiento, hacer referencia a esta clase de almacenamiento en el PVC y establecer el contexto de seguridad del pod con un valor runAsUser que se añade automáticamente al ID de grupo suplementario. Cuando otorga al ID de grupo complementario acceso de lectura y de escritura sobre el almacenamiento de archivos, cualquier usuario no root que pertenezca al ID de grupo, incluido su pod, recibe acceso sobre el almacenamiento de archivos.

Puede utilizar uno de los gid clases de almacenamiento proporcionados o crear su propia clase de almacenamiento para definir su propio ID de grupo suplementario.

La asignación de un ID de grupo suplementario para un usuario no root de un dispositivo de almacenamiento de archivos solo está soportada para clústeres de zona única y no se puede utilizar en clústeres multizona.

  1. Seleccione una de las clases de almacenamiento gid proporcionadas para asignar el ID de grupo predeterminado 65531 al usuario no root del que desea leer, y escribir en, el almacenamiento de archivos. Si desea asignar un ID de grupo personalizado, cree un archivo YAML para una clase de almacenamiento personalizada. En el archivo YAML de la clase de almacenamiento personalizada, incluya el parámetro gidAllocate: "true" y defina el ID de grupo en el parámetro gidFixed.

    Ejemplo de clases de almacenamiento para asignar el ID de grupo por defecto 65531:

    • ibmc-file-bronze-gid
    • ibmc-file-silver-gid
    • ibmc-file-gold-gid

    Ejemplo de clase de almacenamiento personalizada para especificar un ID de grupo diferente:

    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"
    

    Para crear la clase de almacenamiento en el clúster, ejecute kubectl apply -f storageclass.yaml.

  2. Cree un archivo YAML para la PVC que utilice la clase de almacenamiento que ha creado.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: gid-pvc
      labels:
        billingType: "monthly"
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 20Gi
      storageClassName: ibmc-file-bronze-gid
    
  3. Cree la PVC en el clúster.

    kubectl apply -f pvc.yaml
    
  4. Espere unos minutos hasta que se suministre el almacenamiento de archivos y el estado de la PVC sea Bound.

    Si creó el PVC en un clúster multizona, el PVC permanece en estado pending.

    kubectl get pvc
    

    Salida de ejemplo:

    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. Cree un archivo YAML para el despliegue que monte la PVC que ha creado. En el campo spec.template.spec.securityContext.runAsUser, especifique el ID de usuario no root que desee utilizar. Este ID de usuario se añade automáticamente al ID de grupo complementario definido en la clase de almacenamiento para obtener acceso de lectura y de escritura sobre el almacenamiento de archivos.

    Ejemplo de creación de un despliegue 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. Cree el despliegue en el clúster.

    kubectl apply -f deployment.yaml
    
  7. Compruebe que el estado del pod sea Running.

    kubectl get pods
    

    Salida de ejemplo:

    NAME                              READY   STATUS    RESTARTS   AGE
    gid-deployment-5dc86db4c4-5hbts   2/2     Running   0          69s
    
  8. Inicie una sesión en el pod.

    kubectl exec <pod_name> -it -- bash
    

Verificar los permisos de lectura y escritura para el usuario no root

  1. Obtenga una lista del ID de usuario y de los ID de grupo para el usuario actual en el pod. La configuración es correcta si el ID de usuario no root aparece como uid y el ID de grupo complementario que ha definido en la clase de almacenamiento aparece bajo groups.

    id
    

    Salida de ejemplo:

    uid=2020 gid=0(root) groups=0(root), 65531
    
  2. Obtenga una lista de los permisos correspondientes a su directorio de montaje de volumen que ha definido en el despliegue. La configuración es correcta si el ID de grupo complementario que ha definido en la clase de almacenamiento se muestra con permisos de lectura y escritura en el directorio de montaje del volumen.

    ls -l /<volume_mount_path>
    

    Salida de ejemplo:

    drwxrwxr-x 2 nobody 65531 4096 Dec 11 07:40 .
    drwxr-xr-x 1 root   root  4096 Dec 11 07:30 ..
    
  3. Cree un archivo en el directorio de montaje.

    echo "Able to write to file storage with my non-root user." > /myvol/gidtest.txt
    
  4. Obtenga una lista de los permisos correspondientes a los archivos del directorio de montaje del volumen.

    ls -al /myvol/
    

    Salida de ejemplo:

    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 .
    

    En la salida de la CLI, el ID de usuario no root aparece con acceso de escritura y lectura sobre el archivo que ha creado.

  5. Salga del pod.

    exit
    

Si tiene que cambiar la propiedad de la vía de acceso de montaje, nobody, consulte La app falla cuando un usuario no root es propietario de la vía de acceso de montaje del almacenamiento de archivos NFS.