4

The spring boot application is deployed on openshift 4. This application needs to create a file on the nfs-share. The openshift container has configured a volume mount on the type NFS. The container on openshift creates a pod with random userid as

sh-4.2$ id
uid=1031290500(1031290500) gid=0(root) groups=0(root),1031290500

The mount point is /nfs/abc

sh-4.2$ ls -la /nfs/
ls: cannot access /nfs/abc: Permission denied
total 0
drwxr-xr-x. 1 root root 29 Nov 25 09:34 .
drwxr-xr-x. 1 root root 50 Nov 25 10:09 ..
d?????????? ? ?    ?     ?            ? abc

on the docker image I created a user "technical" with uid= gid=48760 as shown below.

FROM quay.repository
MAINTAINER developer

LABEL description="abc image" \
      name="abc" \
      version="1.0"

ARG APP_HOME=/opt/app
ARG PORT=8080

ENV JAR=app.jar \
    SPRING_PROFILES_ACTIVE=default \
    JAVA_OPTS=""

    
RUN mkdir $APP_HOME 

ADD $JAR $APP_HOME/

WORKDIR $APP_HOME
EXPOSE $PORT
ENTRYPOINT java $JAVA_OPTS -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE -jar $JAR

my deployment config file is as shown below

 spec:
      volumes:
        - name: bad-import-file
          persistentVolumeClaim:
            claimName: nfs-test-pvc
      containers:
        - resources:
            limits:
              cpu: '1'
              memory: 1Gi
            requests:
              cpu: 500m
              memory: 512Mi
          terminationMessagePath: /dev/termination-log
          name: abc
          env:
            - name: SPRING_PROFILES_ACTIVE
              valueFrom:
                configMapKeyRef:
                  name: abc-configmap
                  key: spring.profiles.active
            - name: DB_URL
              valueFrom:
                configMapKeyRef:
                  name: abc-configmap
                  key: db.url
            - name: DB_USERNAME
              valueFrom:
                configMapKeyRef:
                  name: abc-configmap
                  key: db.username
            - name: BAD_IMPORT_PATH
              valueFrom:
                configMapKeyRef:
                  name: abc-configmap
                  key: bad.import.path
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: abc-secret
                  key: db.password
          ports:
            - containerPort: 8080
              protocol: TCP
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: bad-import-file
              mountPath: /nfs/abc
      dnsPolicy: ClusterFirst
      securityContext:
        runAsGroup: 44337
        runAsNonRoot: true
        supplementalGroups:
          - 44337

the PV request is as follows

apiVersion: v1
kind: PersistentVolume
metadata:
  name: abc-tuc-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: classic-nfs
  mountOptions:
    - hard
    - nfsvers=3
  nfs:
    path: /tm03v06_vol3014
    server: tm03v06cl02.jit.abc.com
    readOnly: false

Now the openshift user has id

sh-4.2$ id
        uid=1031290500(1031290500) gid=44337(technical) groups=44337(technical),1031290500

RECENT UPDATE

Just to be clear with the problem, Below I have two commands from the same pod terminal,

sh-4.2$ cd /nfs/
sh-4.2$ ls -la (The first command I tried immediately after pod creation.)
total 8
drwxr-xr-x.  1 root  root    29 Nov 29 08:20 .
drwxr-xr-x.  1 root  root    50 Nov 30 08:19 ..
drwxrwx---. 14 technical technical 8192 Nov 28 19:06 abc
sh-4.2$ ls -la(few seconds later on the same pod terminal)
ls: cannot access abc: Permission denied
total 0
drwxr-xr-x. 1 root root 29 Nov 29 08:20 .
drwxr-xr-x. 1 root root 50 Nov 30 08:19 ..
d?????????? ? ?    ?     ?            ? abc

So the problem is that I see these question marks(???) on the mount point. The mounting is working correctly but I cannot access this /nfs/abc directory and I see this ????? for some reason

UPDATE

sh-4.2$ ls -la /nfs/abc/
ls: cannot open directory /nfs/abc/: Stale file handle
sh-4.2$ ls -la /nfs/abc/ (after few seconds on the same pod terminal)
ls: cannot access /nfs/abc/: Permission denied

Could this STALE FILE HANDLE be the reason for this issue?

