約一年前に構築した自宅 Kubernetes クラスタをバージョンアップした手順のメモです.
課題と対応
多分,自宅で Kubernetes クラスタを運用(≠構築)するにあたって,最も大きな壁がこのバージョンアップだと思います.
Kubernetes は業務でも活用されているだけあって,バージョンアップ手順のドキュメントは充実しています.しかし,残念ながらマイナーバージョンをスキップしてのバージョンアップについては以下のように対象外となっています.
一方,昨年夏に構築したクラスタの kubeadm
のバージョンは 1.24.3 で,約1年後の23年5月時点の最新バージョンは 1.27.1 となっており,マイナーバージョンが3回も更新されています.
これは,正しいお作法でクラスターを最新バージョンに上げるには全てのノードに対してバージョンアップを3回実施する必要がある,ということを意味します.その道を進むのも手ですが,普通は Kubernetes クラスタ自体が好きでないとやってられないと思います.
ということで,クラスターを動かしたままバージョンアップするのではなく,クラスターをリセットして新しいバージョンで再構築することにしました.
バージョンアップ作業
次の3つの作業をすべてのノードで行います.Pod は事前に停止しておきます.
kubeadm
,kubelet
,kubectl
の更新kubeadm reset
の実行- Kubernetes の再設定
最初の項目は,次のようなスクリプトを準備しておくと便利です.実行には Z Shell が必要です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#!/usr/bin/env zsh set -e set -u set -o pipefail set -v curl -fsSL https://dl.k8s.io/apt/doc/apt-key.gpg | sudo gpg --dearmor --batch --yes --output /etc/apt/keyrings/kubernetes-archive-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt update -qq echo -e "\e[0;32mインストールするバージョンを選択してください.\e[0m" select ver in $(apt-cache madison kubeadm | head -n 8 | cut -d '|' -f 2 | xargs) do break done echo -ne "\e[0;32mバージョン \033[1;33m${ver} \033[0;32mに更新しますか?\e[0m" read -q "A? [y/N] " echo if [ $A != "y" ]; then echo "Stop.". exit fi echo echo -e "バージョン \033[1;33m${ver} \033[0;37mへの更新を開始します.\e[0m" for name in kubeadm kubelet kubectl; do sudo apt-get install -qq --allow-downgrades --allow-change-held-packages -y $name=$ver done |
こんな感じで,バージョンを選択してアップデートが行えます.
残りの項目は,『Ubuntu 22.04 に Kubernetes をインストールして自宅クラウド』と同等の内容を実行すればOKです.
トラブルシューティング
バージョンアップの中で一部トラブったので紹介します.
apt update が正常に完了しない
間が空いたためか,apt update
を実行したときに下記のような Warning が出てしまいました.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ヒット:1 https://download.docker.com/linux/ubuntu jammy InRelease 取得:2 https://packages.cloud.google.com/apt kubernetes-xenial InRelease [8,993 B] エラー:2 https://packages.cloud.google.com/apt kubernetes-xenial InRelease 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY B53DC80D13EDEF05 ヒット:3 http://jp.archive.ubuntu.com/ubuntu jammy InRelease ヒット:4 http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease ヒット:5 http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease ヒット:6 http://jp.archive.ubuntu.com/ubuntu jammy-security InRelease 8,993 B を 1s で取得しました (6,573 B/s) Reading package lists... Done Building dependency tree... Done Reading state information... Done アップグレードできるパッケージが 106 個あります。表示するには 'apt list --upgradable' を実行してください。 W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://packages.cloud.google.com/apt kubernetes-xenial InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY B53DC80D13EDEF05 W: Failed to fetch https://apt.kubernetes.io/dists/kubernetes-xenial/InRelease 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY B53DC80D13EDEF05 W: Some index files failed to download. They have been ignored, or old ones used instead. |
これは下記のコマンドで解消できます.
1 |
% sudo curl -so /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg |
MetalLB
Pod で動かしているサービスを外部に公開するにあたり MetalLB を使用していたのですが,バージョンアップの過程で次の2点で躓きました.
- バージョン不整合
- サービスに振り出される EXTERNAL-IP の変動
最初の項目については,昨年時点の v0.13.4 だと動かなかったので,最新の v0.13.9 に更新すればOKです.
後者は IP を自動割り付けしている限り回避できないので,クラスタ再構築によって変動することを頭に入れておくとスムーズに作業できると思います.CoreDNS 等を使って名前引きできるように設定しておくのも良いと思います.
【追記】設定方法を『Kubernetes 上のサービスにホスト名でアクセス』にて紹介しています.
ダウンタイムの考慮
これは蛇足ですが,今回紹介した方法でバージョンアップする場合,クラスタが正常稼働していない期間が数時間オーダーで発生する可能性がありますのでそれを見越して対策しておくとよいです.
私の場合,Fluentd で家中のセンサーからデータを収集しているのですが,バージョンアップ作業でそこそこの欠損が生じてしまいました.同じように Fluentd を使っている場合,HAProxy で Pod 上の Fluentd にデータを飛ばすのではなく,クラスタ外に Fluentd を立てておいて,そこから Forwarding するのがお勧めです.これにより,クラスタ内の Fluentd が停止している間も,クラスタ外の Fluentd に一時的にデータをためておけます.
なお,前述のように,クラスタ内の Fluentd の IP アドレスは再構築で変動する可能性があります.そのため,クラスタ外の Fluentd の Buffer タイプは file にしておき,クラスタ再構築後に Forwarding 先の IP アドレスを書き換えて再起動してもデータが残るようにしておくと良いと思います.
コメント