This “blog post"/"cheat sheet
” is about “Open the door for root users in OpenShift
(example StatefulSet)”. The topic is in context of two blog posts I wrote called Run a PostgreSQL container as a non-root user in OpenShift
and Open the door for root users in Red Hat OpenShift¶.
If you want to get an overview of the existing Default OpenShift security context constraints visit the IBM Cloud documentation.
In this blog post, once more we don’t want to take advantage of the Out Of The Box
provided security in Red Hat OpenShift. We are going to run a PostgreSQL
container as root.
To do this, we will do the following:
- We will deploy a
PostgreSQL
container as a very simple StatefulSet and notify that this container will not start, because by default the container is designed to run as root and that doesn’t work by default in Red Hat OpenShift. - We will investigate the problem and find that the container cannot create a temporary database when the container starts.
- We will create a service account and we add the policy
anyuid
. - We will add this service account to our project.
- Then will modify the existing StatefulSet to use the service account and we “open the door for root usage” with the policy
anyuid
. - We will delete the actual pod.
- We will check the newly created pod.
- In the last step we verify the changes we made in the StatefulSet.
Provide a container that uses root privileges
Step 1: Log in to the cluster as a user with cluster administrator rights
Step 2: Create a project called postgres
oc new-project postgres
Step 3: Create a yaml file for following StatefulSet and Service definition
Here you see the StatefulSet and the Service to deploy a simple example postgres container.
---
apiVersion: v1
kind: Service
metadata:
labels:
app: database-articles
name: database-articles-service
spec:
ports:
- name: http
port: 5432
protocol: TCP
selector:
app: database-articles
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database-articles
namespace: postgres
labels:
app: database-articles
spec:
serviceName: "database-articles-service"
selector:
matchLabels:
app: database-articles
template:
metadata:
labels:
app: database-articles
spec:
containers:
- env:
- name: POSTGRES_DB
value: postgres
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: postgres
- name: PGDATA
value: /temp/data
image: docker.io/postgres:latest
imagePullPolicy: Always
name: postgres-pod
ports:
- containerPort: 5432
protocol: TCP
resources:
limits:
cpu: 60m
memory: 512Mi
requests:
cpu: 30m
memory: 128Mi
restartPolicy: Always
Step 4: Apply your deployment and service configuration
oc apply -f postgres-statefulset.yaml
Example output:
service/database-articles-service created
statefulset.apps/database-articles created
Step 5: Verify that the pod is running
oc get pod
Example output:
vend-tmp % oc get pod
NAME READY STATUS RESTARTS AGE
database-articles-0 0/1 Error 3 56s
Step 6: Get logs for the pod
oc logs -f -p database-articles-0
Example output:
mkdir: cannot create directory ‘/temp’: Permission denied
Open the door for root usage
Step 1: Create a service account?
oc create sa postgres-sa
Example output:
serviceaccount/postgres-sa created
Step 2: Verify the created service account
oc get sa
Example output:
NAME SECRETS AGE
builder 2 2m25s
default 2 2m25s
deployer 2 2m25s
postgres-sa 2 17s
Step 3: Add policy add-scc-to-user anyuid
to service account
oc adm policy add-scc-to-user anyuid -z postgres-sa
Example output:
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "postgres-sa"
Step 4: Add service account and policy to project
oc adm policy add-scc-to-user anyuid -z postgres-sa -n postgres
Example output:
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "postgres-sa"
Step 5: Get the statefulset
oc get statefulset
Example output:
NAME READY AGE
database-articles 0/1 3m29s
Step 6: Add service account to statefulset
oc set sa statefulset database-articles postgres-sa
Example output:
statefulset.apps/database-articles serviceaccount updated
Step 7: Delete existing pod
oc delete pod database-articles-0
Example output:
pod "database-articles-0" deleted
Step 8: Get running pod
oc get pod database-articles-0
Example output:
NAME READY STATUS RESTARTS AGE
database-articles-0 1/1 Running 0 4m36s
Step 9: Access to running pod
- Access the running pod
oc exec database-articles-0 -i -t -- bash
- Verify the temp folder contains now a data folder inside the container.
root@database-articles-56c9977c7-vstgp:/# ls
bin docker-entrypoint-initdb.d lib mnt root srv tmp
boot etc lib64 opt run sys usr
dev home media proc sbin temp var
root@database-articles-56c9977c7-vstgp:/# cd temp
root@database-articles-56c9977c7-vstgp:/temp# ls
data
root@database-articles-56c9977c7-vstgp:/temp#
Step 10: Verify the changes in the statefulset
oc describe statefulset
Example output:
We will notice that a the Service Account: postgres-sa was added.
Name: database-articles
Namespace: postgres
CreationTimestamp: Tue, 14 Dec 2021 09:51:45 +0100
Selector: app=database-articles
Labels: app=database-articles
Annotations: <none>
Replicas: 1 desired | 1 total
Update Strategy: RollingUpdate
Partition: 0
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=database-articles
Service Account: postgres-sa
Containers:
postgres-pod:
Image: docker.io/postgres:latest
Port: 5432/TCP
Host Port: 0/TCP
Limits:
cpu: 60m
memory: 512Mi
Requests:
cpu: 30m
memory: 128Mi
Environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
PGDATA: /temp/data
Mounts: <none>
Volumes: <none>
Volume Claims: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 10m (x2 over 17m) statefulset-controller create Pod database-articles-0 in StatefulSet database-articles successful
Here are two useful blog posts and a YouTube video:
- “Managing SCCs in OpenShift”.
- “Managing security context constraints”
- “YouTube “Add a SCC permission like “anyuid” to a Service Account in Red Hat OpenShift”
Summary¶
It works once more pretty easily to enable root privileges for a container in OpenShift (it worked in the same way for the StatefulSet as it worked for the Deployment), but I would recommend using the “Out Of The Box” security provided by Red Hat OpenShift.
I hope this was useful to you and let’s see what’s next?
Greetings,
Thomas
#redhat, #openshift, #yaml, #security, #statefulset