CKA Imperative Commands — Full Reference Link to heading

Pods Link to heading

# Basic pod
k run web --image nginx

# With labels
k run app --image node:18 --labels tier=frontend,env=dev

# With command
k run runner --image busybox --command -- sleep 7200

# With env vars
k run api --image python:3.11 --env DEBUG=true --env PORT=8080

# With port
k run backend --image redis:7 --port 6379

# With service account
k run web --image nginx --port 80 --env ENV=prod --labels app=foo --serviceaccount my-sa

# In namespace
k run api --image nginx -n production

# Generate YAML
k run web --image nginx $do

# Force delete
k delete pod web --now

# Exec into pod
k exec -it web -- sh
k exec -it web -c <container> -- sh

# Logs
k logs web
k logs web -c <container>
k logs web --previous
k logs web -f

# Top
k top pods
k top pods -n <namespace>
k top nodes

Temp Pods (Connectivity Testing) Link to heading

# Single command — use -i only (NOT -it)
k run tmp -i --rm --restart Never --image nginx:alpine -- curl http://<svc>:<port>

# wget (busybox)
k run tmp -i --rm --restart Never --image busybox -- wget -O- http://<svc>:<port>

# nc raw TCP test
k run tmp -i --rm --restart Never --image busybox -- nc -zv <svc> <port>

# Save output to file
k run tmp -i --rm --restart Never --image nginx:alpine -- curl http://<svc>:<port> > /path/to/file

# Source pod already exists
k exec <pod> -- curl http://<svc>:<port>
k exec <pod> -- nc -zv <svc> <port>

Deployments Link to heading

# Create
k create deploy nginx --image nginx

# With replicas
k create deploy nginx --image nginx --replicas 3

# With port
k create deploy nginx --image nginx --port 80

# Scale
k scale deploy nginx --replicas 5

# Set image
k set image deploy nginx nginx=nginx:1.21

# Rollout status
k rollout status deploy nginx

# Rollout history
k rollout history deploy nginx

# Rollback to previous
k rollout undo deploy nginx

# Rollback to specific revision
k rollout undo deploy nginx --to-revision 2

# Restart — forces pod recycle (required after ConfigMap/Secret env var changes)
k rollout restart deploy nginx
k rollout restart daemonset nginx
k rollout restart statefulset nginx

# Pause / resume (hold rollout mid-way)
k rollout pause deploy nginx
k rollout resume deploy nginx

# Generate YAML
k create deploy nginx --image nginx $do

Services Link to heading

# Expose
k expose <resource> <name> --name <svc-name> --type <type> --port <port> --target-port <target-port>

# Examples
k expose pod web --name web-svc --type ClusterIP --port 80 --target-port 8080
k expose deploy nginx --name nginx-svc --type NodePort --port 80 --target-port 80
k expose deploy app --name app-svc --type LoadBalancer --port 443 --target-port 8443

# Debug: check endpoints (none = selector mismatch)
k get endpoints <svc>
k get ep <svc>

# Blue/Green switch
k edit svc my-svc #change selector

ConfigMaps Link to heading

# From literal
k create cm app-config --from-literal key=value
k create cm app-config --from-literal DB_HOST=mysql --from-literal DB_PORT=3306

# From file
k create cm app-config --from-file config.properties

# From file with key
k create cm app-config --from-file=index.html=/usr/file/nginx/html

# Generate YAML
k create cm app-config --from-literal key=value $do

# Inspect
k get cm app-config -o yaml
k describe cm app-config

Secrets Link to heading

# Generic (opaque)
k create secret generic db-secret --from-literal password=mysecret
k create secret generic db-secret --from-literal user=admin --from-literal password=pass123

# From file
k create secret generic tls-secret --from-file cert.pem

# TLS secret
k create secret tls tls-secret --cert /path/to/tls.crt --key /path/to/tls.key

# Docker registry
k create secret docker-registry regcred \
 --docker-server <registry> \
 --docker-username <user> \
 --docker-password <pass>

# Inspect
k get secret db-secret -o yaml
k get secret db-secret -o jsonpath='{.data.password}' | base64 -d

