지속적 스토리지에 루트가 아닌 사용자 액세스를 추가할 수 없는 이유는 무엇입니까?

클래식 인프라

루트 사용자가 아닌 사용자는 액세스 권한을 구성한 후에도 파일 저장소에 쓸 수 없습니다.

지속적 스토리지에 루트가 아닌 사용자 액세스를 추가하거나 지정된 루트가 아닌 사용자 ID로 Helm 차트를 배치한 후 사용자가 마운트된 스토리지에 쓸 수 없습니다.

앱 배포 또는 Helm 차트 구성은 파드의 fsGroup (그룹 ID) 및 runAsUser (사용자 ID)에 대한 보안 컨텍스트를 지정합니다. 일반적으로 팟(Pod)의 기본 보안 컨텍스트는 팟(Pod)을 루트 사용자로 실행할 수 없도록 runAsNonRoot를 설정합니다. fsGroup 설정은 NFS 파일 스토리지와 같은 공유 스토리지를 위해 설계된 경우가 아니므로 fsGroup 설정이 지원되지 않으며 runAsUser 설정이 자동으로 2020으로 설정됩니다. 이러한 기본 설정은 루트가 아닌 다른 사용자가 마운트된 스토리지에 쓰도록 허용하지 않습니다.

문제 해결

루트 사용자가 아닌 사용자가 파일 저장 장치에 대한 읽기 및 쓰기 액세스를 허용하려면, 스토리지 클래스에 추가 그룹 ID를 할당하고, PVC에서 이 스토리지 클래스를 참조하고, 추가 그룹 ID에 자동으로 추가되는 runAsUser 값으로 파드의 보안 컨텍스트를 설정해야 한다. 부가 그룹 ID에 파일 스토리지에 대한 읽기 및 쓰기 액세스 권한을 부여하는 경우, 팟(Pod)을 포함해 그룹 ID에 속한 루트가 아닌 사용자에게 파일 스토리지에 대한 액세스 권한이 부여됩니다.

제공된 gid 스토리지 클래스 중 하나를 사용하거나 자신만의 스토리지 클래스를 생성하여 추가 그룹 ID를 정의할 수 있습니다.

파일 스토리지 디바이스의 루트가 아닌 사용자에 대한 보충 그룹 ID 할당은 단일 구역 클러스터에 대해서만 지원되며 다중 구역 클러스터에 사용할 수 없습니다.

  1. 제공된 gid 스토리지 클래스 중 하나를 선택하여 기본 그룹 ID 65531을 파일 스토리지에 읽고 쓸 루트가 아닌 사용자에게 지정하십시오. 사용자 그룹 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. 작성한 PVC를 마운트하는 배치에 대한 YAML 파일을 작성하십시오. spec.template.spec.securityContext.runAsUser 필드에서 사용하려는 루트가 아닌 사용자 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)이 실행 중 상태인지 확인하십시오.

    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
    

루트가 아닌 사용자에 대한 읽기 및 쓰기 권한 확인

  1. 팟(Pod) 안에 있는 현재 사용자에 대한 사용자 ID와 그룹 ID를 나열하십시오. 루트가 아닌 사용자 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 출력에서, 작성한 파일에 대한 읽기 및 쓰기 액세스 권한과 함께 루트가 아닌 사용자 ID가 나열됩니다.

  5. 팟(Pod)을 종료하십시오.

    exit
    

마운트 경로의 소유권을 nobody에서 변경해야 하는 경우, 루트가 아닌 사용자가 NFS 파일 스토리지 마운트 경로를 소유하는 경우 앱이 실패함을 참조하십시오.