2023年12月16日土曜日

Kubernetesにてノードの削除・追加を行う

Kubernetesでノードの調子が悪くなったりした際に、一度ノードを削除して同じ名前で再度追加をさせたい場合がある。

簡単にノードを削除・追加するだけであればよいが、Kubernetesの場合、少し追加で必要な作業がある。本記事では、Kubernetesにてノードの削除・追加を行うために必要な手順を記載する。

環境

以下に今回構築する各種ソフトウェアのバージョンを記載する。

  • ホストOS : AlmaLinux 8.6
  • Kubernetes : v1.28.2
  • Docker : 24.0.6
  • CRI : cri-dockerd 0.3.4
  • CNI : flannel v0.22.0

今回の構成の概要図を以下に記載する。

作業前のKubernetesのノードの状態は以下の通り。3台目に存在する「t1053kube」のノードを削除したのち、追加する手順を説明する。

# kubectl get node -o=wide
NAME        STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                    KERNEL-VERSION              CONTAINER-RUNTIME
t1051kube   Ready    control-plane   202d   v1.28.2   192.168.11.51   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6
t1052kube   Ready    control-plane   202d   v1.28.2   192.168.11.52   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6
t1053kube   Ready    control-plane   174d   v1.28.2   192.168.11.53   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6

ノード削除手順

1. Kubernetesクラスタからノードを削除

Kubernetesクラスタからノードを削除する際は、kubectl delete node [ノード名]で行う。処理はすぐに完了する。

# kubectl delete node t1053kube
node "t1053kube" deleted

3台存在したノードが2台になったことが確認できる。

# kubectl get node -o=wide
NAME        STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                    KERNEL-VERSION              CONTAINER-RUNTIME
t1051kube   Ready    control-plane   202d   v1.28.2   192.168.11.51   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6
t1052kube   Ready    control-plane   202d   v1.28.2   192.168.11.52   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6

2. ノードをリセット

削除した対象のOSにログインし、kubeadm resetを用いて、一度ノードをリセットする。なお、複数のCRIがインストールされている環境の場合は、--cri-socketオプションにて使用するCRIを明記する必要がある(オプションを指定しない場合、Found multiple CRI endpoints on the host.というエラーが表示されコマンドが失敗する)。

# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
[reset] Reading configuration from the cluster...
[reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
W1210 07:53:07.866239  247333 reset.go:120] [reset] Unable to fetch the kubeadm-config ConfigMap from cluster: failed to get node registration: failed to get node name from kubelet config: open /etc/kubernetes/kubelet.conf: no such file or directory
W1210 07:53:07.866312  247333 preflight.go:56] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] Are you sure you want to proceed? [y/N]: y ★"y"を入力
[preflight] Running pre-flight checks
W1210 07:53:09.421805  247333 removeetcdmember.go:106] [reset] No kubeadm config, using etcd pod spec to get data directory
[reset] Deleted contents of the etcd data directory: /var/lib/etcd
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Deleting contents of directories: [/etc/kubernetes/manifests /var/lib/kubelet /etc/kubernetes/pki]
[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]

The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d

The reset process does not reset or clean up iptables rules or IPVS tables.
If you wish to reset iptables, you must do so manually by using the "iptables" command.

If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
to reset your system's IPVS tables.

The reset process does not clean your kubeconfig files and you must remove them manually.
Please, check the contents of the $HOME/.kube/config file.

3. etcdからNode情報を削除

Kubernetesクラスタから削除しても、etcdからは情報が削除されない。そこで、直接etcdのPodにログインし削除作業を行う。etcdにログインすると、プロンプトがsh-5.1#に変わる。

# kubectl exec -it -n kube-system etcd-t1051kube -- sh
sh-5.1#

etcdの操作はetcdctlコマンドで実行する。オプションが多いため超絶コマンドが長いが、以下の通りetcdctl member listを実行すると、現在etcdに登録されている情報を確認することができる。先ほどKubernetesクラスタから削除した「t1053kube」のノードの情報が残っていることがわかる。

sh-5.1# ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd//peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt --endpoints=https://127.0.0.1:2379 member list
391db64cfd0b76da, started, t1052kube, https://192.168.11.52:2380, https://192.168.11.52:2379, false
40f1e9f856640698, started, t1051kube, https://192.168.11.51:2380, https://192.168.11.51:2379, false
a642d0757a50ab59, started, t1053kube, https://192.168.11.53:2380, https://192.168.11.53:2379, false

テーブル形式でもう少し見やすくする場合は、etcdctl -w table member listを実行する。

sh-5.1# ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd//peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt --endpoints=https://127.0.0.1:2379 -w table member list
+------------------+---------+-----------+----------------------------+----------------------------+------------+
|        ID        | STATUS  |   NAME    |         PEER ADDRS         |        CLIENT ADDRS        | IS LEARNER |
+------------------+---------+-----------+----------------------------+----------------------------+------------+
| 391db64cfd0b76da | started | t1052kube | https://192.168.11.52:2380 | https://192.168.11.52:2379 |      false |
| 40f1e9f856640698 | started | t1051kube | https://192.168.11.51:2380 | https://192.168.11.51:2379 |      false |
| a642d0757a50ab59 | started | t1053kube | https://192.168.11.53:2380 | https://192.168.11.53:2379 |      false |
+------------------+---------+-----------+----------------------------+----------------------------+------------+

削除対象の「t1053kube」のIDを引数として、etcdctl member remove [ID]を実行する。

sh-5.1# ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd//peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt --endpoints=https://127.0.0.1:2379 member remove a642d0757a50ab59
Member a642d0757a50ab59 removed from cluster 786da9e9c378caa1