# SA token extraction
k get secret <secret-name> -o jsonpath='{.data.token}' | base64 -d > /path/to/file

ServiceAccounts Link to heading

# Create
k create sa my-sa

# Describe
k describe sa my-sa

# Verify auth as SA
k auth can-i get pods --as=system:serviceaccount:<namespace>:<sa-name>

RBAC — Roles and RoleBindings Link to heading

# Create Role
k create role pod-reader --verb get,list,watch --resource pods
k create role dev-role --verb get,list,create --resource pods,deployments,services

# Create RoleBinding — user
k create rolebinding pod-reader-binding --role pod-reader --user jane

# Create RoleBinding — group
k create rolebinding dev-binding --role dev-role --group developers

# Create RoleBinding — ServiceAccount
k create rolebinding sa-binding --role pod-reader --serviceaccount default:my-sa

# Generate YAML
k create role pod-reader --verb get,list,watch --resource pods $do

# Verify
k auth can-i get pods --as=jane
k auth can-i list secrets --as=jane

RBAC — ClusterRoles and ClusterRoleBindings Link to heading

# Create ClusterRole
k create clusterrole node-reader --verb get,list,watch --resource nodes
k create clusterrole pv-reader --verb get,list,watch --resource persistentvolumes

# Create ClusterRoleBinding — user
k create clusterrolebinding node-reader-binding --clusterrole node-reader --user kevin

# Create ClusterRoleBinding — group
k create clusterrolebinding dev-binding --clusterrole deploy-viewer --group developers

# Create ClusterRoleBinding — ServiceAccount
k create clusterrolebinding sa-binding --clusterrole secret-admin --serviceaccount security:vault-sa

# Generate YAML
k create clusterrole node-reader --verb get,list,watch --resource nodes $do

# Verify
k auth can-i list nodes --as=kevin
k auth can-i get pods --as=system:serviceaccount:security:vault-sa

--role → RoleBinding only. --clusterrole → ClusterRoleBinding only. --serviceaccount=namespace:name — colon separator, no -n flag. No -n on ClusterRole/ClusterRoleBinding (cluster-scoped).

Jobs Link to heading

# Create
k create job my-job --image busybox -- echo hello

# From CronJob (manual trigger)
k create job manual-run --from cronjob/<cronjob-name>

# Generate YAML
k create job my-job --image busybox -- echo hello $do

# Monitor
k get jobs
k get pods -l job-name=my-job
k logs <job-pod-name>
# Job spec fields (add to YAML after $do export):
spec:
  completions: 3 # total successful pod runs required
  parallelism: 2 # how many pods run simultaneously
  backoffLimit: 4 # retries before job marked failed
  activeDeadlineSeconds: 30 # timeout for entire job — hard kill
  ttlSecondsAfterFinished: 60 # auto-delete job N seconds complete
  suspend: false # pause job if true

restartPolicy: Never required — in template.spec, not spec.

CronJobs Link to heading

# Create
k create cronjob my-cron --image busybox --schedule "*/5 * * * *" -- echo hello

# Common schedules
*/5 * * * * # Every 5 min
0 * * * * # Every hour
0 0 * * * # at midnight every
0 6 * * *. # Daily 6am
0 */2 * * * # every two hours

# Generate YAML
k create cronjob my-cron --image busybox --schedule "*/5 * * * *" -- echo hello $do

# Monitor
k get cronjobs
k get jobs
spec:
  concurrencyPolicy: Allow
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  startingDeadlineSeconds: 60
  suspend: false

successfulJobsHistoryLimit / failedJobsHistoryLimit — prose only in docs.

Namespaces Link to heading

k create ns production
k get ns
k config set-context --current --namespace <namespace>
k config set-context --current --namespace default

Labels and Annotations Link to heading

# Labels
k label pod web env=prod
k label pod web env=dev --overwrite
k label pods -l type=worker env=prod # add label env=prod to pods labeled type=worker
k label pod web env- # remove label with KEY env

k get pods -l env=prod # return pods with label
k get pods -l env=prod,tier=frontend # return pods with BOTH labels
k get pods --show-labels

# Annotations
k annotate pod web team=backend
k annotate pod web team=frontend --overwrite
k annotate pods -l env=prod owner=kevin

