You are on page 1of 3

Setting up a master and worker node for TLS bootstrapping can be tricky because many

configuration steps are involved, so we decided to walk you through the process of enabling this
useful feature in Kubernetes. Let’s get started!
What Is TLS Bootstrapping?
Kubernetes recommends making communication between node components such as kubelet and
kube-proxy and master components private and secure. To achieve this, we need to distribute TLS
certificates for node components and sign them with the master CA. Prior to Kubernetes v1.4,
users had to do most of the TLS bootstrapping work such as issuing and distributing certificates
manually. In particular, the following steps were involved:
1. Creating a Certificate Authority (CA) key and a certificate
2. Distributing the CA certificate to the master(s)
3. Creating a certificate and a key for each kubelet.
4. Signing the kubelet certificate using the CA key on the master
5. Distributing the kubelet key and the signed certificate to the node where the kubelet will be
running
A certificate request and signing API was introduced in Kubernetes v1.4 to simplify this process.
More specifically, it automates steps 3 forward. Thus, TLS bootstrapping may be described as a
mechanism for the automatic retrieval of certificates from the API to allow newly created nodes(s)
to communicate with master(s) securely. This feature became Generally Available in Kubernetes v.
1.12.
Tutorial
For the purpose of this article, we will use kubeadm to provision a master node, create a worker
node, set up it manually, and connect to the master. Instructions on creating a single-master K8s
cluster can be found here.
Assuming that a node has been created, we need the following information:
1. master host:port
2. a bootstrap token
3. a CA certificate
First two can be obtained from the kubeadm init output down below:
1 Your Kubernetes control-plane has initialized successfully!
2
3 To start using your cluster, you need to run the following as a regular user:
4
5 mkdir -p $HOME/.kube
6 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
7 sudo chown $(id -u):$(id -g) $HOME/.kube/config
8
9 You should now deploy a Pod network to the cluster.
10 Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
11 https://kubernetes.io/docs/concepts/cluster-administration/addons/
12
13 Then you can join any number of worker nodes by running the following on each as root:
14
15
kubeadm join <master-ip>:<master-port> --token <bootstrap-token> --discovery-token-
ca-cert-hash sha256:<ca-cert-hash>
A CA cert can be found on a master node in /etc/kubernetes/pki/ca.crt , which is its default
location.
To bootstrap a new node, we need only two binaries: kubectl and kubelet .
Download those binaries from here and unpack them:
1 wget https://dl.k8s.io/v1.13.4/kubernetes-server-linux-
2 amd64.tar.gz
3 tar -xvf kubernetes-server-linux-amd64.tar.gz
4 sudo cp kubernetes/server/bin/kubelet /usr/bin
5 sudo cp kubernetes/server/bin/kubectl /usr/bin

A container runtime is also a required node component, so don’t forget to install Docker or any
other container runtime you prefer (e.g., rkt):
1 sudo apt-get update
2 sudo apt install -y docker.io
3
Next, create a folder for storing Kubernetes-related files:
1 sudo mkdir /etc/kubernetes
2 sudo mkdir
3 /etc/kubernetes/manifests
4 sudo mkdir /etc/kubernetes/pki

Copy the ca.crt from the master to /etc/kubernetes/pki


Now, we are almost prepared for the TLS bootstrapping of a new node. We do need two additional
things, though:
1. A path to kubeconfig that does not exist yet and will be stored there
after successful bootstrap: --kubeconfig
2. A path to bootstrap config: --bootstrap-kubeconfig
We can either create a bootstrap config manually using kubectl config command
or just copy the kubeconfig from a master node:
1 sudo kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-cluster
2 kubernetes --server='https://<master-host>:<master-port>' --certificate-
3 authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
4
5 sudo kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-credentials
6 tls-bootstrap-token-user --token=<bootstrap-token>
7
sudo kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-context tls-
bootstrap-token-user@kubernetes --user=tls-bootstrap-token-user --cluster=kubernetes

sudo kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig use-context tls-


bootstrap-token-user@kubernetes
The last step we need to do is to create a systemd
file in /etc/systemd/system/kubelet.service to run kubelet as a daemon.
We use the RotateKubeletClientCertificate feature gate that enables certificate rotation. This Beta
feature enables kubelet to update a certificate each time it’s going to expire.
1 [Service]
2 Restart=always
3 ExecStart=/usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubeconfig
4 \\
5 --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig \\
6 --pod-manifest-path=/etc/kubernetes/manifests \\
7 --feature-gates=RotateKubeletClientCertificate=true \\
8 --rotate-certificates
9
10 [Install]
11 WantedBy=multi-user.target

Reload systemd daemon and enable kubelet service to run on startup.


1 systemctl daemon-
2 reload
3 systemctl enable kubelet
4 systemctl start kubelet

Finally, check that node is up and running in Ready state:


1 kubectl get no
2
3 NAME STATUS ROLES AGE VERSION
4 instance-1 Ready master 15m v1.13.4
5 instance-2 Ready <none> 30s v1.13.4
Conclusion
That’s it! We have successfully enabled TLS bootstrapping of a new node. This automatic feature
makes connecting nodes to the cluster and securing their communication with the kube-apiserver
much easier. In particular, we do not need to manually create kubelet certificates and sign them
with the master certificates because this process is automatically handled by the Kubernetes TLS
API.
Below is the list of references that will help you install a single-master K8s cluster with kubeadm
and learn more about TLS bootstrapping:

You might also like