Certified Kubernetes Application Developer - CKAD
Configuration
Solutions Security Contexts
In this article, we explore various Kubernetes security context scenarios and demonstrate how to update pod configurations to meet specific security requirements. You'll learn how to check the running user inside pods, update configurations to run processes as non-root or root with additional capabilities, and understand container-level versus pod-level security context inheritance.
Checking the User of a Running Pod
To determine which user is executing the sleep process inside an Ubuntu sleeper pod, follow these steps:
List the Pods
Identify the Ubuntu sleeper pod by listing all pods:kubectl get pods
Access the Pod
Usekubectl exec
to access the pod's shell:kubectl exec -it ubuntu-sleeper -- bash
Verify the User Inside the Container
Once inside, run the command:whoami
The expected output should be:
root
Below is a sample console output demonstrating these steps:
kubectl get pods
NAME READY STATUS RESTARTS AGE
ubuntu-sleeper 1/1 Running 0 7m58s
And, inside the container:
whoami
root
This confirms that the sleep process is running as the root user.
Updating the Pod to Run as a Specific Non-Root User (UID 1010)
To update the Ubuntu sleeper pod so that the process runs with the user ID 1010, follow these steps:
Export the Current Pod Configuration
Retrieve the current configuration and save it to a file:kubectl get pod ubuntu-sleeper -o yaml > ubuntu-sleeper.yaml
Edit the Configuration File
Openubuntu-sleeper.yaml
in your favorite text editor. Locate the pod'ssecurityContext
, which should currently look like:securityContext: {}
Modify the Security Context
Update the file by adding therunAsUser
property with UID 1010:securityContext: runAsUser: 1010
Apply the Updated Configuration
Save the changes, then delete the existing pod (forcing deletion if necessary) and reapply the configuration:kubectl delete pod ubuntu-sleeper --force kubectl apply -f ubuntu-sleeper.yaml
An excerpt of the modified configuration is as follows:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-sleeper
namespace: default
spec:
containers:
- command:
- sleep
- "4800"
image: ubuntu
imagePullPolicy: Always
name: ubuntu
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-vwn5z
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: controlplane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
runAsUser: 1010
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
After applying these changes, you can verify that the pod is running:
kubectl get pods
Note
At the container level, the securityContext
settings override those defined at the pod level.
Determining the User for Multiple Containers in a Pod
When dealing with pods that contain multiple containers, it's important to understand how user contexts are inherited. Consider the following pod definition from the multi-pod.yaml
file:
apiVersion: v1
kind: Pod
metadata:
name: multi-pod
spec:
securityContext:
runAsUser: 1001
containers:
- image: ubuntu
name: web
command: ["sleep", "5000"]
securityContext:
runAsUser: 1002
- image: ubuntu
name: sidecar
command: ["sleep", "5000"]
Key observations:
- The pod-level security context sets
runAsUser
to 1001. - The web container defines its own
securityContext
withrunAsUser: 1002
.
Since the container-level security context takes precedence, the processes in the web container run as user 1002. The sidecar container, which lacks a container-specific security context, inherits the pod-level setting, so its processes run as user 1001.
The final configuration is provided below for reference:
apiVersion: v1
kind: Pod
metadata:
name: multi-pod
spec:
securityContext:
runAsUser: 1001
containers:
- image: ubuntu
name: web
command: ["sleep", "5000"]
securityContext:
runAsUser: 1002
- image: ubuntu
name: sidecar
command: ["sleep", "5000"]
Updating the Ubuntu Sleeper Pod to Run as Root with SYS_TIME Capability
To modify the Ubuntu sleeper pod so that:
- The process runs as the default root user.
- The pod is granted the
SYS_TIME
capability,
follow these steps:
Edit the Pod Configuration
Open the current configuration file (e.g.,ubuntu-sleeper.yaml
), and remove any pod-levelsecurityContext
that enforces a non-root user.Add Capabilities at the Container Level
Under the container specification responsible for running the sleep command, add asecurityContext
that includes the required capability:securityContext: capabilities: add: ['SYS_TIME']
A sample updated configuration is shown below:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2023-07-26T22:12:07Z"
name: ubuntu-sleeper
namespace: default
resourceVersion: "945"
uid: 34c800d-d278-498b-b6be-f9e41086be9f
spec:
containers:
- command:
- sleep
- "4800"
image: ubuntu
imagePullPolicy: Always
name: ubuntu
securityContext:
capabilities:
add: ['SYS_TIME']
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-km279
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: controlplane
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
After saving the configuration, delete the existing pod and apply the new configuration:
kubectl delete pod ubuntu-sleeper --force
kubectl apply -f ubuntu-sleeper.yaml
Verify that the pod is running as expected:
kubectl get pods
Adding the NET_ADMIN Capability
To enhance the security context further by adding the NET_ADMIN
capability in addition to SYS_TIME
, follow these steps:
Modify the Container’s Security Context
Open theubuntu-sleeper.yaml
file and update thesecurityContext
under the container section to include both capabilities:securityContext: capabilities: add: ['SYS_TIME', 'NET_ADMIN']
Apply the Changes
Save the file and reapply the pod configuration by deleting the current pod and applying the updated configuration:kubectl delete pod ubuntu-sleeper --force kubectl apply -f ubuntu-sleeper.yaml
Verify the Update
Optionally, check that the pod is running with the updated capabilities:kubectl get pods
A sample console interaction may look like this:
controlplane ~ ➜ vi ubuntu-sleeper.yaml
controlplane ~ ➜ kubectl delete pod ubuntu-sleeper --force
Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "ubuntu-sleeper" force deleted
controlplane ~ ➜ kubectl apply -f ubuntu-sleeper.yaml
pod/ubuntu-sleeper created
controlplane ~ ➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
ubuntu-sleeper 1/1 Running 0 10s
This completes the guide on updating Kubernetes pod configurations with various security contexts and capabilities. For more detailed information on Kubernetes security practices, see the Kubernetes Documentation.
Happy securing!
Watch Video
Watch video content