Taints and Tolerations Link to heading

k taint node node1 key=value:NoSchedule
k taint node node1 key=value:NoExecute
k taint node node1 key=value:PreferNoSchedule
k taint node node1 key=value:NoSchedule-
k describe node node1 | grep Taint

Helm (Exam = v3) Link to heading

helm repo add <name> <url>
helm repo update
helm repo list
helm search repo <repo/chart>
helm search repo <repo/chart> --versions
helm show values <repo/chart>
helm install <release> <repo/chart>
helm install <release> <repo/chart> --set key=value
helm install <release> <repo/chart> --version 1.2.3
helm install <release> <repo/chart> -f values.yaml
helm list
helm list -A
helm upgrade <release> <repo/chart> --version 2.0.0
helm upgrade <release> <repo/chart> --set key=value
helm history <release>
helm rollback <release> <revision>
helm uninstall <release>
helm get values <release>

Kevin’s cluster = Helm v4. Exam = v3. Use -n <ns> not -A on exam.

Docker / Podman Link to heading

docker build -t <registry>/<image>:<tag> .
podman build -t <registry>/<image>:<tag> .
docker push <registry>/<image>:<tag>
podman push <registry>/<image>:<tag>
docker run -d --name <n> <image>
podman run -d --name <n> <image>
docker logs <n>
podman logs <n>
docker save -o /path/image.tar image:tag # docker does not save OCI

# Save OCI archive (Podman) — tags stripped on load, must retag
podman save --format oci-archive -o /path/to/archive.tar <image>:<tag>
podman load -i /path/to/archive.tar
podman tag <image-id> <name>:<tag>

# docker buildx export
docker buildx build --output type=docker,dest=/path/to/archive.tar .
docker buildx build --output type=oci,dest=/path/to/archive.tar .

crictl — Key Commands Link to heading

crictl ps # list containers
crictl ps -a # all containers including stopped
crictl inspect <container-id> #full contianer details
crictl info # runtime info
crictl pods # list pods
crictl images # list images
crictl logs <container-id> # container logs
crictl exec -it <id> sh # exec into container

Debugging Link to heading

k get pods
k get pods -o wide
k describe pod <n>
k events --sort-by .lastTimestamp
k get endpoints <svc>
k top pods
k top nodes
k auth can-i <verb> <resource>
k auth can-i <verb> <resource> --as <user>
k auth can-i <verb> <resource> --as=system:serviceaccount:<ns>:<sa>

jsonpath Link to heading

k get pod web -o jsonpath='{.metadata.name}'
k get pod web -o jsonpath='{.status.podIP}'
k get node node1 -o jsonpath='{.status.nodeInfo.osImage}'
k get pods -o jsonpath='{.items[*].metadata.name}'
k get pod web -o jsonpath='{.spec.containers[0].image}'
k get secret <n> -o jsonpath='{.data.token}' | base64 -d
k get secret <n> -o jsonpath='{.data.token}' | base64 -d > /path/to/file
k get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
k get pods -o custom-columns="NAME:.metadata.name,STATUS:.status.phase"
k get pods -o custom-columns="NAME:.metadata.name,QOS:.status.qosClass"

jsonpath = YAML with dots instead of indentation, [n] for list positions.

Ingress Pre-flight Link to heading

k get ingressclass
k get svc
k get svc -A | grep -i ingress

Ingress Link to heading

# Single path
k create ingress <name> --rule="/wear=wear-service:80"

# Multiple paths
k create ingress <name> --rule="/wear=wear-service:80" --rule="/watch=video-service:80"

# Host-based
k create ingress <name> --rule="wear.mystore.com/=wear-service:80"

# With TLS (secret: app-tls)
k create ingress <name> --rule="wear.mystore.com/=wear-service:80,tls" --class nginx

# View
k get ingress
k get ingress -n <namespace>
k describe ingress <name>

rewrite-target — strip path before forwarding to backend: add annotation: nginx.ingress.kubernetes.io/rewrite-target: /

Kustomize Link to heading

kustomize build <dir>
kubectl apply -k <dir>
kustomize build <dir> | kubectl apply --dry-run=client -f -