How to pass CKS — Kubernetes Security Specialist exam. Part 2

Arek Borucki
3 min readApr 11, 2021

CKS requires CKA (Certified Kubernetes Administrator) passed first. It is a mandatory pre-request. I shared my tips in a different post on how to pass CKA and CKAD. If you received CKA, know how to use kubectl and Kubernetes documentation in an efficient way, you can start study for CKS. CKS is harder than the other two K8s exams. Good preparation requires deep study of native and external Kubernetes security tools, best security practices, and also requires a good knowledge of Kubernetes architecture, especially about API server, etcd, and kubelet. The exam covers: gVisor, AppArmor, RBAC, Network Policies, Auditing, Falco,Trivy, Admission Controllers, CIS Benchmark, Pod Security Policies, writing secure Dockerfiles, Secrets, Privileged Pods.

  1. Episode — Network Policies
  2. Episode — gVisor
  3. Episode — Trivy
  4. Episode — AppArmor
  5. Episode — PodSecurityPolicies
  6. Episode — RBAC
  7. Dockerfile & SecurityContext

gVisor is a container sandbox developed by Google that focuses on security. gVisor implements a substantial portion of the Linux system call interface. It provides an additional layer of isolation between running applications and the host operating system

On exam, you can be asked to create a new RuntimeClass with runcs as handler and a Deployment which use this RuntimeClass.

CRI Configuration with container — It is good to know, that on worker node runtime handlers are configured through containerd configuration at /etc/containerd/config.toml. Valid handlers are configured under the runtimes section:

[plugins.cri.containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"

Let’s create now a RuntimeClass called gvisor with runsc handler

---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc

create a Deployment template with nginx image via kubectl command

k create deploy test --image=nginx --dry-run=client -oyaml >dep.yaml

adjust Deployment manifest

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
runtimeClassName: gvisor # ADD THIS
containers:
- image: nginx
name: nginx
resources: {}
status: {}

and create Deployment via kubectl create -f dep.yaml , after creation, we can test if it uses the gVisor sandbox by executing dmesg on newly started Pod

kubectl exec test-76974f9cd9-jqmg2 -- dmesg
[ 0.000000] Starting gVisor...
[ 0.479413] Searching for needles in stacks...
[ 0.916631] Rewriting operating system in Javascript...
[ 1.344014] Digging up root...
[ 1.637811] Daemonizing children...
[ 2.046348] Feeding the init monster...
[ 2.056526] Searching for socket adapter...
[ 2.058984] Letting the watchdogs out...
[ 2.222011] Reading process obituaries...
[ 2.361719] Preparing for the zombie uprising...
[ 2.424331] Adversarially training Redcode AI...
[ 2.701016] Ready!

Examples from this post are available on GitHub. Thank you and see you soon in the next episode! The next post will be about Trivy.

--

--