Kubeadmで構築したKubernetesクラスタにワーカーノードを追加する

#環境
ESXi6.7上のVM4台

- vm
  - k8s-master cpu:2 mem:4GB HDD:30GB IP:192.168.123.170
  - k8s-node1  cpu:2 mem:4GB HDD:30GB IP:192.168.123.171
  - k8s-node2  cpu:2 mem:4GB HDD:30GB IP:192.168.123.172
  - k8s-node3  cpu:2 mem:4GB HDD:30GB IP:192.168.123.173  ←今回追加するノード

- OS
  - CentOS8.2.2004 Minimalインストール

- Kubernetesのバージョン
  - 1.18.6

#はじめに
なんだかんだでCentOS7ではなく、カーネル版数の新しいCentOS8上で構築したKubernetesクラスタ環境を使用しています。
今までワーカーノードを2ノードで使っていましたが、1ノード増やすことにしました。
軽く躓いたこともあり、似たような記事はいくつもありますが、自分自身の整理も兼ねて公開します。

#手順
1. 追加するノード(k8s-node3)にkubeadm, kubelet, kubectlをインストールします。

    CentOS8.2.2004 Minimalインストールしたk8s-node3に「[ESXi上のCentOS8にKubeadmでKubernetesクラスタを構築する](https://qiita.com/yasubehe/items/51a05688d1f66d51531e)」の手順1～13までを実施して追加するノードをセットアップします。

2. 既存のKubernetesクラスタに用意したノードを追加します。（失敗）

    構築時に使用した kubeadm joinコマンドを実行します。
    構築してから時間がたっているとパラメタとか忘れてるかもしれません。。。
    別のk8s-nodeにログインしてhistoryコマンドで履歴を探してそれを実行します。
    ですが、たいていは以下のエラーとなり失敗します（私も失敗しました・・・）

    ```
    [root@k8s-node3 ~]# kubeadm join 192.168.123.170:6443 0cxone.2cwojy2o87tgiqu4 \
        --discovery-token-ca-cert-hash sha256:306eaa294baefe5c78e514dfb7b52646f2338c9f9e466c2724e3c6140028340f
    W0726 02:16:11.982073    8480 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
    [preflight] Running pre-flight checks
            [WARNING FileExisting-tc]: tc not found in system path

    error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap for token ID "0cxone"
    To see the stack trace of this error execute with --v=5 or higher
    [root@k8s-node3 ~]#
    ```

    理由は、クラスターに参加するノードとコントロールプレーンノード間で相互信頼を確立するためのkubeadmトークンの有効期限が切れてしまっていることが原因です。
    有効期限のデフォルトが24時間のため、kubeadm構築後、日にちが経過していると失敗します。

    参考：[kubeadm token](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-token/)

3. コントロールプレーンノード(k8s-master)で新しいkubeadmトークンを作成します。
    このとき、--print-join-commandオプションを使用することで、kubeadm join のコマンドラインを出力してくれます。
    
    ```
    [root@k8s-master ~]# kubeadm token create --print-join-command
    W0726 02:23:03.536227  214761 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
    kubeadm join 192.168.123.170:6443 --token 8x1zbh.rwys7cnih8sidmzg     --discovery-token-ca-cert-hash sha256:306eaa294baefe5c78e514dfb7b52646f2338c9f9e466c2724e3c6140028340f
    [root@k8s-master ~]# kubeadm token list
    TOKEN                     TTL         EXPIRES                     USAGES                   DESCRIPTION                                                EXTRA GROUPS
    8x1zbh.rwys7cnih8sidmzg   23h         2020-07-27T02:23:03-04:00   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token
    [root@k8s-master ~]#
    ```

4. 再度、既存のKubernetesクラスタに用意したノードを追加します。

    ```
    [root@k8s-node3 ~]# kubeadm join 192.168.123.170:6443 --token 8x1zbh.rwys7cnih8sidmzg     --discovery-token-ca-cert-hash sha256:306eaa294baefe5c78e514dfb7b52646f2338c9f9e466c2724e3c6140028340f
    W0726 02:23:55.847808    9000 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
    [preflight] Running pre-flight checks
            [WARNING FileExisting-tc]: tc not found in system path
    [preflight] Reading configuration from the cluster...
    [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
    [kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
    [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
    [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
    [kubelet-start] Starting the kubelet
    [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

    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.

    [root@k8s-node3 ~]#
    ```
    無事、新しいワーカーノードが追加されました。

    ```
    [root@k8s-master ~]# kubectl get nodes
    NAME         STATUS   ROLES    AGE     VERSION
    k8s-master   Ready    master   6d18h   v1.18.6
    k8s-node1    Ready    <none>   6d18h   v1.18.6
    k8s-node2    Ready    <none>   6d18h   v1.18.6
    k8s-node3    Ready    <none>   65s     v1.18.6
    [root@k8s-master ~]#
    ```


#参考URL
[kubeadm token](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-token/)
[CentOS 8でKubernetes Clusterを構築してみた_2](https://higherhope.net/?p=4234)
[K8s on Vagrant, Workerノードの追加と削除](https://qiita.com/MahoTakara/items/42a1ec9022fafab252e0)
[[kubernetes] kubeadmで構築した後トークン失効後にworkerノードを追加する](https://zaki-hmkc.hatenablog.com/entry/2020/04/05/103651)