はじめに
株式会社ピー・アール・オー Advent Calendar 2023の1日目がなんと空いているので参戦しました。どうぞよろしくお願いします。
今回はK3sでクラスタを作成するまでを記事にします。
K3sとは?
K3sとは、Rancher Labsが開発した軽量なKubernetesディストリビューションです。
公式サイトを見ると、以下のような特徴と利点が挙げられています。
- エッジコンピューティングやIoTに最適
- 単一のバイナリファイルとしてパッケージングされているので導入が楽
- ARM用に最適
端的に述べると、とても軽量で導入が容易なコンテナオーケストレーションシステムということです。
今回はRaspberry Pi 4と、このK3sを使用し、クラスターの構築を行います。
動作確認環境
端末 | OS | ノードタイプ |
---|---|---|
Raspberry Pi 4 Model B / 8GB | Ubuntu 20.04.4 LTS | Server |
Raspberry Pi 4 Model B / 8GB | Ubuntu 20.04.4 LTS | Agent |
Raspberry Pi 4 Model B / 8GB | Ubuntu 20.04.4 LTS | Agent |
OSのインストール手順はUbuntu公式サイトのチュートリアルに従うとよいでしょう。
各ノードの共通設定
ローカルIPアドレスの固定
99-config.yaml
を編集し、各ノードのローカルIPアドレスを固定します。
# cd /etc/netplan/
# vim 99-config.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 192.168.0.16/24
gateway4: 192.168.0.1
nameservers:
addresses: [8.8.8.8]
以下のコマンドで適用します。
# netplan apply
我が家の環境ではそれぞれ以下の通りに設定しました。
- Server
- 192.168.0.16
- Agent1
- 192.168.0.17
- Agent2
- 192.168.0.18
ホストネーム設定
各ノードにホスト名をユニークになるよう設定します。
これは、K3sはデフォルトでホスト名を kubernetes ノード名として使用するためです。
# hostnamectl set-hostname <ホスト名>
NFSのインストール
必要に応じ、NFSをインストールします。
PersistentVolumeを使う場合などは用意しておいた方がよいでしょう。
# apt install nfs-common
以下のコマンドで外付けHDDをマウントします。
# mount -t nfs 192.168.0.4:/external-hdd/ /mnt/ -o hard,intr
OSの日本語化
必須ではないですが、日本語化しておきます。
# apt -y install language-pack-ja-base language-pack-ja ibus-kkc
# localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
# source /etc/default/locale
# echo $LANG
WireGuardのインストール
WireGuardをFrannelのバックエンドとして使用することで、クラスター内の通信を暗号化することができ、よりセキュアな運用を行うことができます。
ここでは、クラスター内の全ての端末にWireGuardをインストールし、適用する手順を記載します。
# apt install wireguard -y
キーペアの作成
キーペアを作成します。このキーペアの内容を設定ファイルに記載します。
# wg genkey | tee wg.key | wg pubkey > wg-pub.key
設定ファイルの作成
/etc/wireguard/wg0.conf
を作成します。
我が家の環境では、それぞれ以下のIPアドレスを利用するようにしました。
- Server
- 172.16.0.1
- Agent1
- 172.16.0.2
- Agent2
- 172.16.0.3
なお、WireGuardのインターフェース名はwg0
としています。
- 172.16.0.3
サーバーの場合
[Interface]
Address = 172.16.0.1
ListenPort = 51871
PrivateKey = <サーバーで作成した秘密鍵>
[Peer]
PublicKey = <エージェント1で作成した公開鍵>
AllowedIPs = 172.16.0.2
[Peer]
PublicKey = <エージェント2で作成した公開鍵>
AllowedIPs = 172.16.0.3
エージェントの場合
[Interface]
Address = 172.16.0.2
ListenPort = 51871
PrivateKey = <エージェント1で作成した秘密鍵>
[Peer]
PublicKey = <サーバーで作成した公開鍵>
Endpoint = 192.168.0.16:51871
AllowedIPs = 172.16.0.1
[Interface]
Address = 172.16.0.3
ListenPort = 51871
PrivateKey = <エージェント2で作成した秘密鍵>
[Peer]
PublicKey = <サーバーで作成した公開鍵>
Endpoint = 192.168.0.16:51871
AllowedIPs = 172.16.0.1
WireGuardの起動
全てのサーバー、エージェントで自動起動を有効にし、起動します。
# systemctl enable wg-quick@wg0
# systemctl start wg-quick@wg0
サーバー側作業
K3sのインストール作業
ファイアウォールの設定
以下のポートを開けます。UFWを使用している場合の例です。
# ufw enable
# ufw allow 22
# ufw allow 6443/tcp
# ufw allow 7946/tcp
# ufw allow 10250/tcp
# ufw allow 51820/udp
# ufw allow 51871/udp
メモリサブシステムの有効化
/boot/firmware/cmdline.txt
を編集し、行末にcgroup_memory=1 cgroup_enable=memory
を追加します。
これにより、cgroupのメモリサブシステムを有効化します。
elevator=deadline net.ifnames=0 console=serial0,115200 dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 rootwait fixrtc quiet splash cgroup_memory=1 cgroup_enable=memory
追記後、マシンをrebootしてください。
# reboot -h now
K3sインストールスクリプトの実行
K3sのインストールスクリプトを実行し、サーバーとしてインストールします。
デフォルトでいくつかのPodが自動的にデプロイされるようになっていますが、--disable
オプションを付与することで無効化することができます。
対象はcoredns, servicelb, traefik, local-storage, metrics-server
となります。
なお、以前のバージョンでは--no-deploy
で無効化することができましたが、名称が変わっています。旧称で指定するとエラーとなるので注意が必要です。
また、我が家の環境はIPv6 over IPv4に固定IPオプションを利用しています。
そのため、--tls-san
オプションを付与し、明示的に割り当てられた固定IPをAPIサーバーの証明書のSANに設定しています。(ローカルIPも一応指定しています)
これを指定しないと、IPv6アドレスのみSANに設定されてしまい、固定IPでアクセスした際、証明書の検証に失敗してしまうためです。
# curl -sfL https://get.k3s.io | sh -s - --disable traefik,local-storage,servicelb --node-name master --tls-san 固定したIPv4アドレス(グローバル) --tls-san 192.168.0.16 --tls-san 127.0.0.1`
トークンの確認
インストール後、サーバーのトークンを取得します。
このトークンはエージェントのインストール時に使用するため、値を控えておきます。
# cat /var/lib/rancher/k3s/server/node-token
Systemdサービスの編集
/etc/systemd/system/k3s.service
を編集し、起動オプションと、WireGuardの設定を追加しておきます。
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/etc/sysconfig/%N
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
'--disable' \
'traefik,local-storage,servicelb' \
'--node-name' \
'server' \
'--tls-san' \
'固定したIPv4アドレス(グローバル)' \
'--tls-san' \
'192.168.0.16' \
'--tls-san' \
'127.0.0.1' \
'--flannel-backend' \
'wireguard-native' \
'--flannel-external-ip' \
'--flannel-iface' \
'wg0' \
Unitファイルの変更を反映し、K3sを再起動します。
# systemctl daemon-reload
# systemctl restart k3s
エージェント側作業
本環境ではエージェントを2台用意するため、それぞれの端末に対して手順を実施しています。
K3sのインストール作業
ファイアウォールの設定
以下のポートを開けます。UFWを使用している場合の例です。
# ufw enable
# ufw allow 22
# ufw allow 7946/tcp
# ufw allow 10250/tcp
# ufw allow 51820/udp
# ufw allow 51871/udp
メモリサブシステムの有効化
サーバーと同様に、/boot/firmware/cmdline.txt
を編集し、行末にcgroup_memory=1 cgroup_enable=memory
を追加します。
これにより、cgroupのメモリサブシステムを有効化します。
elevator=deadline net.ifnames=0 console=serial0,115200 dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 rootwait fixrtc quiet splash cgroup_memory=1 cgroup_enable=memory
K3sインストールスクリプトの実行
K3sのインストールスクリプトを実行し、エージェントとしてインストールします。
K3S_TOKEN
にはサーバーから取得したトークンを指定します。
また、node-name
はクラスタ内でユニークなものにしてください。
# curl -sfL https://get.k3s.io | K3S_URL=https://192.168.0.16:6443 K3S_TOKEN="サーバーから取得したトークン" sh -s - --node-name agent
各ノードの確認
kubectl
コマンドでノードを確認すると、クラスタの構築を確認することができます。
ちなみに、Kubeconfigは/etc/rancher/k3s/k3s.yaml
に出力されています。
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
agent2 Ready <none> 209d v1.26.4+k3s1
server Ready control-plane,master 209d v1.26.4+k3s1
agent1 Ready <none> 209d v1.26.4+k3s1
おわりに
今回はクラスタの構築で一旦終了となりますが、この後時間があれば、実際にPodを載せるところまで別記事に書ければと思っています。