OpenShift version: 3.10
I have some doubts about Security Context Constraint (SCC)
in OpenShift, for example, I give privileged
SCC to service account, but some containers are still running as non-root user.
First what is SCC
used for: control the actions that a pod can perform and what it has the ability to access, also very useful for managing access to persistent storage.
Prerequisite
Spin up a fresh OpenShift Enterprise cluster with version:
1 | openshift v3.9.31 |
Create regular user demo1
1 | htpasswd -b /etc/origin/master/htpasswd demo1 demo1 |
After login as demo1
, you have its records in cluster, if run as system:admin
user:
1 | oc get user |
You will get demo1 information.
Fetch integrated docker registry address and port from system:admin
user:
1 | oc get svc -n default | grep -E "^docker-registry" |
Experiment
This experiment will show you:
- How to enable pulling image from other project.
- How to run container as root user.
Start with demo1
, login by oc login -u demo1
and create 2 projects:
1 | oc new-project demo1-proj ## this one is for deploying app |
Pull busybox
and update entrypoint
to tail /dev/null
:
1 | docker pull busybox |
1 | docker run -d \ |
Then commit:
1 | docker commit <container id> busybox |
Then docker tag to add docker registry address prefix:
1 | docker tag docker.io/busybox 172.30.159.11:5000/demo1-ds/busybox:v1 |
Docker login to integrated docker registry and push:
1 | docker login -u openshift -p `oc whoami -t` 172.30.159.11:5000 |
Go back to demo1-proj
project by oc project demo1-proj
, write a simple deployment yaml bb-deploy.yml
:
1 | apiVersion: apps/v1 |
Enable Pull from Other Projects
If now run:
1 | oc apply -f bb-deploy.yml |
It will fail to pull the image from demo1-ds
(describe pod can see) because we deploy objects on project demo1-proj
, it doesn’t have the permission to pull image from other project, let’s enable it:
1 | oc policy add-role-to-user \ |
Note that if you run this several times, it will create severl duplicate
system:image-puller
.
Then if you check rolebindings
in demo1-ds
, you see there is a new binding system:image-puller
with service account demo1-proj/default
:
1 | oc get rolebindings -n demo1-ds |
Ok, then we can deploy the busubox in demo1-proj
project:
1 | NAME READY STATUS RESTARTS AGE |
Let’s next see the container UID:
1 | kbc exec -it bb-deployment-78bdb8c4f-lzqfj sh |
Set Security Context Constraint
Correct, OpenShift by default doesn’t spin up container run as root user due to security issue. Acutally this is about SCC
, let’s dig deeper:
These 2 articles cover lots of things for SCC and service account: Managing Security Context Constraints Security Context Constraints official Configuring Service Accounts
you must have cluster-admin
privilege to manage SCCs (you can grant cluster-admin
privilege to regular user), there are 7 SCCs:
1 | oc get scc |
By default, when a container or pod does not request a user ID under which it should be run, the effective UID depends on the SCC that emits this pod. Because restricted
SCC is granted to all authenticated users by default, it will be available to all users and service accounts and used in most cases.
1 | oc describe scc restricted |
The restricted
SCC uses MustRunAsRange
strategy for constraining and defaulting the possible values of the securityContext.runAsUser field. The admission plug-in will look for the openshift.io/sa.scc.uid-range
annotation on the current project to populate range fields, as it does not provide this range. In the end, a container will have runAsUser equal to the first value of the range that is hard to predict because every project has different ranges.
1 | oc describe project demo1-proj |
You see, here openshift.io/sa.scc.uid-range
start from 1000130000
, is the UID of our busybox
container.
SCCs are not granted directly to a project. Instead, you add a service account to an SCC and either specify the service account name on your pod or, when unspecified, run as the default
service account.
Add and Remove SCC
Add service account default
in project demo1-proj
to SCC privileged
1 | oc adm policy add-scc-to-user privileged system:serviceaccount:demo1-proj:default |
Where to examine the result:
1 | oc describe scc privileged |
In the Users
field, we now have system:serviceaccount:demo1-proj:default
.
How to remove the SCC from a service account?
1 | oc adm policy remove-scc-from-user privileged system:serviceaccount:demo1-proj:default |
Deploy Again
Then login as demo1
, go to demo1-proj
, deploy again:
1 | oc apply -f bb-deploy.yml |
1 | oc exec -it bb-deployment-78bdb8c4f-rgj88 sh |
Why the UID is still 1000130000
? We have applied privileged
right?
Because privileged
is just a constraint, you need to Ensure that at least one of the pod’s containers is requesting a privileged mode in the security context.
So update the yaml file, add securityContext
, and deploy again:
1 | apiVersion: apps/v1 |
Now if you check the UID, it’s 0
:
1 | oc rsh bb-deployment-58cb44b56b-zmdcw |
Note that
oc rsh
is the same askubectl exec -it ... sh
Conclusion
Add privileged
SCC to service account is not enough, need to specify runAsUser: 0
in yaml file.