Highly available control planes
Stacked or external etcd, quorum math, a load balancer in front of the API servers, and the kubeadm flags that add more control plane nodes.
Key ideas in this lesson · tap one for a simple explanation
What you will be able to do
- Explain stacked and external etcd, and say how many failures three or five etcd members survive.
- Start a cluster with a load-balanced controlPlaneEndpoint and join more control plane nodes with --control-plane and --certificate-key.
- Read how an existing cluster's control plane is laid out, from the kubeadm-config ConfigMap and the API server's flags.
A highly available (HA) keeps working when one control plane machine dies. You get it by running the control plane on three machines instead of one. Example: your cluster has one control plane and its disk fails. Running apps keep going, but nobody can deploy, scale or fix anything until it is back. With three control plane nodes, the other two carry on.
This lesson covers the exam topic Implement and configure a highly-available control plane. The exam will not make you build a load balancer. It can ask you to join another control plane node, or to say how many members may fail. It can also ask how a cluster is laid out.
Clients
kubectl, kubelets and joining nodes
Load balancer
the controlPlaneEndpoint
k8s-api.lab.internal:6443
Three control plane nodes
cp1
API server, etcd, scheduler, controller manager
cp2
the same
cp3
the same
Everyone uses one address, the load balancer. It passes each request to any healthy API server.
What has to be redundant
In an HA cluster, each control plane part runs on several machines. But the copies work together in different ways:
Quorum: why three members, not two or four
Quorum means a majority of the etcd members. etcd saves a write only once a has it. The formula is floor(n/2) + 1: half the members, rounded down, plus one. Example: with 3 members, quorum is 2, so 1 member can fail.
- Even numbers add nothing. 4 members survive 1 failure, the same as 3, with one more machine that can break. 2 members are worse than 1.
- Run 3, or 5 if you must survive 2 failures. More members make every write wait for more machines.
- When quorum is lost, nothing can change. The API server cannot save anything. Running keep running, but you cannot create, change or delete objects.
| Members | Quorum | Can lose |
|---|---|---|
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
Stacked or external etcd
There are two ways to place etcd. Stacked: each control plane node also runs an etcd member, so 3 machines give you 3 API servers and 3 etcd members. This is what builds by default. External: etcd runs on its own machines, so the same takes 6 machines.
Building it with kubeadm
You build an HA cluster with the same kubeadm init and kubeadm join as a normal one, plus four flags:
# First control plane. The endpoint is the load balancer's DNS name (or VIP) and port.
sudo kubeadm init \
--control-plane-endpoint "k8s-api.lab.internal:6443" \
--upload-certs \
--pod-network-cidr=192.168.0.0/16
# kubeadm prints two join commands. The control plane one adds two flags:
sudo kubeadm join k8s-api.lab.internal:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
# Two hours later the uploaded certificates are gone. On an existing control plane:
sudo kubeadm init phase upload-certs --upload-certs # prints a new key
sudo kubeadm token create --print-join-command --certificate-key <new-key>controlPlaneEndpoint is the one address that every , and joining node uses. Set it on day one, even with a single control plane node: kubeadm cannot turn a cluster built without it into an HA one later. On this kind lab it is cka-control-plane:6443.
With external etcd you use a config file instead of flags. Only the etcd part differs:
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controlPlaneEndpoint: "k8s-api.lab.internal:6443"
etcd:
external:
endpoints:
- https://10.0.0.21:2379
- https://10.0.0.22:2379
- https://10.0.0.23:2379
# plus caFile, certFile and keyFile: the client certificate the API server uses for etcdReading an existing cluster's layout
Exam questions about HA are mostly about reading. kubeadm saved its choices in the kubeadm-config , and the API server's flags show which etcd members it uses:
# What kubeadm decided at init time
kubectl -n kube-system get cm kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' | grep '^controlPlaneEndpoint:'
kubectl -n kube-system get cm kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' | grep -A3 '^etcd:'
# Which etcd members the API server uses (one argument per line, so commas stay intact)
kubectl -n kube-system get pod -l component=kube-apiserver \
-o jsonpath='{range .items[0].spec.containers[0].command[*]}{@}{"\n"}{end}' | grep -- --etcd-servers
# Control plane nodes and their Pods
kubectl get nodes -l node-role.kubernetes.io/control-plane
kubectl -n kube-system get pods -l tier=control-plane -o wideIn the official docs· open on exam day too
- Options for Highly Available Topologysearch: ha topology
- Creating Highly Available Clusters with kubeadmsearch: highly available kubeadm
- Set up a High Availability etcd Cluster with kubeadmsearch: high availability etcd kubeadm
Describe this cluster's control plane layout
host:port, to /tmp/cka/ar-cp-endpoint.txt. (2) The etcd topology, as the single word stacked or external, to /tmp/cka/ar-etcd-topology.txt. (3) The full value of kube-apiserver's --etcd-servers flag to /tmp/cka/ar-etcd-servers.txt. (4) If this cluster were grown to five control plane nodes with the same etcd topology, how many etcd members could fail at once without losing quorum? Write the number to /tmp/cka/ar-etcd-tolerance.txt.Cluster:kubectl config use-context kind-cka
- 1
Set up the scenario
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-ha-1/setup | bash - 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-ha-1/verify | bashGot FAIL? Read which check failed, fix it, run it again. - 4
Clean up (optional)
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-ha-1/cleanup | bash
Join a third control plane node
k8s-api.lab.internal:6443. Control plane nodes cp1 and cp2 run stacked etcd. Node cp3 is prepared with containerd and v1.37 packages and is already in the load balancer's backend pool. Join cp3 as a third control plane node. The cluster was initialized days ago, so neither its bootstrap token nor its certificate key is valid anymore. You work on cp1; ssh cp3 reaches the new node.Runs on a kubeadm cluster (VM lab), not on the kind lab.
- 1
Start from a healthy lab
No setup needed for this one.
- 2
Solve it in your terminal
Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under
/tmp/cka/. - 3
Check your work
curl -fsSL https://codewithmuh.com/labs/cka/t/ar-ha-2/verify | bashGot FAIL? Read which check failed, fix it, run it again.
Finished this lesson?
0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.