11
votes

I created a Kubernetes cluster a few days ago with 1 Master and 1 worker Node. Now I want to add another node to the cluster, but the token printed by the original "kubeadm init" on the master has expired (by default after 24 hours).

The "kubeadm join" command have a "--discovery-file". It takes a config file and I have tried with the format I found here:

https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.8.md

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <really long certificate data>
    server: https://10.138.0.2:6443
  name: ""
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []

I copied the corresponding data from my working kubectl config file and created a local file "a.config".

But, when I try the command "sudo kubeadm join --discovery-file a.conf" it fails with the following error messages:

[discovery: Invalid value: "": token [""] was not of form ["^([a-z0-9]{6})\\.([a-z0-9]{16})$"], discovery: Invalid value: "": token must be of form '[a-z0-9]{6}.[a-z0-9]{16}']

What am I missing here?

What is a procedure know to work in my situation? I prefer not to tear down the cluster and re-join it again.

4

4 Answers

20
votes

The easiest way i know to join new nodes to existing cluster is

kubeadm token create --print-join-command

this will give output like this.

kubeadm join 192.168.10.15:6443 --token l946pz.6fv0XXXXX8zry --discovery-token-ca-cert-hash sha256:e1e6XXXXXXXXXXXX9ff2aa46bf003419e8b508686af8597XXXXXXXXXXXXXXXXXXX
17
votes

Create a new bootstrap token and join

Use kubeadm token create to create a new bootstrap token, See kubeadm: Managing Tokens.

# login to master node
# create a new bootstrap token
$ kubeadm token create
abcdef.1234567890abcdef

# get root ca cert fingerprint
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
e18105ef24bacebb23d694dad491e8ef1c2ea9ade944e784b1f03a15a0d5ecea 

# login to the new worker node
# join to cluster 
$ kubeadm join --token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:e18105ef24bacebb23d694dad491e8ef1c2ea9ade944e784b1f03a15a0d5ecea 1.2.3.4:6443

Note: --discovery-token-ca-cert-hash is preferred in Kubernetes 1.8 and above.

(Alternative) Use discovery file to establish trust

--discovery-file provides an out-of-band way to establish a root of trust between the master and bootstrapping nodes.

Consider using this mode if you are building automated provisioning using kubeadm.

The discovery file does not provide a valid token, so we still need kubeadm token create to create a new one.

kubeadm join --token abcdef.1234567890abcdef --discovery-file a.conf
0
votes

Thanks for @silverfox's answer, but it's still a little painful for typing these commands manaually, so I build the following command to help me do this much quickly.

This command will create a token and generate the joining command:

echo sudo kubeadm join $(kubeadm config view | grep ^controlPlaneEndpoint | awk '{print $2}') --token $(kubeadm token create) --discovery-token-ca-cert-hash sha256:$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //')
0
votes

As suggested above in Mansur's answer, was able to run the following commands to set up the cluster.

# command ran from master node:
kubeadm token create --print-join-command

# sample output
kubeadm join <IP_OF_MASTER_NODE>:6443 --token iic9jq.<redacted> --discovery-token-ca-cert-hash <redacted>

Ran the output from above in the other node with sudo-

sudo kubeadm join <IP_OF_MASTER_NODE>:6443 --token iic9jq.<redacted> --discovery-token-ca-cert-hash <redacted>

When I was running the above command without sudo, was getting the error-

[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR IsPrivilegedUser]: user is not running as root
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`

When I ran with sudo, got this success message:


This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

Ran kubectl get nodes from the master node and saw that the new node has joined the cluster.

Before running the above commands the cluster state was like the following-

# ran on master node
$ kubectl get nodes
NAME            STATUS     ROLES    AGE   VERSION
ip-[REDACTED]   NotReady   master   20m   v1.14.5

After running the above commands the cluster state was like the following:

# ran on master node
kubectl get nodes
NAME            STATUS     ROLES    AGE   VERSION
ip-[REDACTED]   NotReady   master   20m   v1.14.5
ip-[REDACTED]   NotReady   <none>   14s   v1.14.5