Post

Immutable infrastructure (readOnlyRootFilesystem,privileged)

Set UID and GID within securityContext for a pod and verify results using runAsUser and runAsGroup.

Set UID and GID within securityContext for a pod and verify results (runAsUser and runAsGroup).

The following pod manifest runs a busybox container as user 1000 and group 3000, with an emptyDir volume mounted at /data/demo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: v1
kind: Pod
metadata:
  name: grimsby
  namespace: alpha
spec:
  containers:
  - command:
    - sh
    - -c
    - sleep 5h
    image: busybox
    imagePullPolicy: Always
    name: sec-ctx-demo
    securityContext:
      runAsUser: 1000
      runAsGroup: 3000
    volumeMounts:
    - mountPath: /data/demo
      name: demo-volume
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-4lmbt
      readOnly: true
...
  volumes:
  - emptyDir: {}
    name: demo-volume
  - name: default-token-4lmbt
    secret:
      defaultMode: 420
      secretName: default-token-4lmbt

Create an Nginx pod with readOnlyRootFilesystem option and adjust necessary volumes (/var/cache/nginx, /var/run). Since Nginx needs to write to these directories at runtime, they are mounted as writable emptyDir volumes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: solaris
  name: solaris
  namespace: alpha
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: solaris
    ports:
    - containerPort: 8080
      protocol: TCP
    resources: {}
    securityContext:
      privileged: false
      readOnlyRootFilesystem: true
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/cache/nginx
      name: nginx
    - mountPath: /var/run
      name: run
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-4lmbt
      readOnly: true
...
  volumes:
  - name: nginx
    emptyDir: {}
  - name: run
    emptyDir: {}

Run Apache (httpd) with readOnlyRootFilesystem within the security context as well as create temporary mountPath/volumeMounts. Apache needs a writable logs directory, so /usr/local/apache2/logs is mounted as an emptyDir volume.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: triton
    namespace: alpha
  name: triton
  namespace: alpha
spec:
  containers:
  - image: httpd
    imagePullPolicy: Always
    name: triton
    resources: {}
    securityContext:
            readOnlyRootFilesystem: true
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-4lmbt
      readOnly: true
    - mountPath: /usr/local/apache2/logs
      name: apache
...
    tolerationSeconds: 300
  volumes:
  - name: apache
    emptyDir: {}

  - name: default-token-4lmbt
    secret:
      defaultMode: 420
      secretName: default-token-4lmbt
This post is licensed under CC BY 4.0 by the author.