Kubernetes 挂载 nfs 卷时出现权限被拒绝的问题

9
以下是使用的k8s定义:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pv-provisioning-demo
  labels:
    demo: nfs-pv-provisioning
spec:
  accessModes: [ "ReadWriteOnce" ]
  resources:
    requests:
      storage: 200Gi
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: nfs-server
spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 2000
  replicas: 1
  selector:
    role: nfs-server
  template:
    metadata:
      labels:
        role: nfs-server
    spec:
      containers:
      - name: nfs-server
        image: k8s.gcr.io/volume-nfs:0.8
        ports:
          - name: nfs
            containerPort: 2049
          - name: mountd
            containerPort: 20048
          - name: rpcbind
            containerPort: 111
        securityContext:
          privileged: true
        volumeMounts:
          - mountPath: /exports
            name: mypvc
      volumes:
        - name: mypvc
          persistentVolumeClaim:
            claimName: nfs-pv-provisioning-demo
---
kind: Service
apiVersion: v1
metadata:
  name: nfs-server
spec:
  ports:
    - name: nfs
      port: 2049
    - name: mountd
      port: 20048
    - name: rpcbind
      port: 111
  selector:
    role: nfs-server
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    # FIXME: use the right IP
    server: nfs-server
    path: "/"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 1Gi
---
# This mounts the nfs volume claim into /mnt and continuously
# overwrites /mnt/index.html with the time and hostname of the pod.

apiVersion: v1
kind: ReplicationController
metadata:
  name: nfs-busybox
spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 2000
  replicas: 2
  selector:
    name: nfs-busybox
  template:
    metadata:
      labels:
        name: nfs-busybox
    spec:
      containers:
      - image: busybox
        command:
          - sh
          - -c
          - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'
        imagePullPolicy: IfNotPresent
        name: busybox
        volumeMounts:
          # name must match the volume name below
          - name: nfs
            mountPath: "/mnt"
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: nfs

现在,根据文档,nfs-busybox中的/mnt目录应该具有2000作为gid。但是它仍然将root和root作为用户和组。由于应用程序正在使用1000/2000运行,因此无法在/mnt目录中创建任何日志或数据。
chmod可能可以解决此问题,但它似乎只是一个解决方法。是否有任何永久解决方案?
观察结果:如果我将nfs替换为其他PVC,则按照文档所述正常工作。

你可以添加一个运行 chmod 的 init 容器。 - Norbert
抱歉,那只是一条评论(关于复制控制器过时的问题),并不是答案。实际上,chmod能解决这个问题吗? - suren
2个回答

7
你尝试过使用initContainers方法吗?它可以修复导出目录的权限问题: (链接)
initContainers:
    - name: volume-mount-hack
      image: busybox
      command: ["sh", "-c", "chmod -R 777 /exports"]
      volumeMounts:
      - name: nfs
        mountPath: /exports 

如果你在Linux服务器上使用独立的NFS服务器,我建议使用no_root_squash选项: /exports *(rw,no_root_squash,no_subtree_check) 为了管理nfs服务器上的目录权限,需要更改安全上下文并将其提升到特权模式:
apiVersion: v1
kind: Pod
metadata:
  name: nfs-server
  labels:
    role: nfs-server
spec:
  containers:
    - name: nfs-server
      image: nfs-server
      ports:
        - name: nfs
          containerPort: 2049
      securityContext:
        privileged: true

1
我用两种不同的方法解决了这个问题:
1/ 将卷挂载到用户的主目录,并使用最低权限模型来设置安全上下文。
mountPath: /home/<nfsuser>

安全上下文如下
containers:
- name: evmosnode
  securityContext:
    runAsUser: 1000  #nfs user id
    runAsGroup: 1000 #nfs user group id 
    allowPrivilegeEscalation: false
    capabilities:
      drop:
      - ALL
    privileged: false
    readOnlyRootFilesystem: true
    runAsNonRoot: true

2/ 以root身份运行容器,并切换所有安全上下文的标志。 出于安全原因,这显然是不推荐的,但它允许访问mountPath /mydir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接