えんじにあメモ

試してみた技術とか、たまに家電ネタ

おうちk8sのクラスタアップグレードをしたら少しハマった話

Kubernetes 1.18がリリースされたのでおうちk8sに対してもアップグレードを行いました

その際にいくつかハマったので書き起こしておきます

きっかけ

3/26にオンライン配信で開催された Kubernetes Meetup Tokyo #29 Cluster Upgrade 編 にて、
「kubeadmでのクラスタアップグレード:その光と闇」
という発表がありました

speakerdeck.com

おうち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がうまく動きました

github.com

これでなんとか1.17.2 -> 1.18.0へのアップグレードは成功しました(もう1台のworker nodeは問題なくアップグレードできた 🤔)

まとめ

発表にある通り、kubeadmでのクラスタアップグレードの闇を感じたけどいい経験になった