问题背景:不同于常规k8s的statefulset,我们没有创建pv,在statefulset的yaml文件里没有使用volumeClaimTemplates声明PVC的模板,而是直接使用的volumes搭配hostpath的方式,使用的宿主机的存储卷(宿主机的存储卷目录已经挂载到nas的nfs共享卷)。
statefulset.yaml的volume字段(完整的yaml文件会在文章附录中贴出来):

apiVersion: apps/v1
kind: StatefulSet
      ...
      volumes:
      - name: postgres-volume
        hostPath:
          path: /mnt
      - name: cgwire-volume
        hostPath:
          path: /mnt

问题描述:我们的实验需要在pod里面启动一个postgresql容器,在postgresql的dockerfile里面需要执行一个指令:

chown -R postgres:postgres /var/lib/postgresql

postgresql想修改挂载目录/mnt里面一个文件的owner和group,但是nfs共享文件夹不让给他权限,pod内的postgresql容器报错:

chown  /var/lib/postgresql :Permission denied

以上就是错误信息,我们是用root身份在运行整个流程为什么我们会没有权限执行chown,我们通过命令查看statefulset被调度到的哪个节点,我们去那个节点的挂载目录/mnt下查看文件的所属用户和组,具体如下:
在这里插入图片描述
我们可以看到文件的所属用户为nfsnobody,root用户被压缩成了匿名使用者nfsnobody,难怪没有权限,这是怎么回事?我权限呢?通过查询资料我们发现,其实nfs在用户映射方面是有自己的一套操作的,nfs会识别你登陆进nfs的用户信息,是root啊?还是普通用户啊?然后进行映射,映射成nfs内部用户,很显然,我没有进行任何配置映射规则的操作,结果,被nfs映射成了nfsnobody(普通用户,权限最低的普通用户,防止黑客恶意攻击的一种手段)。
知道了原因,我们就可以想办法解决了,通过查询,我们查询到了以下方法:
①挂载时指定mount的版本。
步骤:
加上vers=3,指定使用mount v3 版本进行挂载,例:

mount -t nfs -o vers=3 server:/share /mnt

②修改映射规则。
步骤:
1 先在挂载nfs共享的节点上umount /mnt

umount /mnt

注:如果umount时出现了“device is busy”和“Stale file handle”,点击此链接可能会有帮助。
2 然后在nfs server上修改/etc/exports文件,添加no_root_squash,修改如下:

/mnt  *(rw,no_root_squash,sync)
#*的意思是对所有连接过来的用户都执行此操作

分析:
用户对目录的权限受两方面的约束:NFS认证约束、Posix权限
NFS权限
NFS服务器中的exports中可以配置读写,只读权限。
Posix权限
exports目录权限中,参数no_root_squash作用是:NFS客户端使用共享目录的用户,如果是root用户的话,所有的操作均在服务端映射为root用户,拥有共享目录的root权限
默认情况下使用的时相反的参数root_squash:在登入NFS主机的export目录的使用者如果是root时,那么这个使用者的权限将被压缩成匿名使用者,通常他的UID和GID都会变成nobody那个身份(因为之前我们的客户端是用root登录的,自然权限被压缩成nobody了,难怪无法chown)。
3 重新加载业务
exportfs -arv
4 重新将nfs挂载到/mnt文件夹尝试是否可以chown。

#指定v3的方法 
mount -t nfs -o vers=3 server:/share /mnt

例:mount -t nfs -o vers=3 192.168.1.5:/mnt/pool0/hpc /mnt
:也有可能是selinux的问题
关闭selinux(我是使用的关闭selinux的方法)或者在selinux添加规则,修改挂载目录(我没有做,读者可以自行尝试一下)

关闭selinux
修改/etc/sysconfig/selinux

SELINUX=disabled

还要临时关闭selinux

setenforce 0

关于nfs用户权限的问题修改可以点此了解更详细的内容

但是,我使用的nas服务器,以上的方法对我的没有权限问题都不奏效,所以说如果写的不到位,还请指教。
在关于nas服务器,我找到了一种解决方法,就是:
在这里插入图片描述
这种设置以后,会在nas服务器的/etc/exports文件上追加一条指令。
刚开始是这样:

/mnt/pool0/hpc

修改了映射规则后是这样:

/mnt/pool0/hpc -mapall="root":"wheel"

追加了一条映射指令。
我们重新挂载/mnt,然后常见文件查看nfs文件夹内创建的文件的所属用户和所属组:
我们执行statefulset的yaml文件后,nas上的nfs共享文夹/mnt/pool0/hpc同步过来的文件:
在这里插入图片描述
全是root和wheel组,没问题。
节点上挂载nfs的/mnt文件夹内的情况:
在这里插入图片描述
没问题,已经修改成了postgres的专属的所属用户,这证明chown也可以使用了。
总结:
最开始介绍的方法,我都用过,但是没有成功,最后的方法是奏效的,可能是TrueNAS有自己的一套开权限的方法吧。

附录:

①完整的statefulset.yaml文件(内含service的yaml文件):

apiVersion: v1
kind: Service
metadata:
  name: cgwire
  labels:
    app: cgwire
spec:
  ports:
  - port: 80
    name: web-service
    targetPort: 80
  clusterIP: None
  selector:
    app: cgwire
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web-service
spec:
  selector:
    matchLabels:
      app: cgwire
  serviceName: "cgwire"
  replicas: 1
  template:
    metadata:
      labels:
        app: cgwire
    spec:
      containers:
      - name: postgres
        image: postgres:latest
        imagePullPolicy: IfNotPresent
        env:
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        - name: POSTGRES_PASSWORD
          value: mysecretpassword
        ports:
        - containerPort: 5432
          name: web-service
        volumeMounts:
        - name: postgres-volume
          mountPath: /var/lib/postgresql/data
      - name: cgwire
        image: cgwire:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 80
        lifecycle:
         postStart:
          exec:
           command:
             - sh
             - -c
             - while [ ! -f  "/tmp/existed.txt"  ];do sleep 8;/opt/zou/init_zou.sh; done
        volumeMounts:
        - name: cgwire-volume
          mountPath: /tmp
        livenessProbe:
          tcpSocket:
             port: 80
          initialDelaySeconds: 12
          periodSeconds: 3
          timeoutSeconds: 3
          failureThreshold: 2
      volumes:
      - name: postgres-volume
        hostPath:
          path: /mnt/postgres
      - name: cgwire-volume
        hostPath:
          path: /mnt/cgwire

②几个当时我查阅博客,供大家参考。
nfs报错chown changing ownership of xxx Operation not permitted
权限 – 挂载的NFS分区上的chown给出“不允许操作”
NFS服务的用户身份映射
nfs挂载Permission denied问题解决
nfs的配置文件/etc/exports

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