再度登録状況を確認すると、「t1053kube」が削除されていることが確認できる。

sh-5.1# ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd//peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt --endpoints=https://127.0.0.1:2379 -w table member list
+------------------+---------+-----------+----------------------------+----------------------------+------------+
|        ID        | STATUS  |   NAME    |         PEER ADDRS         |        CLIENT ADDRS        | IS LEARNER |
+------------------+---------+-----------+----------------------------+----------------------------+------------+
| 391db64cfd0b76da | started | t1052kube | https://192.168.11.52:2380 | https://192.168.11.52:2379 |      false |
| 40f1e9f856640698 | started | t1051kube | https://192.168.11.51:2380 | https://192.168.11.51:2379 |      false |
+------------------+---------+-----------+----------------------------+----------------------------+------------+

最後にexitでetcdから抜けておく。

sh-5.1# exit

ノード参加手順

1. 参加するためのtoken作成

ノード参加のためには、tokenを作成する必要がある。現在作成されているtokenは以下コマンドで確認できる。何も表示されない場合は、未登録であることを意味する。

# kubeadm token list

tokenを作成しつつノード追加のコマンドを表示させるため、以下コマンドを実行する。

# kubeadm token create --print-join-command
kubeadm join t1041kube.intrat.local:6443 --token hqrq5b.lmlys2u5vsqmza06 --discovery-token-ca-cert-hash sha256:cd21077ae8389da3990d28424f3e8aa1fcbf5394094bcb849803b8664d700b55

また、ノード追加時に必要となる証明書の更新も実施する。

# kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
36568d37aa84232e623cd8df34c1704c2fb16e7846e7df92b55f13072ce262f0

再度tokenを確認すると、tokenと証明書の2行が表示されていることが確認できる。

# kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
hqrq5b.lmlys2u5vsqmza06   23h         2023-12-10T22:41:01Z   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token
x87o7b.ya73txnsszqsx8x5   1h          2023-12-10T00:58:59Z   <none>                   Proxy for managing TTL for the kubeadm-certs secret        <none>

2. kubectl joinコマンド実行

token作成時に生成したkubeadm joinコマンドを実行し、ノードを再参加させる。なお、コントロールプレーンとして追加する場合は、--control-plane--certificate-keyのオプション指定が追加で必要となる。--cri-socketは前述したとおり、複数のCRIがインストールされている環境の場合に必要となる。

今回の場合はコントロールプレーンとしてノードを参加させるため、コマンドは以下のようになった。

kubeadm join t1041kube.intrat.local:6443 --token hqrq5b.lmlys2u5vsqmza06 \
--discovery-token-ca-cert-hash sha256:cd21077ae8389da3990d28424f3e8aa1fcbf5394094bcb849803b8664d700b55 \
--control-plane \
--certificate-key 36568d37aa84232e623cd8df34c1704c2fb16e7846e7df92b55f13072ce262f0 \
--cri-socket=unix:///var/run/cri-dockerd.sock

実際の実行結果は以下となる。

# kubeadm join t1041kube.intrat.local:6443 --token hqrq5b.lmlys2u5vsqmza06 \
> --discovery-token-ca-cert-hash sha256:cd21077ae8389da3990d28424f3e8aa1fcbf5394094bcb849803b8664d700b55 \
> --control-plane \
> --certificate-key 36568d37aa84232e623cd8df34c1704c2fb16e7846e7df92b55f13072ce262f0 \
> --cri-socket=unix:///var/run/cri-dockerd.sock
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[preflight] Running pre-flight checks before initializing the new control plane instance
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
W1210 08:16:25.328679  250776 checks.go:835] detected that the sandbox image "registry.k8s.io/pause:3.6" of the container runtime is inconsistent with that used by kubeadm. It is recommended that using "registry.k8s.io/pause:3.9" as the CRI sandbox image.
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[download-certs] Saving the certificates to the folder: "/etc/kubernetes/pki"
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost t1053kube] and IPs [192.168.11.53 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost t1053kube] and IPs [192.168.11.53 127.0.0.1 ::1]
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local t1041kube.intrat.local t1053kube] and IPs [10.96.0.1 192.168.11.53]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[certs] Using the existing "sa" key
[kubeconfig] Generating kubeconfig files
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[check-etcd] Checking that the etcd cluster is healthy
[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...
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
The 'update-status' phase is deprecated and will be removed in a future release. Currently it performs no operation
[mark-control-plane] Marking the node t1053kube as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node t1053kube as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]

This node has joined the cluster and a new control plane instance was created:

* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.

To start administering your cluster from this node, you need to run the following as a regular user:

        mkdir -p $HOME/.kube
        sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
        sudo chown $(id -u):$(id -g) $HOME/.kube/config

Run 'kubectl get nodes' to see this node join the cluster.

最後にノードの状態を確認すると「t1053kube」が正常に登録されステータスがReadyになっていることがわかる。

# kubectl get node -o=wide
NAME        STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                    KERNEL-VERSION              CONTAINER-RUNTIME
t1051kube   Ready    control-plane   202d   v1.28.2   192.168.11.51   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6
t1052kube   Ready    control-plane   202d   v1.28.2   192.168.11.52   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6
t1053kube   Ready    control-plane   17s    v1.28.2   192.168.11.53   <none>        AlmaLinux 8.6 (Sky Tiger)   4.18.0-372.9.1.el8.x86_64   docker://24.0.6

以上で、Kubernetesにてノードの削除・追加を行うために必要な手順は完了となる。

0 件のコメント:

コメントを投稿

人気の投稿