Kubernetesクラスタ構築 - おうちでGitOpsシリーズ投稿2/6
こちらはおうちラボでGitOpsシリーズの2つ目のポストです。
前回のポストでは一体このシリーズで何を作っていくかのイントロと流れの紹介、またDockerでDNSサーバ、リバースプロキシサーバ、そしてGitLabをセットアップしました。
今回はKubernetesクラスタをセットアップしていきます。バージョンは私がここ最近作った時点での最新、v1.27.1です。最初にKubernetesクラスタのコントロールプレーンとして使用するノードとしてRaspberry Pi 4、そしてクラスタに参加させるノードとしてRaspberry Pi 4をもう一台と、Debian11を入れたファンレスミニPCそれぞれでの作業を紹介していきます。
なお本シリーズではノードはそれぞれ、rpi4bp, rpi4, d11と呼んでいきます。
本シリーズのお約束
-
Kubernetes
Cluster on 3 nodes (2 raspberry pi4 - arm64, and 1 amd64 fanless mini PC)-
flannel
for networking -
flux
as a GitOps tool - metallb for
LoadBalancer
service type implementation
-
- 1 or more machine running
Docker
- serving
GitLab
(Used for GitOps central repository) - serving
Nginx
(Reverse proxy to provide access to GitLab and other web services to be created on Kubernetes Cluster) - serving
Unbound
(DNS resolver for machines on LAN)
- serving
- public DNS domain + SSL/TLS certification (for example, Let's Encrypt) recommended
- they are all
mydomain.net
in the series - replace
mydomain.net
with your own DNS domain to follow through
- they are all
More on Docker - Series Top: Dockerで作るおうちLAN遊び場 シリーズ1/7
Interested in getting your own DNS domain?
セットアップ
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
やることとしてはKubernetesのドキュメント通りですが、次の通りとなります。
- (Raspberry Pi ImagerなどでOSインストールは完了しておりsshでログインできる状態まで持ってきている前提)
- 固定IPアドレス設定
- DNS設定
- swap無効
- システムのネットワーク設定
- containerdインストールと設定
- kubeadm, kubelet, kubectlインストール
- kubeadmでクラスタ立ち上げ
- 2, 3台目はkubeadmでクラスタに参加
- ネットワークプラグインとしてflannelをインストール
固定IPアドレスとDNS設定
Raspberry Piはデスクトップ環境などの入っていないLiteバージョンを入れています。sudo vi /etc/dhcpcd.conf
で設定を更新し、リブートすれば設定できます。
内容に関しては、元々ファイル内でコメントアウトされている例を参考にできるかと思いますが、例えばLANのサブネットが192.168.1.0/24でルータ・ゲートウェイのIPアドレスが192.168.1.1とした場合、以下のようになります。また、このシリーズでは192.168.1.55でUnbound DNSサービスをDockerコンテナとして走らせている前提ですので、DNSサーバも指定します。
なおDNSサーバは2台以上あるのが理想的です。もし他のノードでもDNSサーバを立ち上げている場合はスペース区切りでstatic domain_name_servers=192.168.1.55 192.168.1.54
のように記載しましょう。
domain_search
は単に名前解決するときに利用するサーチサフィックスです。本シリーズではなくても問題ないですし、好きなように設定しましょう。
ちなみにrpi4bpで192.168.1.56、rpi4では192.168.1.57としていきます。IPアドレスは重複しないように好きなように割り当ててください。
interface eth0
static ip_address=192.168.1.56/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.55
static domain_search=mydomain.net
なおOSが異なるd11は別のファイルで設定します。
まず固定IPアドレスですが、sudo vi /etc/network/interfaces
で以下のように編集します。元々iface enp2s0 inet dhcp
のような行が#
でコメントアウトされずにあると思います。その行はコメントアウトして残しても削除してもどちらでも良いです。
# The primary network interface
allow-hotplug enp2s0
#iface enp2s0 inet dhcp
iface enp2s0 inet static
address 192.168.1.58
netmask 255.255.255.0
gateway 192.168.1.1
次にDNSサーバの設定は、sudo vi /etc/resolv.conf
で以下のように編集します。
domain mydomain.net
search mydomain.net
nameserver 192.168.1.55
swap無効
ここからは公式のドキュメント通りに行くと思います。あらゆるところに同じことを書いたドキュメント、ブログポストがあると思いますが、このポストでもセットアップ手順を一から書いていきます。
まずswap無効ですが、やり方がシステムごとに異なると思いますが、Raspberry Pi 4もDebian 11を入れたミニPCも次の手順でswap無効化できました。
grubでnoresume
を追加しsudo update-grub
で反映するのと、systemctl --type swap
でsystemd上で見えるswapを確認し、それをmaskするという2点です。あともしfstabにswap関連の記載があればコメントアウトしたらよいと思います。
sudo vi /etc/default/grub
# add "noresume" in GRUB_CMDLINE_LINUX_DEFAULT
# GRUB_CMDLINE_LINUX_DEFAULT="quiet noresume"
sudo update-grub
# find swap on systemd and mask it
systemctl --type swap
sudo systemctl mask dev-sda3.swap
# comment out an entry for swap in fstab if present
sudo vi /etc/fstab
sudo shutdown -r now
システムのネットワーク設定
ドキュメントはswap無効化などの要件の次はcontainer runtimeをインストールする流れですが、前提として必要となる設定の有効化をします。
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# sysctl params required by setup, params persist across reboots
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
# Apply sysctl params without reboot
sudo sysctl --system
containerdなどのインストールと設定
続いてcontainerd, runc, CNI pluginsをインストール、設定します。下のコードブロック一つに全てまとめてしまっていますが、やっていることは次の通りです。ちなみにRaspberry Pi、d11ともに共通の流れでできます。ダウンロードするファイルについては最新を選べば良いと思います。CPUアーキテクチャに注意して選択しましょう。私はRasbperry Pi 2台にはarm64、d11についてはamd64とついているファイルを選択しました。
- ホームディレクトリにtmp (~/tmp)を用意してそこでファイルをダウンロード
- containerdのダウンロード、解凍、daemonとして有効化
- runcのダウンロードとインストール
- CNIプラグインのダウンロード、
/opt/cni/bin
ディレクトリ作成、ダウンロード物をそのディレクトリに解凍 - containerdのデフォルトコンフィグをひとまず
~/tmp/config.toml.default
として出力し、containerd、runcオプションのところでSystemdCgroup=trueとなるよう変更 - 用意できたcontainerdのコンフィグファイルを
/etc/containerd/config.toml
として保存し、サービスリスタート
mkdir ~/tmp
cd ~/tmp
# download and install containerd
curl -LO https://github.com/containerd/containerd/releases/download/v1.7.1/containerd-1.7.1-linux-arm64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.7.1-linux-arm64.tar.gz
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
# download and install runc
curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.arm64
sudo install -m 755 runc.arm64 /usr/local/sbin/runc
# download and install CNI plugins
curl -LO https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-arm64-v1.3.0.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-arm64-v1.3.0.tgz
# configure containerd
# first, generate default config at ~/tmp/config.toml.default
containerd config default > config.toml.default
# and then edit one line as described below
vi config.toml.default
## find section
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
## and find "SystemdCgroup = false", and change it to true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
...
...
SystemdCgroup = true
# and then cp this file to the containerd config directory
sudo cp config.toml.default /etc/containerd/config.toml
# restart containerd
sudo systemctl restart containerd
kubeadm, kubelet, kubectlインストール
ではKubernetes関連パッケージをインストールしていきます。先にリンクを貼った公式のドキュメントに記載しているもの、そのまんまです。パッケージマネージャaptでインストールするための下準備、インストール、そして平時のapt upgrade
などでバージョンアップされないようホールドするという手順が以下です。
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
kubeadmでクラスタ立ち上げ
いよいよKubernetesクラスタの立ち上げです。
Control-planeとするノードではkubeadm init
、他のクラスタ構成ノードはkubeadm join
していきます。
私の環境ではrpi4bpをcontrol-planeとするので、そのノードで以下のコマンドを実行します。ネットワークプラグインにはflannel
を使うのですが、そのデフォルト設定となっているpod用のネットワークは10.244.0.0/16なので、それを指定するためのオプションが追加されています。
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
いろいろ出力されますが、注目してほしいのは2点です。まずはsudo
せずともKubernetes関連のコマンドを実行できるようにするためのコマンドが次の通りです。
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2つ目は、他のノードでkubeadm join
するためのコマンドについてです。これをKubernetesクラスタに参加させるノードで実行しましょう。
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join {ipaddr of the control-plane node}:6443 --token {tokenstring} \
--discovery-token-ca-cert-hash sha256:{cacerthashstring}
ネットワークプラグインとしてflannelをインストール
この時点では、control-planeでkubectl get nodes
と実行すると全ノードnot readyとなっていると思います。クラスタが機能するのにもう一つ必要なものがネットワークプラグインです。ちなみにkubectl get pods -A
で現時点で動いているpodが確認できます。
flannelというネットワークプラグインのインストールには以下のコマンドをcontrol-planeで実行しましょう。これだけでflannelのセットアップが完了します。
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
あらためてkubectl get nodes
とすると若干時間はかかるかもしれませんが、ほどなくすべてreadyとなっているでしょう。再度kubectl get pods -A
を実行するとflannel関連のpodが作られているのが確認できます。
完成!!
これでKubernetesクラスタの完成です!次回はGitOpsでこのKubernetesクラスタを使っていくためのセットアップを進めていきます。
Discussion