[Kubernetes (K8S) Kubespray] Use Kubespray to add or remove control-plane,master node into the exist kubernetes (K8S) cluster

Add or remove control-plane,master node into the exist kubernetes (K8S) cluster

This still be the easiest with Kubespray.

Usages

First, check current all node status(2 nodes, 2 control-plane,master nodes):

1
2
3
4
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready control-plane,master 3d16h v1.21.4
node2 Ready control-plane,master 3d16h v1.21.4

Add a new control-plane,master node

Add the new control-plane,master into kubernetes (K8S) cluster.

1) Add a new node to the inventory

Edit inventory/mycluster/hosts.yaml file to add node3 host.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
all:
hosts:
node1:
ansible_host: 192.168.8.90
ip: 192.168.8.90
access_ip: 192.168.8.90
ansible_user: root
node2:
ansible_host: 192.168.8.91
ip: 192.168.8.91
access_ip: 192.168.8.91
ansible_user: root
# add new node3
node3:
ansible_host: 192.168.8.92
ip: 192.168.8.92
access_ip: 192.168.8.92
ansible_user: root
children:
kube_control_plane:
hosts:
node1:
node2:
# add new node3
node3:
kube_node:
hosts:
node1:
node2:
# add new node3
node3:
etcd:
hosts:
node1:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
hosts: {}

2) Run cluster.yml

Run ansible-playbook command with cluster.yml and --limit=node3.

1
$ ansible-playbook -i inventory/mycluster/hosts.yaml cluster.yml

Append the new host to the inventory and run cluster.yml. You can NOT use scale.yml for that.


3) Restart Docker or kube-system/nginx-proxy

In all hosts, restart docker or reboot the host. Kubespray will update its static config, but it needs to be restarted in order to reload.

1
2
3
4
# systemctl restart docker

# Or reboot host
# reboot

4) Check current node status

check current all node status(3 nodes, 3 control-plane,master nodes):

1
2
3
4
5
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready control-plane,master 3d16h v1.21.4
node2 Ready control-plane,master 3d16h v1.21.4
node3 Ready control-plane,master 5m16s v1.21.4

Remove the control-plane,master node

Remove the control-plane,master node from kubernetes (K8S) cluster.

1) Run remove-node.yml

Run ansible-playbook command with remove-node.yml and --e=node=node3.

1
$ ansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml -e node=node3

With the old node still in the inventory, run remove-node.yml. You need to pass -e node=NODE_NAME to the playbook to limit the execution to the node being removed. If the node you want to remove is not online, you should add reset_nodes=false and allow_ungraceful_removal=true to your extra-vars.


2) Check current node status

Check current all node status(2 nodes, 2 control-plane,master nodes, without work node):

1
2
3
4
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready control-plane,master 3d16h v1.21.4
node2 Ready control-plane,master 3d16h v1.21.4

1) Remove the control-plane,master from the inventory

Edit inventory/mycluster/hosts.yaml file to remove node3 host.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
all:
hosts:
node1:
ansible_host: 192.168.8.90
ip: 192.168.8.90
access_ip: 192.168.8.90
ansible_user: root
node2:
ansible_host: 192.168.8.91
ip: 192.168.8.91
access_ip: 192.168.8.91
ansible_user: root
children:
kube_control_plane:
hosts:
node1:
node2:
kube_node:
hosts:
node1:
node2:
etcd:
hosts:
node1:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
hosts: {}

FAQs

Check apiserver Certificate

1
2
# On all nodes, check apiserver Certificate.
$ openssl x509 -text -noout -in /etc/kubernetes/ssl/apiserver.crt

Update apiserver Certificate

1
2
3
4
# On control-plane,master nodes
$ cd /etc/kubernetes

$ kubeadm init phase certs apiserver --config kubeadm-config.yaml

error downloading certs

1
error execution phase control-plane-prepare/download-certs: error downloading certs: error downloading the secret: Secret \"kubeadm-certs\" was not found in the \"kube-system\" Namespace. This Secret might have expired. Please, run `kubeadm init phase upload-certs --upload-certs` on a control plane to generate a new one

Manually upload Certificate.

1
2
# On control-plane,master nodes
$ kubeadm init phase upload-certs --upload-certs

Run reset.yml

If you are doing this after you ended up with a broken master, be sure to run reset.yml using the parameter --limit=<broken_master_hostname> before continuing. If you take the precaution of recreating the certificate before adding the new master node, you won’t need this.

Run ansible-playbook command with reset.yml and --limit=node3.

1
$ ansible-playbook -i inventory/mycluster/hosts.yaml reset.yml --limit=node3

You should use --limit=NODE_NAME to limit Kubespray to avoid disturbing other nodes in the cluster.


References

[1] Adding/replacing a node - https://kubespray.io/#/docs/nodes

[2] Unable to add new master/etcd node to cluster · Issue #3471 · kubernetes-sigs/kubespray - https://github.com/kubernetes-sigs/kubespray/issues/3471

[3] Getting started - https://kubespray.io/#/docs/getting-started

[3] kubernetes-sigs/kubespray: Deploy a Production Ready Kubernetes Cluster - https://github.com/kubernetes-sigs/kubespray

[4] Deploy a Production Ready Kubernetes Cluster | Readme - https://kubespray.io/

[5] Ansible is Simple IT Automation - https://www.ansible.com/

[6] Kubernetes - https://kubernetes.io/