Skip to main content

Bootstrapping the control plane

With the master node prepped, one command brings the control plane to life:

kubeadm init \
  --apiserver-advertise-address=10.100.100.7 \
  --pod-network-cidr=192.168.0.0/16

Two flags matter:

  • --apiserver-advertise-address pins the API server to the node's private IP. On a multi-homed box you don't want it guessing.
  • --pod-network-cidr declares the range pods will get addresses from. I used 192.168.0.0/16 because that's Calico's default — picking the CNI's default here means one less thing to reconfigure later.

When it finishes, kubeadm prints two things you care about: the commands to set up your kubectl config, and a kubeadm join command (with a token and a CA hash) for adding workers. The join token is a short-lived secret — treat it like a password (here it's <REDACTED>).

Set up access for your user:

mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

At this point kubectl get nodes shows the master as NotReady. That's expected and not a bug: there's no network layer yet, so the node can't host pods. It goes Ready the moment Calico is installed (next pages).