💪

【Kubernetes】Ubuntu OS 22.04で高可用性クラスタを作りたい

2023/08/24に公開

追記

はじめに

今回はcontrol-planeを3台とした高可用性なクラスタを作りたい時にまとまった資料がなかったので備忘録的な感じで作りました。またこの記事のこだわりとして、右上のコピーのところでコピーしてもらえばそのまま通常ユーザーで実行できるように記載しているのでいい感じに活用してください。ただし一部はお使いの環境に合わせて変更する必要がある場所もございます。

構成

今回はRaspiを12台使っています。そしてこのRaspiはModel4Bの8GBモデルを使用しています。
また、OSはUbuntu OS 22.04.2 LTSを使用しています。一方で、上流のファイヤーウォールやスイッチのほうはあまり気にしないでもらって構いません。

ネットワーク図

IPアドレス割り当て

機器名 IPv4 機器名 IPv4
node1 192.18.100.1 node2 192.168.100.2
node3 192.168.100.3 node4 192.168.100.4
node5 192.168.100.5 node6 192.168.100.6
node7 192.168.100,7 node8 192.168.100.8
node9 192.168.100.9 node10 192.168.100.10
node11 192.168.100.11 node12 192.168.100.12

使用技術

今回は主に以下の3つを使って高可用性クラスタを作っていきます。

kubeadm

kubeadmではKubernetesを高速に作成する方法としてkubeadm initとkubeadm joinというコマンドを使えるようになります。また、セキュアに立てれたりといいことづくしということも言えるそうです。詳しくは、以下のサイトがびっくりするくらいわかりやすく載っているのでどうぞ。
https://qiita.com/FY0323/items/6a3b3270888c96ba13d3

cilium

ciliumはよく聞くCNIのうちの一つで、他に代表的なものでCalicoやflannelがあります。このciliumはeBPFというLinux kernelの仕組みを使ってNode間の通信を担っているらしい。また、カーネルレベルでNW制御を行うことで従来のkube-proxyといったユーザー空間で行う方法と異なり、高速であるみたい。
https://blog.framinal.life/entry/2021/02/20/222728

kube-vip

kube-vipはcontrol-planeをいい感じにロードバランシングするためのものです。また、公式ドキュメントでは

kube-vipは、外部のハードウェアやソフトウェアに依存することなく、コントロールプレーン(可用性の高いクラスタ構築用)とロードバランサータイプのKubernetesサービスの両方に仮想IPとロードバランサをKubernetesクラスタに提供する。

というふうに記載されていました。
https://kube-vip.io/
今回は、このkube-vipを使用していますが、構築手順としてはStatic PodDaemon Setの2つがあり今回はStatic Podとしてkube-vipをデプロイして使うことにしました。2つの違いとして、前者は構築が楽ですが、Kubernetesクラスタがkube-vipを管理しているわけではなくあくまで静的にデプロイしていることになります。一方で後者はKubernetesクラスタが自動で全control-planeに対してkube-vipをデプロイ・管理を行ってくれます。そのため、本番環境で運用する際はDaemon Setを使用して運用することが勧められています。
https://kube-vip.io/docs/installation/daemonset/

注意事項

kubernetesを立てる際に事前に以下の項目をよく確認した上で立ててください。

  1. ファイヤーウォールでポートを制限している偉い人は、ポートとプロトコルにアクセスし、それぞれのノードで必要なポートを開放するようにしてください。
  2. MACアドレスとproduct_uuidが全てのノードで独立している必要があり、以下のところで確認してください。
  • ネットワークインターフェースのMACアドレスはip linkもしくはifconfig -aコマンドで取得できます。
  • product_uuidはsudo cat /sys/class/dmi/id/product_uuidコマンドで確認できます。
  1. その他スペック等は公式サイトを参考に用意してください。

構築手順

これから、kubernetesを動かしていくために必要な手順を載せます。左上にAll-nodeとあれば、全ノードで実施していただければと思います。それ以外は、node1のみの実行であればnode1と記載しています。

初設定

  1. 恒例のアップデート
All-node
sudo apt update && sudo apt upgrade -y
  1. IPv4のフォワーディングを有効化する設定
All-node
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system
  1. スワップをオフにする
    一時的にスワップをオフにする場合は以下のコマンドでオフにすることができます。
All-node
sudo swapoff -a

しかし、上記のコマンドを実行するだけだと再起動後はまた使用する設定なっていて、kubernetesがReadyにならない原因になりますので、fstabからスワップは使用しないようにコメントアウトを行います。

All-node
sudo vim /etc/fstab
/etc/fstab
- /swap.img      none    swap    sw      0       0\
+ #/swap.img      none    swap    sw      0       0
  1. host名を解決できるようにする
    IPアドレスとホスト名はお使いの環境に合わせて設定してください。
All-node
cat <<EOF | sudo tee -a /etc/hosts
192.168.100.1 k8s1
192.168.100.2 k8s2
192.168.100.3 k8s3
192.168.100.4 k8s4
192.168.100.5 k8s5
192.168.100.6 k8s6
192.168.100.7 k8s7
192.168.100.8 k8s8
192.168.100.9 k8s9
192.168.100.10 k8s10
192.168.100.11 k8s11
192.168.100.12 k8s12
EOF

コンテナランタイムのインストール

今回は、コンテナランタイムとしてcontainerdを使います。そのためにまずはcontainerdをダウンロードするところから始めます。

