CKS study materials
CKS study resources

CKS cheat sheet

CKS · Keep the key ideas within reach.

Quick reference

Cluster Setup

  • A pod is isolated for ingress only when a NetworkPolicy's podSelector matches it; any ingress not matched by an allow rule is then denied.

  • An empty podSelector {} selects every pod in the policy's namespace; an empty namespaceSelector {} selects every namespace, so both together mean all pods everywhere.

  • Cloud instance credentials are reachable at 169.254.169.254 from pods unless an egress NetworkPolicy denies that address; IMDSv2-only mode adds another layer.

  • kube-bench executes the CIS Kubernetes Benchmark checks against control plane binaries, config files and node settings, and exits non-zero when a check fails.

  • Encryption at rest requires an EncryptionConfiguration listing providers (aesgcm, aescbc, secretbox, identity) referenced by kube-apiserver --encryption-provider-config; pre-existing Secrets are only re-encrypted after a rewrite.

  • --anonymous-auth=false must be set on both kube-apiserver and kubelet; otherwise unauthenticated requests map to system:anonymous.

  • An Ingress TLS entry needs a Secret of type kubernetes.io/tls holding tls.crt and tls.key, referenced from spec.tls[].secretName.

  • Correct upgrade order: kubeadm upgrade plan, kubeadm upgrade apply on the first control plane node, drain and kubeadm upgrade node on remaining nodes, then upgrade kubelet and kubectl packages.

  • Only one minor version skew is supported between kube-apiserver and kubelet, and kubelet may never be newer than kube-apiserver.

Quick reference

Cluster Hardening

  • --authorization-mode=Node,RBAC delegates kubelet requests to the Node authorizer and all other requests to RBAC; ABAC and AlwaysAllow should not appear in the list.

  • The NodeRestriction admission plugin restricts a kubelet to its own Node object and to Pods already bound to that node, blocking label and taint tampering elsewhere.

  • A ClusterRoleBinding to cluster-admin grants unrestricted cluster-wide control; namespaced RoleBindings and narrowly scoped ClusterRoles keep blast radius small.

  • automountServiceAccountToken: false at Pod or ServiceAccount level removes the projected API token and therefore the credential an attacker can steal.

  • kubeadm certs check-expiration reports remaining validity, kubeadm certs renew all refreshes control plane certificates; CA certificates default to 10 years, other kubeadm certificates to 1 year.

  • Kubelet hardening baseline: --anonymous-auth=false, --authorization-mode=Webhook, --read-only-port=0, and client CA configured for certificate auth.

  • The Kubernetes Dashboard requires a service account token and has had privilege-escalation CVEs; if kept, expose it only behind an authenticating proxy.

  • system:masters group membership bypasses RBAC entirely, so audit who holds it and map external identity-provider groups carefully.

Quick reference

System Hardening

  • securityContext.seccompProfile.type=RuntimeDefault applies the runtime's default syscall allowlist; Localhost points to a JSON profile on the node.

  • AppArmor is selected with the container.apparmor.security.beta.kubernetes.io/ annotation on older clusters and securityContext.appArmorProfile from Kubernetes 1.30.

  • hostPath, hostNetwork, hostPID and hostIPC all cross the pod/node boundary; the baseline Pod Security level rejects hostPath, host namespaces and privileged containers.

  • The kubelet read-only port 10255 served pod specs without authentication when enabled; --read-only-port=0 closes it.

  • Node SSH should be key-based, reachable only from a bastion or session manager, with password auth and root login disabled.

  • Cloud node IAM roles should grant only the permissions the node needs, because any pod that reaches the metadata endpoint inherits them.

  • Disable unused kernel modules and filesystems via /etc/modprobe.d and modprobe blacklists, and apply sysctl settings such as kernel.kptr_restrict and net.ipv4.conf.all.accept_redirects=0.

  • A minimal node OS image with unused packages and services removed reduces both the patch burden and the exploitable surface.

Quick reference

Minimize Microservice Vulnerabilities

  • Baseline container SecurityContext: runAsNonRoot: true, allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, capabilities.drop: ["ALL"], and seccompProfile RuntimeDefault.

  • Pod Security Admission defines three levels (privileged, baseline, restricted) and three modes (enforce, audit, warn) configured by namespace labels such as pod-security.kubernetes.io/enforce=restricted.

  • restricted PSA requires non-root execution, dropped capabilities, RuntimeDefault or Localhost seccomp and no privilege escalation; privileged containers only pass under the privileged level.

  • Secrets are stored base64-encoded in etcd unless an encryption provider is configured; volume mounts avoid exposing them in env, process listings and crash dumps.

  • A default-deny NetworkPolicy per namespace plus explicit allow rules limits lateral movement; mTLS or a service mesh authenticates pod-to-pod traffic.

  • OPA Gatekeeper uses ConstraintTemplates containing Rego plus Constraints that select target resources; Kyverno expresses validate, mutate and generate rules directly in YAML.

  • RuntimeClass with gVisor or Kata Containers inserts an extra kernel or user-space boundary between the container and the host.

  • Resource requests and limits prevent a single workload from exhausting node CPU or memory and degrading neighbours.

Quick reference

Supply Chain Security

  • Image scanning (Trivy, Grype) should run in CI and continuously on registry contents; builds fail when fixable HIGH or CRITICAL CVEs are present.

  • cosign signs an image digest and stores the signature in the registry as an OCI artifact; admission policies such as Kyverno verifyImages or Connaisseur reject unsigned images.

  • Referencing image@sha256: pins the exact bytes, whereas tags are mutable and can be repointed at a different image.

  • ImagePullPolicy defaults to Always when the tag is :latest or omitted and to IfNotPresent otherwise; digest references with IfNotPresent avoid repeated pulls.

  • Distroless or scratch base images contain no shell or package manager, removing the tooling an attacker needs after code execution.

  • Multi-stage Dockerfiles keep compilers and build caches out of the runtime layer, and the final stage should run as a non-root USER.

  • Image pull credentials belong in a namespaced imagePullSecret or a node-level credential provider; registry push rights should be limited to the CI identity.

  • SBOM generation (syft) and provenance attestations (SLSA, cosign attest) let you trace which dependencies and build systems produced a deployed image.

Quick reference

Monitoring, Logging and Runtime Security

  • Falco is a CNCF runtime security project that reads syscalls from eBPF or a kernel module and fires alerts when events match its rules.

  • Falco's default ruleset flags a shell spawned inside a container, writes under /etc or /bin, access to /etc/shadow, and outbound connections to unexpected destinations.

  • Audit policy rule levels are None, Metadata, Request and RequestResponse, in increasing order of recorded request and response body detail.

  • Audit stages are RequestReceived, ResponseStarted, ResponseComplete and Panic; every emitted event carries its stage in the auditID-scoped record.

  • Audit backends are the log file (--audit-log-path with --audit-log-maxbackup, --audit-log-maxsize, --audit-log-maxage) and a webhook (--audit-webhook-config-file) for SIEM shipping.

  • kubectl logs shows only container stdout and stderr; node-level tooling such as journalctl or sysdig is needed for process and system call evidence.

  • sysdig captures live syscalls and container events on a node and is used for post-incident forensics after a suspected runtime compromise.

  • A read-only root filesystem combined with an image lacking a shell makes post-exploitation persistence and tooling drops much harder.