CKA Cluster Architecture Master Reference Link to heading

Domain 5 — Cluster Architecture, Installation and Configuration Link to heading

RBAC Link to heading

Four Built-in ClusterRoles (memorize) Link to heading

ClusterRolePermissions
viewread-only
editread/write, no RBAC
adminfull namespace including RBAC
cluster-admingod mode

When question says “view permissions” or “read-only” → bind existing view ClusterRole, don’t create a new Role.

RBAC Combinations (3 valid of 4) Link to heading

  1. Role + RoleBinding — namespace scoped, applied in namespace
  2. ClusterRole + ClusterRoleBinding — cluster-wide, applied cluster-wide
  3. ClusterRole + RoleBinding — cluster-wide permissions, scoped to one namespace

Imperative Commands Link to heading

# Create Role
k -n <ns> create role <name> --verb=list,delete --resource=pods,deployments,statefulsets

# Create RoleBinding (user)
k -n <ns> create rolebinding <name> --role=<role> --user=<username>

# Create RoleBinding (SA)
k -n <ns> create rolebinding <name> --role=<role> --serviceaccount=<ns>:<sa-name>

# Bind existing ClusterRole
k -n <ns> create rolebinding <name> --clusterrole=view --user=<username>

# Multiple subjects — edit existing RoleBinding
k -n <ns> edit rolebinding <name>
# Add to subjects array:
# - kind: ServiceAccount
#   name: janitor-v2
#   namespace: ops

RBAC Verbs Link to heading

VerbUsage
getread single resource
listlist resources
watchstream changes (-w flag)
createcreate resource
updatereplace whole resource
patchmodify fields (kubectl label, kubectl annotate)
deletedelete resource

Trap: kubectl label requires patch verb, NOT update Trap: k get pods -w needs both get AND watch

User vs ServiceAccount Link to heading

TypeFormatCreated by
User--user smoke or --as smokecert CN field
SA--serviceaccount ops:janitor or --as system:serviceaccount:ops:janitorSA object

No k get user — users exist only as cert CN values.

Test Permissions Link to heading

k auth can-i <verb> <resource> --as <user> -n <ns>
k auth can-i delete pods --as system:serviceaccount:ops:janitor -n ops

No Deny-RBAC in K8s Link to heading

“All namespaces except kube-*” = create RoleBinding in each non-kube namespace individually.


ServiceAccount Link to heading

Disable Token Automount Link to heading

apiVersion: v1
kind: ServiceAccount
metadata:
  name: janitor-v2
  namespace: ops
automountServiceAccountToken: false

SA Token curl Pattern Link to heading

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
kubectl exec <pod> -n <ns> -- sh -c \
  'TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token); \
   curl -sk -H "Authorization: Bearer $TOKEN" \
   https://kubernetes.default.svc/api/v1/namespaces/<ns>/secrets' \
  > /opt/course/9/result.json

Token path mnemonic: Very Resourceful Secrets, Kubernetes Is Serving Accounts Tokens


CRDs and Operators Link to heading

Install CRD and Create Custom Resource Link to heading

k apply -f /root/project-crd.yaml     # install CRD
k explain project.spec                 # discover required fields
cat /root/project-crd.yaml             # find: group + version + kind

CRD fields:

  • spec.group + spec.versions[].name → apiVersion
  • spec.names.kind → Kind (singular, capitalized)
  • spec.names.plural → resource name for kubectl
apiVersion: resource-manager.io/v1
kind: Project
metadata:
  name: web-portal
  namespace: project-a788
spec:
  team: platform
  budget: 5000
  environment: production

Operator Pattern Link to heading

  • Operator = pod/sts with kubectl baked in + SA + RBAC
  • SA token mounted → kubectl can call K8s API
  • Logic = shell commands in container command
  • StatefulSet default strategy = OnDelete → must rollout restart to apply changes

Fix Operator RBAC Link to heading

k -n <ns> logs <pod-name>             # find permission error
k edit clusterrole <name>             # add missing rule
# Add new - apiGroups entry, don't modify existing rules

Static Pods Link to heading

Move Static Pod to Another Node Link to heading

# Copy from source node
scp node01:/etc/kubernetes/manifests/resource-reserver.yaml .

# Edit (rename, change spec)
vim resource-reserver.yaml

# Place on target node manifests dir
mv resource-reserver.yaml /etc/kubernetes/manifests/

# Remove from source node
ssh node01 rm /etc/kubernetes/manifests/resource-reserver.yaml

# Verify
k get pod -A | grep <name>

Trap: Must remove from source node — otherwise pod runs on both nodes

Get Taint Key (never guess) Link to heading

k describe node <name> | grep Taint

Copy exact key into toleration YAML.


kubeadm Cluster Setup Link to heading

Init Controlplane Link to heading

kubeadm init \
  --kubernetes-version=1.35.1 \
  --pod-network-cidr 192.168.0.0/16 \
  --ignore-preflight-errors=NumCPU \
  --ignore-preflight-errors=Mem

cp /etc/kubernetes/admin.conf /root/.kube/config
  • No v prefix on version
  • --pod-network-cidr required for CNI
  • --ignore-preflight-errors always needed on KillerCoda (undersized VMs)
  • cp admin.conf before kubectl will work

Join Worker Node Link to heading

# On controlplane
kubeadm token create --print-join-command

# On worker
ssh <node>
kubeadm join <ip>:6443 --token ...
exit

k get node    # verify both Ready

Install CNI (Cilium) Link to heading

cilium install              # no --version unless question specifies
cilium status --wait        # blocks until ready
k get node                  # verify Ready

Trap: Don’t add --version from docs examples — use default


Cluster Upgrade Link to heading

Controlplane Link to heading

kubeadm upgrade plan                                    # find latest patch
apt-get install kubeadm=1.35.2-1.1                     # 1. upgrade kubeadm
kubeadm upgrade apply v1.35.2                          # 2. apply upgrade (v prefix required)
apt-get install kubectl=1.35.2-1.1 kubelet=1.35.2-1.1  # 3. upgrade kubectl+kubelet
systemctl restart kubelet                               # 4. restart kubelet
kubectl get nodes

Worker Node Link to heading

# On controlplane
k drain <node> --ignore-daemonsets

# On worker
ssh <node>
apt-get install kubeadm=1.35.2-1.1
kubeadm upgrade node                   # no version — gets from controlplane
apt-get install kubelet=1.35.2-1.1
systemctl restart kubelet
exit

# On controlplane
k uncordon <node>
k get nodes

Trap: Worker uses kubeadm upgrade node not kubeadm upgrade apply


Certificate Management Link to heading

# Check expiration
kubeadm certs check-expiration

# Renew specific cert
kubeadm certs renew apiserver
kubeadm certs renew scheduler.conf

# Verify
kubeadm certs check-expiration

# Connect to apiserver via HTTPS and capture cert info
IP=$(k get svc kubernetes -o jsonpath='{.spec.clusterIP}')
curl -k -v https://$IP:443 2>&1 | grep -A 20 "Server certificate" > /root/apiserver-https

Note: -v goes to stderr → 2>&1 required before piping