All-node
sudo apt install -y containerd

次に、containerdをkubernetesで使うための設定をこれからしていきます。

All-node
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo sed -i 's#sandbox_image = "registry.k8s.io/pause:3.6"#sandbox_image = "registry.k8s.io/pause:3.9"#g' /etc/containerd/config.toml
sudo systemctl restart containerd && systemctl status containerd

最後にcontainerdがrunningしていることを確認して次のステップへ進んでください。また、これらの設定はUbuntu 22.04での場合は必須となるみたいです。今回は以下の記事がとても参考になりました。

どうやらUbuntu 22.04ではUbuntu 20.04と比べて、Cgroupのバージョンバージョンがv1からv2に変更になっているため、このような事態が起きているらしいことがわかった。
kubeadmはv1.22以降、何も指定しなければデフォルトでcgroupドライバーとしてsystemd(≒v2?)を使うようになっているようなのでUbuntu 22.04でも問題ないが、どうやらUbuntuの公式リポジトリからインストールしたcontainerdが標準でcgroupドライバーとしてcgroupfs(≒v1?)を使うため、上手く動作しないようだった。

https://www.notr.app/posts/2023/07/17/

kubeadm,kubectl,kubeletのインストール

次に、kubeadmとkubectl、kubeletといったkubernetesを動かすために必要なパッケージを全ノードで実行してインストールします。

All-node
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

#Google Cloudの公開鍵ダウンロード
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

#kubernetesのリポジトリをaptリポジトリに追加
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

#aptのパッケージを更新後にkubeadm、kubectl、kubeletをインストール
sudo apt-get update
sudo apt-get install -y kubeadm kubectl kubelet

# 勝手に更新されないように固定化
sudo apt-mark hold kubeadm kubectl kubelet 

kube-vipの導入

ここでは、kube-vipを導入していきます。この章ではrootユーザーに切り替えて作業することをお勧めします。

All control-plane
# ロードバランサーのIPアドレスを指定(セグメントが同じであれば好きなものに)
export VIP=192.168.100.98

# ロードバランサーのトラフィックを流すインターフェイスの指定
export INTERFACE=eth1

# kube-vipの最新バージョンの取得
KVVERSION=$(curl -sL https://api.github.com/repos/kube-vip/kube-vip/releases | jq -r ".[0].name")

# kube-vip用のmanifestの作成
alias kube-vip="ctr image pull ghcr.io/kube-vip/kube-vip:$KVVERSION; ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:$KVVERSION vip /kube-vip"
kube-vip manifest pod \
    --interface $INTERFACE \
    --address $VIP \
    --controlplane \
    --services \
    --arp \
    --leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml    

kubeadmの実行

ここまでの設定を行えたらようやくkubernetesのコントロールプレーンの設定にいけます。

node1
sudo kubeadm init \
--control-plane-endpoint "192.168.100.98:6443" \
--pod-network-cidr=10.1.0.0/16 \
--upload-certs

この時、contro-plane-endpointで指定するのは先ほどkube-vipのところで導入で指定したロードバランサーのIPアドレスを指定してください。 また、ポート番号は6443で構いません。一方で、pod-netwrok-cidrも自由に割り当ててもらって構いません。
 次に、kubernetesを操作するために必要な設定をします。以下のコマンドを通常ユーザーで実行してください。

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

最後にkubeadm initを実行した際に最後のほうにkubeadm joinというのが2つ出てくるはずです。上の方は引数オプションでcontrol-planeみたいなのがあるので、コントロールプレーンとして参加させたいnodeで実行するべきコマンドです。一方で、下の特に何もない方はWorkerノードとして参加させたい場合に使います。

control-planeの例
sudo kubeadm join <IPアドレス:ポート> --token <TOKEN> \
	--discovery-token-ca-cert-hash <token-hash> \
	--control-plane --certificate-key <certificate-key>
Workerの例
sudo kubeadm join <IPアドレス:ポート> --token <TOKEN> \
	--discovery-token-ca-cert-hash <token-hash> \

これをそれぞれのノードで実行させてしばらく待てばkubernetesに参加することができます。

Ciliumのインストール

CNIプラグインであるCiliumのインストールを行っていきます。以下に記述している通り、node1のみで実行してください。これを行うことでkubectl get nodesした時にReadyになります。

node1
# ciliumのコマンドをダウンロード
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}

# インストール
cilium install --version 1.14.1

Nodeが参加できているかの確認

ここまでの設定を問題なく行えれれば、以下のコマンドを実行したときにReadyと記されたノードが12個(今回の構築図より)表示されるはずです。

node1
kubectl get nodes

Readyになっていたら大成功です!!おめでとうございます。これでkubernetesでいろいろ遊べます。

さいごに

今回はとあるイベントでkubernetesが必要だったので、リソースがかなりあることから高可用性クラスタを作ってみました。勉強目的でも実際に運用する方でも少しでもご参考になったらうれしいです。また、これからkubernetesを弄る上で便利なものだったり、kubernetesに関連することに関しても投稿できればと思いますのでその時はぜひまた見ていただければと思います。

参考文献

今回の記事を作成するうえで参考になったサイトです。ありがとうございました。
https://zenn.dev/murasame29/articles/ee5868123c1e33
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#始める前に
https://kubernetes.io/ja/docs/reference/networking/ports-and-protocols/
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/high-availability/
https://kube-vip.io/docs/installation/static/
https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/

Discussion