How to display command to join Kubernetes cluster

Display command to join the Kubernetes cluster.

Use new token

Create a new token that will be valid for next 30 minutes and display the full command needed to join this cluster.

kube@kubernetes:~$ kubeadm token create --print-join-command --ttl 30m
kubeadm join 172.16.30.120:6443 --token slp3mo.o0sxw308q3xj4l1n --discovery-token-ca-cert-hash sha256:350192ceb34c2b3a66e43b4f177065d98b90215d8ea0cc9e99367a628a69ee7f

Inspect this token.

kube@kubernetes:~$ kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
slp3mo.o0sxw308q3xj4l1n   29m         2020-07-22T16:29:48Z   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token
# kubectl -n kube-system get secret bootstrap-token-slp3mo
NAME                     TYPE                            DATA   AGE
bootstrap-token-slp3mo   bootstrap.kubernetes.io/token   6      105s
kube@kubernetes:~$ kubectl -n kube-system get secret bootstrap-token-slp3mo -o yaml
apiVersion: v1
data:
  auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
  expiration: MjAyMC0wNy0yMlQxNjoyOTo0OFo=
  token-id: c2xwM21v
  token-secret: bzBzeHczMDhxM3hqNGwxbg==
  usage-bootstrap-authentication: dHJ1ZQ==
  usage-bootstrap-signing: dHJ1ZQ==
kind: Secret
metadata:
  creationTimestamp: "2020-07-22T15:59:48Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:auth-extra-groups: {}
        f:expiration: {}
        f:token-id: {}
        f:token-secret: {}
        f:usage-bootstrap-authentication: {}
        f:usage-bootstrap-signing: {}
      f:type: {}
    manager: kubeadm
    operation: Update
    time: "2020-07-22T15:59:48Z"
  name: bootstrap-token-slp3mo
  namespace: kube-system
  resourceVersion: "189437"
  selfLink: /api/v1/namespaces/kube-system/secrets/bootstrap-token-slp3mo
  uid: 8fb447c6-95d7-4dbb-ba63-084c7696be01
type: bootstrap.kubernetes.io/token

Decode token data (description was not provided, so this field is missing).

kube@kubernetes:~$ kubectl -n kube-system get secret bootstrap-token-slp3mo -o json | jq -r '.data."token-id" | @base64d'
slp3mo
kube@kubernetes:~$ kubectl -n kube-system get secret bootstrap-token-slp3mo -o json | jq -r '.data."token-secret" | @base64d'
o0sxw308q3xj4l1n
kube@kubernetes:~$ kubectl -n kube-system get secret bootstrap-token-slp3mo -o json | jq -r '.data."auth-extra-groups" | @base64d'
system:bootstrappers:kubeadm:default-node-token
kube@kubernetes:~$ kubectl -n kube-system get secret bootstrap-token-slp3mo -o json | jq -r '.data.expiration | @base64d'
2020-07-22T16:29:48Z

Delete this token.

kube@kubernetes:~$ kubeadm token delete slp3mo.o0sxw308q3xj4l1n
bootstrap token "slp3mo" deleted

Use existing token

Get a master server IP address.

kube@kubernetes:~$ kubectl get nodes --selector='node-role.kubernetes.io/master' -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
172.16.30.120

Alternatively, parse kubelet configuration.

kube@kubernetes:~$ yq r  /etc/kubernetes/kubelet.conf 'clusters[0].cluster.server'

List tokens.

kube@kubernetes:~$ kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
slp3mo.o0sxw308q3xj4l1n   25m         2020-07-22T16:29:48Z   authentication,signing                                                        system:bootstrappers:kubeadm:default-node-token

Get the certificate hash as described here.

kube@kubernetes:~$ openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -pubkey | openssl rsa -pubin -outform DER 2>/dev/null | openssl dgst -sha256 -r |  cut -d' ' -f1
350192ceb34c2b3a66e43b4f177065d98b90215d8ea0cc9e99367a628a69ee7f

Now you know every value required to build the full command needed to join this cluster.