Skip to main content

CKA Exam notes

  • Don't forget to set context before each task
  • Copy + Paste is important (ctrl + shift + v | Shift + Insert)
  • Important Linux commands
    • kubectl logs >pod-name> | grep "abc" > /tmp/access-failed.txt
    • vim: "set paste" command
  • Great overview of the cluster endpoints: kubectl cluster-info

Possible Tasks

Storage

  • Create a StorageClass
  • Create a PersistentVolume
  • Create a PersistentVolumeClaim
  • Dynamic Volume Provisioning
  • Volume Types, Access Modes, Reclaim Policies
info

If the provisioner kubernetes.io/no-provisioner is used, it means that the PVs need to be created manually (static provisioning).

Scheduling

  • Applying affinity to pods
  • Applying taints to nodes
  • Applying tolerations to pods
  • Configuring and using autoscaling (VPA/HPA)
  • StatefulSets

Networking

  • Troubleshooting CoreDNS
  • Customizing DNS settings
  • Gateway API

Security

  • Enforce restricted pod security standard

3rd Party Resources

  • Helm
  • Kustomize
  • CRDs and Operators

Summary of new Exam Topics

Helm

Important commands:

  • Create new chart: helm create <chart-name>
  • Install helm chart: helm install <release-name> <chart-name> --version <version> -n <namespace>
  • Upgrade chart: helm upgrade <release-name> <chart-name> -n <namespace>
  • Uninstall chart: helm uninstall <release-name> -n <namespace>
  • View chart history: helm history <release-name> -n <namespace>
  • Rollback chart: helm rollback <release-name> <revision> -n <namespace>
  • List installed charts: helm list [-n <namespace>]
  • Search charts: helm search [repo|hub] <search-term>
  • Add repo: helm repo add <repo-name> <repo-url>
  • View chart values: helm show values <chart-name>

Kustomize

Instead of templates & variables, kustomize uses a file called kustomization.yaml to define resources and patches. It should be placed in the same directory as the resources to be managed.

Declaring resources

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Example configuration for the webserver
# at https://github.com/monopole/hello
commonLabels:
app: hello

resources:
- deployment.yaml
- service.yaml

Generate manifests

To generate manifests from a kustomization file, use the command:

kustomize build <directory-containing-kustomization>

Applying Kustomization

Can also be applied directly with kubectl:

kubectl apply -k <directory-containing-kustomization>

Multiple kustomization files

You can have multiple kustomization files in different directories to manage different sets of resources or environments. Each directory can have its own kustomization.yaml file.

Example structure (db, nginx, message-broker):

db/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
nginx/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
message-broker/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
kustomization.yaml

The top-level kustomization.yaml can reference the other directories as bases:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- db/
- nginx/
- message-broker/

Environment Overlays

You can create different overlays for different environments (e.g., dev, staging, prod) by creating subdirectories with their own kustomization.yaml files that reference the base configuration and apply environment-specific patches.

Example structure:

base/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
overlays/
├── dev/
│ └── kustomization.yaml
| └── deployment-patch.yaml
├── staging/
│ └── kustomization.yaml
| └── deployment-patch.yaml
└── prod/
└── kustomization.yaml
└── deployment-patch.yaml

kustomization.yaml in overlays/dev/ might look like:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: development
resources:
- ../../base
commonLabels:
environment: development
patches:
- path: deployment-patch.yaml
target:
kind: Deployment
name: my-app

kustomization.yaml in overlays/prod/ might look like:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- ../../base
commonLabels:
environment: production
patches:
- path: deployment-patch.yaml
target: # Not strictly necessary if the patch already specifies the target
kind: Deployment
name: my-app

The deployment-patch.yaml files would contain the specific changes for each environment like resource limits, replica counts, etc. The patch will only include the fields that need to be changed.

Example deployment-patch.yaml for dev:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
template:
spec:
containers:
- name: my-app-container
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "250m"
memory: "128Mi"

The kustomization.yaml inside the base directory may look like this:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

To apply the configuration for a specific environment, navigate to the respective overlay directory and run:

kubectl apply -k .

StatefulSets

A StatefulSet runs a group of Pods, and maintains a sticky identity for each of those Pods. This is useful for managing applications that need persistent storage or a stable, unique network identity (hostname will be the same).

Creating a StatefulSet

This creates a headless Service, nginx, to publish the IP addresses of Pods in the StatefulSet, web:

apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx" # This is necessary for StatefulSets - they need a headless service if the network identity is required
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.21
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi

PVCs

Each Pod in a StatefulSet gets its own PersistentVolumeClaim created from the volumeClaimTemplates section. The PVCs are named using the pattern <claim-name>-<statefulset-name>-<ordinal>, e.g., www-web-0, www-web-1, etc.

  • The cluster creates a PersistentVolumeClaim for each replica; you do not create a PVC yourself.
  • The cluster creates a PersistentVolume for each PVC; you do not create a PV yourself.
  • The cluster allocates storage (on AWS/EKS, for example, an EBS volume); you do not allocate the storage yourself.

Pod Priority and Preemption

Pod Priority is a feature that allows you to assign a priority level to Pods. When the cluster is under resource pressure, Pods with lower priority may be evicted to make room for higher-priority Pods.

Priority Classes

Priority classes are used to define the priority levels for Pods. You can create custom priority classes or use the default ones provided by Kubernetes.

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "This priority class is for high-priority pods."

Applying Priority Class to Pods

You can assign a priority class to a Pod by specifying the priorityClassName field in the Pod specification.

apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: my-container
image: my-image

Gateway API

Gateway API is a set of resources for managing network traffic in Kubernetes. It provides a more flexible and extensible way to handle ingress and egress traffic compared to traditional Ingress resources.

Things to remember

Dynamic env values

spec:
volumes:
- name: shared-volume
emptyDir: {}
containers:
- image: nginx:1-alpine
name: mc-pod-1
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName

Install a local package

apt install ./cri-docker_0.3.16.3-0.debian.deb or dpkg -i ./cri-docker_0.3.16.3-0.debian.deb

Start service: systemctl start cri-docker
Start on boot: systemctl enable cri-docker

Upgrade existing helm chart

  • List helm charts: helm list -n <namespace-name>
  • Update repos: helm repo update
  • Search repos: helm search repo <search-term>
  • Add repo: helm add repo <repo-name>
  • Upgrade repo: helm upgrade <release-name> <chart-name> --version <version-name> (Chart name is those from repo search)

Number of replicas wrong

If after adjusting resource quota a deployment still has not the wanted number of replicas => Delete the associated replicaset

Create PersistentVolume on a specific node

nodeAffinity has to be used to place the pv on a specific node

Enforce pod security standard

Just follow the docs: Kubernetes Docs

Fix kubeconfig

To test a kubeconfig file, use the command:

k get node --kubeconfig <kubeconfig-file>

This will help you verify if the kubeconfig is set up correctly and can communicate with the cluster.

Edit control-plane pod

To edit a control plane pod, you have to edit the static pod manifest file located in /etc/kubernetes/manifests/.

Gateway API

A Gateway in Kubernetes is a networking resource that controls external traffic into a cluster, supporting HTTP, HTTPS, TCP, and UDP protocols.

  • Create GatewayClass (implementation of the Gateway object)
  • Create Gateway (defines how traffic is managed through listeners)
  • Create Route (defines how traffic is routed)