LoginSignup
9
1

はじめに

株式会社ピー・アール・オー 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
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としています。

サーバーの場合

wg0.conf(Server)
[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

エージェントの場合

wg0.conf(Agent1)
[Interface]
Address = 172.16.0.2
ListenPort = 51871
PrivateKey = <エージェント1で作成した秘密鍵>

[Peer]
PublicKey = <サーバーで作成した公開鍵>
Endpoint = 192.168.0.16:51871
AllowedIPs = 172.16.0.1
wg0.conf(Agent2)
[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のメモリサブシステムを有効化します。

cmdline.txt
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の設定を追加しておきます。

k3s.service
[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のメモリサブシステムを有効化します。

cmdline.txt
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を載せるところまで別記事に書ければと思っています。

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1