Feeling uncertain about things? Go through my How to become a CKAD guide as it will provide you with all the little details necessary for managing Pod
s, Deployment
s, etc.
Also, if you are in need of a PSI bridge (the browser you will use during the CKA exam) simulator, feel free to use this one: https://github.com/42eleven/cncf-psi-k8s-linux-simulator.
Grow an understanding of how to roll out a cluster
And by rolling out I mean from scratch with kubeadm
. Still that’s considered “the easy way”, but at least it’s a more hands-on experience that clicking on the AWS UI to bootstrap an EKS cluster control plane.
Understand the components and the steps this process entails.
Some components useful here or later on in general:
containerd
: your container runtime. Needs to be installed on all your nodes, control-plane and workers.kubeadm
: a tool to help you provision k8s clusters.kubelet
: the kubernetes agent running on each of your nodes.kubectl
: the kubernetes cli management tool.etcdctl
: the etcd database cli management tool.journalctl
andsystemctl
for managing and inspecting system processes, logs, etc.crictl
for managing containers inside nodes
At this point, I can say this: you are in luck, because the official documentation has a guide for this exact process: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
Network Policies
Honestly, the best advice I can give you for NetworkPolicy
objects is to go through the official docs and run a couple of examples on your own. This was the part which I had worked the least with and I found it pretty hard, but once I understood (and remembered) the conditions logic in their spec, everything made sense.
Link to official docs: https://kubernetes.io/docs/concepts/services-networking/network-policies/
Upgrading control-plane and worker nodes with Kubeadm
Control plane
- Install new version of
kubeadm
, eg.1.22.2
sudo apt-get update && \
sudo apt-get install -y --allow-change-held-packages kubeadm=1.22.2-00
- Drain node
kubectl drain <node-name> --ignore-daemonsets
- Plan the upgrade
sudo kubeadm upgrade plan v1.22.2
- Apply the upgrade
sudo kubeadm upgrade apply v1.22.2
- Upgrade
kubelet
andkubectl
sudo apt-get install -y --allow-change-held-packages kubelet=1.22.2-00 kubectl=1.22.2-00
- Reload
sudo systemctl daemon-reload
- Restart
kubelet
for the changes to take effect
sudo systemctl restart kubelet
- Uncordon node
kubectl uncordon <node name>
Worker
- Drain the node
kubectl drain <node-name> --ignore-daemonsets
- Install new version of
kubeadm
sudo apt-get install -y --allow-change-held-packages kubeadm=1.22.2-00
- Upgrade the node
sudo kubeadm upgrade node
- Upgrade
kubelet
andkubeadm
sudo apt-get install -y --allow-change-held-packages kubelet=1.22.2-00 kubectl=1.22.2-00
- Reload system
sudo systemctl daemon-reload
- Restart
kubelet
sudo systemctl restart kubelet
- Uncordon node
kubectl uncordon <node name>
etcd backup and restore
Backup
After SSHing into the node, pin the eksctl api version via an env variable:
export ETCDCTL_API=3
Then backup the etcd data:
etcdctl snapshot save /home/user/etcd_backup.db \
--endpoints=https://etcd1:2379 \
--cacert=/home/user/etcd-certs/etcd-ca.pem \
--cert=/home/user/etcd-certs/etcd-server.crt \
--key=/home/user/etcd-certs/etcd-server.key
Restore
In order to restore etcd data from the backup, follow this process:
- Stop the
etcd
service
sudo systemctl stop etcd
- Delete existing data
sudo rm -rf /var/lib/etcd
- Restore data from the snapshot
etcdctl snapshot restore /home/user/etcd_backup.db \
--initial-cluster etcd-restore=https://etcd1:2380 \
--initial-advertise-peer-urls https://etcd1:2380 \
--name etcd-restore \ # change
--data-dir /var/lib/etcd
- Set the database ownership to the
etcd
user
sudo chown -R etcd:etcd /var/lib/etcd
- Start the
etcd
service again
sudo systemctl start etcd
This process might need to be adjusted depending on how
etcd
has been set up. Eg. if it’s set up as a static pod, you might need to go into/etc/kubernetes/manifests/etcd-config-file.yaml
and edit the path or something similar.
Docs ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
RBAC
Creating Service Accounts, Roles and RoleBindings
Be smart as always and create your SA easy and fast by using imperative kubectl
commands.
No worries if you don’t remember the arguments for each one. Just use the
--help
flag to get you started, eg.kubectl create sa --help
and you’ll see all the flags supported as well as common examples.
Example:
kubectl -n <namespace> create sa <name of SA> --dry-run=client -o yaml > sa.yaml
The same things, in an analogy, apply for Role
, RoleBinding
, ClusterRole
and ClusterRoleBinding
objects.
Figuring out control plane node information
You should be comfortable navigating into a Linux machine/cluster node and be able to figure out various ways a component can be set up and configured.
Some ideas to get you started:
- Look into
/etc/kubernetes/manifests
for static pods ps awx | grep kube
to get any processes running in the system withkube
in their name, eg.kubelet
- Look into the
kube-system
namespace pods withkubectl -n kube-system get pods | grep kube
Understand static pods
Pods are managed by the kube api server. However, static pods are bound and managed by kubelet on a node. A static pod is specifically bound on a node. Kubelet creates a mirror pod and if it fails it’s restarted (again, by kubelet).
Manifests for static pods are stored in /etc/kubernetes/manifests
. Therefore, for whatever components you find *.yaml
laying out there, these are static pods.
Static pods contain their node’s name with a leading hyphen as a suffix. Eg. in a node named cluster2-node5
a static pod named test
will have this name: test-cluster2-node5
.
Advanced scheduling
Remember to use kubernetes.io/hostname
as a topology key when implementing a podAntiAffinity
. (Docs ref)
The topologyspreadconstraint
is another very valid method to spread pods across nodes if you need to simulate DaemonSet
’s functionality with a Deployment
. (Docs ref)
Environment variables
You can add simple key-value objects in the env, or you can dynamically fetch eg. node-specific info. The following example does both.
In the pod spec:
...
spec:
env:
- name: foo
value: bar
- name: MY_NODE
valueFrom:
fieldRef:
fieldPath: spec.nodeName
...
DaemonSets
DaemonSets
will make sure a pod of this daemonset will run on each node of the cluster.
You might be asked to create a DaemonSet
object, but fear not! You can imperatively create a Deployment
object, get rid of the spec.replicas
and replace Deployment
with DaemonSet
.
Read more in the official docs: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
Services and Ingresses
Services
Understand the differences between the different service types:
- NodePort: each node will have a specific port assigned to bind and listen to for that service.
- ClusterIP: exposes the service on a cluster-internal IP.
- LoadBalancer: creates a load balancer on your cloud provider.
Bonus:
- ExternalName (external DNS managing this service)
Exam tip:
NodePort
andClusterIP
will be the ones mostly used during the exam, so make sure you know really well how to imperatively create them.
Ingresses
An ingress essentially lets services interact with the internet.
The basic info to remember is this:
- you can configure
hosts
which will correspond to this ingress - you can back a
Service
(or multiple) as a backend on that ingress. The key here is to remember an ingress’ service is namedbackend
- optional
tls
config
Ingresses are managed by Ingress Controllers. I don’t know if this type of controller is CKA material, but it doesn’t hurt to get a good understanding of how they work and what they do.
Exam tip: you will save up a lot of time if you know how to imperatively create them. Always remember to append
-o yaml > ingress.yaml
so that you can easily edit it if needed or if you don’t feel comfortable adding fancier path rules in the terminal.
More info:
- https://kubernetes.io/docs/concepts/services-networking/ingress/
- https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
General things to remember
- Don’t get spooked by the time pressure. It took me about 45mins to complete the exam (passed with 92/100) and then spent another 15mins just checking around my answers in order to kill some more time. If you’re working with K8s on your day job, you won’t have to blink twice.
- It’s easier than advertised. Caveat: you need to have a good understanding of what you do and try not to memorize a process/multi-step method just for the exam.
- Yes,
ctrl+shift+c
andctrl+shift+v
work out of the box. alias k=kubectl
already exists in your exam machine- Remember to ALWAYS set the correct context. They provide you at the beginning of each question the command to set the correct context. Don’t think about it, just copy and paste it in your terminal.
- Look up the docs! You can use
k8s.io/docs
, take advantage of the search function! - People say they use VSCode and it’s allowed. I find this cumbersome to use a UI editor when managing K8s objects, especially in a simulator. Do what’s most comfortable for you, but would probably be a good idea to stay in your terminal and potentially make
vim
your best friend.
Good luck!