How can I enable an image to run as a set user ID?

When an application is deployed it will run as a user ID unique to the project it is running in. This overrides the user ID which the application image defines it wants to be run as. That the application is run as a different user ID can result in it failing to start.

The best solution is to build the application image so it can be run as an arbitrary user ID. This avoids the risks associated with having to run an application as the root user ID, or other fixed user ID which may be shared with applications in other projects.

If an image can't be modified, you can elect to override the default security configuration of OpenShift and have it run as the user the image specifies, but this can only be done by an administrator of the OpenShift cluster. This cannot be done by normal developers, nor a project administrator. This cannot be done on hosting services such as OpenShift Online.

The change required to override the default security configuration, is to grant rights to the service account the application is run under, to run images as a set user ID.

The service account within a project which applications would usually be run as is the default service account. Because you may run other applications in the same project, and don't necessarily want to override the user ID used for all applications, create a new service account which can be granted the special rights. In the project where the application is to run, run the oc create serviceaccount command, passing the name to be given to the service account.

$ oc create serviceaccount runasanyuid
serviceaccount "runasanyuid" created

The next step is that which must be run as a cluster administrator. It is the granting of the appropriate rights to the service account. This is done by specifying that the service account should run with a specific security context constraint (SCC).

As an administrator, you can see the list of SCCs that are defined in the cluster by running the oc get scc command.

$ oc get scc --as system:admin
NAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES
anyuid             false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
hostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
hostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim projected secret]
hostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
nonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
privileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    <none>     false            [*]
restricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]

By default applications would run under the restricted SCC. The MustRunAsRange value for RUNASUSER is what indicates that the application needs to run within the user ID range associated with the project.

To allow an application to be run as any user ID, including the root user ID, you want to use the anyuid SCC.

To associate the new service account with the SCC, run the oc adm policy add-scc-to-user command. The -z option indicates to apply the command to the service account in the current project, so ensure you run this within the correct project.

$ oc adm policy add-scc-to-user anyuid -z runasanyuid --as system:admin

With applications run under this service account now being able to run as any user ID, you need to update the deployment configuration for the application to use the service account. This can be done by patching the deployment configuration in place using the oc patch command.

$ oc patch dc/minimal-notebook --patch '{"spec":{"template":{"spec":{"serviceAccountName": "runasanyuid"}}}}'
deploymentconfig "minimal-notebook" patched

Once the deployment configuration has been updated, trigger a new deployment if necessary.

$ oc rollout latest minimal-notebook
deploymentconfig "minimal-notebook" rolled out

Allowing a user to run applications as any user ID will allow them to also run application images as root inside of the container. Because of the risks associated with allowing applications to run as root, if root isn't required, use the nonroot SCC instead of anyuid. This will allow an application to be run as any user ID except root.

Do note though that for nonroot to work, the USER specified for the image, must be defined with an integer user ID rather than a user name. If a user name is used, it is not possible to verify that it does in fact map to a user ID other than 0.

If an image doesn't use an integer user ID for USER, the alternative is to create a new SCC which enforces running as a single specific user ID.

To do this for the user ID 1000, create a file 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"
    },
    "supplementalGroups": {
        "type": "RunAsAny"
    },
    "fsGroup": {
        "type": "MustRunAs"
    },
    "volumes": [
        "configMap",
        "downwardAPI",
        "emptyDir",
        "persistentVolumeClaim",
        "projected",
        "secret"
    ]
}

To create the new SCC, you need to be an administrator.

$ oc create -f uid1000.json --as system:admin
securitycontextconstraints "uid1000" created

Create the service account in the project:

$ oc create serviceaccount runasuid1000
serviceaccount "runasuid1000" created

Set the SCC to be used by the service account to that created above.

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

Finally patch the deployment configuration.

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

For a SCC which sets runAsUser to be MustRunAs and provides a set user ID, when the application is run, it will be forced to run as that user ID, overriding whatever user ID the image may have specified. Whether the image sets USER to a user name rather than an integer user ID therefore doesn't matter. The SCC just needs to use the same integer user ID that the user name maps to for the image.

results for ""

    No results matching ""