Kubernetes(k8s)クラスタでnodeが飛んだので復旧した話
ある日、こんなことが起きました。
いつも通りにRaspberry piのKubernetesクラスタを動かすと…
一つのnodeが上がりません;;
HDMIを接続して確認すると /が飛んでいる様ですw
なので再度nodeを一から作成しなおしました。
手順はシンプル
Raspberry piのnodeのインストールはすでに記事にしていますのでそれを参考にしました…
ここでは書いていませんがこのままだと動きません!
kubeが最新ではDocker問題で動きません。
なので動くバージョンを指定しました
wataru@k8s-worker1:~ $ sudo apt-get install -y kubelet=1.23.6-00 kubeadm=1.23.6-00 kubectl=1.23.6-00
join先のnodeを空ける
master側で現状を確認すると…
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 199d v1.23.6
k8s-worker1 NotReady <none> 199d v1.23.6
k8s-worker2 NotReady <none> 199d v1.23.6
k8s-worker3 NotReady <none> 199d v1.23.6
k8s-worker4 NotReady <none> 199d v1.23.6
k8s-worker5 NotReady <none> 199d v1.23.6
k8s-worker6 NotReady <none> 199d v1.23.6
k8s-worker7 NotReady <none> 199d v1.23.6
今回この中のk8s-woker1が飛んだので削除した方が良いです。
削除するとこんな感じになります
wataru@k8s-master:~ $ kubectl delete node k8s-worker1
node "k8s-worker1" deleted
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 199d v1.23.6
k8s-worker2 NotReady <none> 199d v1.23.6
k8s-worker3 NotReady <none> 199d v1.23.6
k8s-worker4 NotReady <none> 199d v1.23.6
k8s-worker5 NotReady <none> 199d v1.23.6
k8s-worker6 NotReady <none> 199d v1.23.6
k8s-worker7 NotReady <none> 199d v1.23.6
はい、歯抜けになりました
相変わらずjoinで詰まる
最終的にkubectl joinすれば入ります。
kubectl joinのコマンドはこんな感じです
wataru@k8s-worker1:~ $ sudo kubeadm join 192.168.1.221:6443 --token <<トークン>> --discovery-token-ca-cert-hash <<hash>>
これで!
前回joinしたコマンドを引っ張り出しましたがこれではエラーになってjoinできません…
wataru@k8s-worker1:~ $ sudo kubeadm join 192.168.1.221:6443 --token mehljf.kbpf7oazqxwhfft4 --discovery-token-ca-cert-hash sha256:20fbb36fde703aaba4d823e0a506c3866fe66f2c818c5685c52034bdc2c908ea
[preflight] Running pre-flight checks
[WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: couldn't validate the identity of the API Server: cluster CA found in cluster-info ConfigMap is invalid: none of the public keys "sha256:e06d2713682eae1387b7c16a29b4e293b03d670914b9f0af349d096e690d473e" are pinned
To see the stack trace of this error execute with --v=5 or higher
原因を調査!とかいう前にトークンとhashが正しくないってのはすぐにわかります。
では、トークンとhashってどこで確認するのか?
joinするトークン
トークンはmaster側で管理していますので、token一覧を確認します…
wataru@k8s-master:~ $ sudo kubeadm token list
はい、トークンはありません…
なのでjoinコマンドは無効です
なのでトークンを作成します
wataru@k8s-master:~ $ sudo kubeadm token create
mehljf.kbpf7oazqxwhfft4
wataru@k8s-master:~ $ sudo kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
mehljf.kbpf7oazqxwhfft4 23h 2022-12-02T01:45:54Z authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
token createコマンドの標準出力でtokenは発行されますが、有効期限の確認はlistで行えます。
24時間くらいなので再セットアップが必要な場合は必ずトークンを作成する必要があると思っててもOKでしょう
hashを確認する
トークンは分かりましたので次にhashを確認します
答えから言いますと、コマンド一発で発行されます
wataru@k8s-master:~ $ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
e06d2713682eae1387b7c16a29b4e293b03d670914b9f0af349d096e690d473e
コマンドの解説は… いいや、コピペしてお使いください
joinコマンドではこのhashキーにsha256を付与して使ってください
sha256:e06d2713682eae1387b7c16a29b4e293b03d670914b9f0af349d096e690d473e
再度joinする
トークンとhashが分かりましたのでnodeをjoinさせます
wataru@k8s-worker1:~ $ sudo kubeadm join 192.168.1.221:6443 --token mehljf.kbpf7oazqxwhfft4 --discovery-token-ca-cert-hash sha256:e06d2713682eae1387b7c16a29b4e293b03d670914b9f0af349d096e690d473e
[preflight] Running pre-flight checks
[WARNING SystemVerification]: missing optional cgroups: hugetlb
[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'
W1201 10:50:50.549680 5302 utils.go:69] The recommended value for "resolvConf" in "KubeletConfiguration" is: /run/systemd/resolve/resolv.conf; the provided value is: /run/systemd/resolve/resolv.conf
[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.
注意は無視してクラスタにjoinできました。
master側で確認してnodeが増えていることを確認します
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 199d v1.23.6
k8s-worker1 NotReady <none> 25s v1.23.6
k8s-worker2 NotReady <none> 199d v1.23.6
k8s-worker3 NotReady <none> 199d v1.23.6
k8s-worker4 NotReady <none> 199d v1.23.6
k8s-worker5 NotReady <none> 199d v1.23.6
k8s-worker6 NotReady <none> 199d v1.23.6
k8s-worker7 NotReady <none> 199d v1.23.6
はい、k8s-worker1が復活していることを確認できました。
しばらく放置すると…
wataru@k8s-master:~ $ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 199d v1.23.6
k8s-worker1 Ready <none> 4m46s v1.23.6
k8s-worker2 NotReady <none> 199d v1.23.6
k8s-worker3 NotReady <none> 199d v1.23.6
k8s-worker4 NotReady <none> 199d v1.23.6
k8s-worker5 NotReady <none> 199d v1.23.6
k8s-worker6 NotReady <none> 199d v1.23.6
k8s-worker7 NotReady <none> 199d v1.23.6
Readyになります
終いに
今回はk8sクラスタのnodeが吹っ飛んだので復旧方法をメモしておきました。
セットアップは別記事にしていましたが、バージョンを指定しないと動かないことと、joinのトークン周りを詳しく書いてみました。
ちゃんと普段から使わないとなw