おうちk8sのクラスタアップグレードをしたら少しハマった話
Kubernetes 1.18がリリースされたのでおうちk8sに対してもアップグレードを行いました
その際にいくつかハマったので書き起こしておきます
きっかけ
3/26にオンライン配信で開催された Kubernetes Meetup Tokyo #29 Cluster Upgrade 編 にて、
「kubeadmでのクラスタアップグレード:その光と闇」
という発表がありました
おうちk8sもkubeadmで構築していて、この発表を聞いてちょうどいい機会なので自分もアップグレードしてみようと思ったのがきっかけです
発表資料内に
- トラブルシューティングも充実してきた→裏を返せばそれだけトラブる
- 壊れることを前提としたほうがいいかもしれない
との記述がありましたが、うまくいくでしょ、というのとちょっと怖いけどお遊び用クラスタだしいっか、という気持ちでやってみることにしました
クラスタアップグレード
アップグレード自体の手順はkubernetes.ioにある こちら の内容を実施するだけです
補足
1.17.2 -> 1.18.0へのアップグレードで、構成はmaster×1、worker×2です
ハマったとこ
1つめ
masterノードで kubeadm upgrade apply v1.18.0
を実行したところ、途中で以下のようなエラーが連続して出るようになりました
[apiclient] Error getting Pods with label selector "k8s-app=upgrade-prepull-kube-controller-manager" [Get https://172.22.0.151:6443/api/v1/namespaces/kube-sys tem/pods?labelSelector=k8s-app%3Dupgrade-prepull-kube-controller-manager: net/http: request canceled (Client.Timeout exceeded while awaiting headers)] [apiclient] Error getting Pods with label selector "k8s-app=upgrade-prepull-kube-scheduler" [Get https://172.22.0.151:6443/api/v1/namespaces/kube-system/pods? labelSelector=k8s-app%3Dupgrade-prepull-kube-scheduler: net/http: request canceled (Client.Timeout exceeded while awaiting headers)] [apiclient] Error getting Pods with label selector "k8s-app=upgrade-prepull-etcd" [Get https://172.22.0.151:6443/api/v1/namespaces/kube-system/pods?labelSelec tor=k8s-app%3Dupgrade-prepull-etcd: net/http: request canceled (Client.Timeout exceeded while awaiting headers)] [apiclient] Error getting Pods with label selector "k8s-app=upgrade-prepull-kube-apiserver" [Get https://172.22.0.151:6443/api/v1/namespaces/kube-system/pods? labelSelector=k8s-app%3Dupgrade-prepull-kube-apiserver: net/http: request canceled (Client.Timeout exceeded while awaiting headers)] I0405 19:59:28.079111 18090 request.go:621] Throttling request took 1.290517695s, request: GET:https://172.22.0.151:6443/api/v1/namespaces/kube-system/pods? labelSelector=k8s-app%3Dupgrade-prepull-etcd
しかもそこで一旦止めたところ、サーバかかなり重たくなりsshするのも数分かかるように 😞
仕方なくリブートして再度実行したら何故かうまくいきました
2つめ
workerノードの1台で
apt-mark unhold kubelet kubectl && apt-get update && apt-get install -y kubelet=1.18.0-00 kubectl=1.18.0-00 && apt-mark hold kubelet kubectl
を実行後にkubeletの再起動を行ったところうまく立ち上がらず 🤔
あまり原因調査をしないまま、最初から設定やり直そうとし、kubeadm resetしました(ちゃんと調べて対応すればよかったかも)
その後のjoinする際に kubeadm token create --print-join-command
で発行されたコマンドを実施したら以下のエラーが
error execution phase kubelet-start: cannot get Node "raspberrypi-node02": nodes "raspberrypi-node02" is forbidden: User "system:bootstrap:aagt70" cannot get resource "nodes" in API group "" at the cluster scope To see the stack trace of this error execute with --v=5 or higher
調べてみるとkubernetes1.18.0のバグ?で、kubeadm token create
で発行されたtokenだとうまく動かないみたいです
代わりに kubeadm init phase bootstrap-token
で発行されたtokenでjoinがうまく動きました
これでなんとか1.17.2 -> 1.18.0へのアップグレードは成功しました(もう1台のworker nodeは問題なくアップグレードできた 🤔)
まとめ
発表にある通り、kubeadmでのクラスタアップグレードの闇を感じたけどいい経験になった