blong
  • 2,815
  • 8
  • 44
  • 110
  • If /nfs/ is really mounted, than it has nothing to do with kubernetes/openshift, the problem lies in the wrong configuration of the access rights in NFS. Make sure that everyone can write / read in the NFS share (o+rw[x]) – 9ilsdx 9rvj 0lo Nov 25 '21 at 11:11
  • @9ilsdx9rvj0lo as you can see I have permissions on the share, drwxrwx---. 13 technical technical 8192 Sep 7 13:50 abc as openshift user is a part of the group "technical" – Syed Iftekharuddin Nov 25 '21 at 11:25
  • In your examples, the path in NFS and in the PV, and the path in ls command and in deployment descriptor, doesn't match. Also, the name of the user/group is irrelevant, but the numeric id must be the same on both sides. – 9ilsdx 9rvj 0lo Nov 25 '21 at 12:09
  • I made the changes, Please check. These are were edit just to follow company policy and hidding information. – Syed Iftekharuddin Nov 25 '21 at 12:36
  • How can I run, the container with id 44337, because if I try to use runAsUser in securityContext I get an error that cannot assign a userid outside some range (1031290500 to 1031295500) – Syed Iftekharuddin Nov 25 '21 at 12:41
  • Which OpenShift version are you using? – Mikolaj S. Nov 26 '21 at 14:03
  • I am using Openshift 4 – Syed Iftekharuddin Nov 30 '21 at 09:01
  • @Stephen Kitt could please have a look at this question https://unix.stackexchange.com/users/86440/stephen-kitt – Syed Iftekharuddin Dec 06 '21 at 07:54
  • You could set a fixed `USER` in your `Dockerfile` and run the pod under a service account configured with the [anyuid security context](https://docs.openshift.com/container-platform/4.2/authentication/managing-security-context-constraints.html) setting the permissions on the PVC (NFS volume) beforehand rather than dealing with randomly generated UID's. – masseyb Dec 06 '21 at 22:13
  • 1
    @masseyb it would be nice if give an example of what you mean PLEASE – Syed Iftekharuddin Dec 07 '21 at 14:01
  • did you configure the permissions for the NFS volume by itself? to have the correct file permissions (rwx) and user\group permissions (user group ) ? – Noam Yizraeli Dec 07 '21 at 15:38
  • Yes, when I type mount in the pod terminal I get the mount point and volume mounted with rw permission – Syed Iftekharuddin Dec 07 '21 at 16:24
  • but for the specified user\group? – Noam Yizraeli Dec 07 '21 at 17:51
  • user range is fixed, whenever we try to change the userid (in securityContext with runAsUser: ) we get an error that userid is out of range – Syed Iftekharuddin Dec 07 '21 at 17:55
  • I'm confused. didn't you make the pod use the specified user you chose? if so, what I'm suggesting is changing the group permissions recursively for the nfs share to be owned by that specified group `chown :technical -R abc` and maybe also `.` and `..` – Noam Yizraeli Dec 07 '21 at 18:02
  • Yes as you mentioned the share has a group (technical) and openshift user(1031290500) is member of the group. Even in deploymentConfig there is securityConfig where I specified all this. As you see in the id command it displays this info – Syed Iftekharuddin Dec 07 '21 at 18:21
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239920/discussion-between-noam-yizraeli-and-syed-iftekharuddin). – Noam Yizraeli Dec 07 '21 at 18:28

1 Answers1

1

TL;DR

You can use the anyuid security context to run the pod to avoid having OpenShift assign an arbitrary UID, and set the permissions on the volume to the known UID of the user.


OpenShift will override the user ID the image itself may specify that it should run as:

The user ID isn't actually entirely random, but is an assigned user ID which is unique to your project. In fact, your project is assigned a range of user IDs that applications can be run as. The set of user IDs will not overlap with other projects. You can see what range is assigned to a project by running oc describe on the project.

The purpose of assigning each project a distinct range of user IDs is so that in a multitenant environment, applications from different projects never run as the same user ID. When using persistent storage, any files created by applications will also have different ownership in the file system.

... this is a blessing and a curse, when using shared persistent volume claims for example (e.g. PVC's mounted in ReadWriteMany with multiple pods that read / write data - files created by one pod won't be accessible by the other pod because of the incorrect file ownership and permissions).

One way to get around this issue is using the anyuid security context which "provides all features of the restricted SCC, but allows users to run with any UID and any GID".

When using the anyuid security context, we know the user and group ID's the pod(s) are going to run as, and we can set the permissions on the shared volume in advance. For example, where all pods run with the restricted security context by default:

restricted security context

When running the pod with the anyuid security context, OpenShift doesn't assign an arbitrary UID from the range of UID's allocated for the namespace:

anyuid security context

This is just for example, but an image that is built with a non-root user with a fixed UID and GID (e.g. 1000:1000) would run in OpenShift as that user, files would be created with the ownership of that user (e.g. 1000:1000), permissions can be set on the PVC to the known UID and GID of the user set to run the service. For example, we can create a new PVC:

cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
  namespace: k8s
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 8Gi
  storageClassName: portworx-shared-sc
EOF

... then mount it in a pod:

kubectl run -i --rm --tty ansible --image=lazybit/ansible:v4.0.0 --restart=Never -n k8s --overrides='
{
  "apiVersion": "v1",
  "kind": "Pod",
  "spec": {
    "serviceAccountName": "default",
    "containers": [
      {
        "name": "nginx",
        "imagePullPolicy": "Always",
        "image": "lazybit/ansible:v4.0.0",
        "command": ["ash"],
        "stdin": true,
        "stdinOnce": true,
        "tty": true,
        "env": [
          {
            "name": "POD_NAME",
            "valueFrom": {
              "fieldRef": {
                "apiVersion": "v1",
                "fieldPath": "metadata.name"
              }
            }
          }
        ],
        "volumeMounts": [
          {
            "mountPath": "/data",
            "name": "data"
          }
        ]
      }
    ],
    "volumes": [
      {
        "name": "data",
        "persistentVolumeClaim": {
          "claimName": "data"
        }
      }
    ]
  }
}'

... and create files in the PVC as the USER set in the Dockerfile.

example file created as anyuid USER

masseyb
  • 3,745
  • 1
  • 17
  • 29
  • as you can see in the recent updates : the above said process is already achieved. drwxrwx---. 14 technical technical 8192 Nov 28 19:06 abc Can I somehow edit pvc and place uid in it? – Syed Iftekharuddin Dec 09 '21 at 14:43
  • The problem here is a runtime issue, as mentioned in the recent updates, these question marks appear after sometime of pod running – Syed Iftekharuddin Dec 09 '21 at 22:16
  • @SyedIftekharuddin can try using the `anyuid` scc and check if the permissions are still being messed with after the deployment, if not then the issue is most probably related to the arbitrary UID assignment. – masseyb Dec 10 '21 at 12:07
  • It might not solve your issue, but it was too long to put in a comment, ref. [this](https://stackoverflow.com/questions/70109707/openshift-missing-permissions-to-create-a-file/70275985#comment124202653_70109707). – masseyb Dec 10 '21 at 12:09