Openshift - Applying RunOnlyAs SCC to pods within a deployment

2/6/2018

I have an SCC defined that lets the developer user run containers as UID 1015:

    kind: SecurityContextConstraints
    apiVersion: v1
    metadata:
      name: developer
    allowPrivilegedContainer: false
    runAsUser:
      type: MustRunAs
      uid: 1015
    seLinuxContext: 
      type: MustRunAs
      uid: 1015
    users:
    - developer

This SCC works fine when I create a pod directly as the developer user:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-1-0
    spec:
      securityContext:
        runAsUser: 1015
      containers:
      - name: test-1-0
        image: test-image:1.0
        imagePullPolicy: "Always"
        volumeMounts:
        - name: secret-dir
          mountPath: "/secrets"
          readOnly: true
      volumes:
      - name: secret-dir
        secret:
          secretName: test-1.0-configs

However, when I transition this to a deployment, I get an error. Here's my YAML:

kind: "DeploymentConfig"
apiVersion: "v1"
metadata:
  name: "test-1-0"
spec:
  template: 
    metadata:
      labels:
        name: "test-1-0"
    spec:
      securityContext:
        runAsUser: 1015
      containers:
      - name: test-1-0
        image: test-image:1.0
        imagePullPolicy: "Always"
        volumeMounts:
        - name: secret-dir
          mountPath: "/secrets"
          readOnly: true
      volumes:
      - name: secret-dir
        secret:
          secretName: test-1.0-configs
  replicas: 2
  selector:
    name: "test-1-0"

And the error I receive:

Error creating: pods "test-1-0-1-" is forbidden: unable to validate against any security context constraint: [securityContext.runAsUser: Invalid value: 1015: UID on container test-1-0 does not match required range. Found 1015, required min: 1000050000 max: 1000059999]

It's as if the deployment is deploying pods NOT as the user I created the deployment with. Is there any way to resolve that?

-- ev0lution37
deployment
kubernetes
openshift

1 Answer

2/7/2018

It is probably better to dictate what SCC is to be used for the deployment via a service account.

First off create the SCC. Using what I have tested as an example, I created uid1000.json containing.

{
    "apiVersion": "v1",
    "kind": "SecurityContextConstraints",
    "metadata": {
        "name": "uid1000"
    },
    "requiredDropCapabilities": [
        "KILL",
        "MKNOD",
        "SYS_CHROOT",
        "SETUID",
        "SETGID"
    ],
    "runAsUser": {
        "type": "MustRunAs",
        "uid": "1000"
    },
    "seLinuxContext": {
        "type": "MustRunAs"
    },
    "fsGroup": {
        "type": "MustRunAs"
    },
    "supplementalGroups": {
        "type": "RunAsAny"
    },
    "volumes": [
        "configMap",
        "downwardAPI",
        "emptyDir",
        "persistentVolumeClaim",
        "projected",
        "secret"
    ]
}

Then ran:

oc create -f uid1000.json --as system:admin

Need to be admin to do that.

Next I created a service account in the target project just for running the application which needs this SCC.

oc create serviceaccount runasuid1000

I now say that anything run as this service account should use the new SCC.

oc adm policy add-scc-to-user uid1000 -z runasuid1000 --as system:admin

Again need to be admin to do that. The -z option means use current project, so make sure you are in the right one.

Finally I patch the existing deployment config.

oc patch dc/minimal-notebook --patch '{"spec":{"template":{"spec":{"serviceAccountName": "runasuid1000"}}}}'

If necessary, due to config change trigger being disabled, trigger a new deployment:

oc rollout latest minimal-notebook

This will force the container to run as uid 1000, overriding what the image even says it should run as according to USER definition.

-- Graham Dumpleton
Source: StackOverflow