Alpine Linux + K3sで実現するRaspberry Piの超軽量Kubernetesノード構築
Summary
- Raspberry Pi 2/3/4でAlpine Linux + K3sによる超軽量Kubernetes環境を構築
- メモリ使用量を300MB程度に抑制し、Ubuntu Server比で大幅なパフォーマンス向上を実現
- 10-20秒の高速ブート時間を達成し、従来のUbuntu Server環境(1分程度)を大幅に改善
やらないこと
- K3s serverの構築手順(本記事はagent構築のみ。server構築手順はk3sドキュメントまたは前回記事を参照)
- 複雑なKubernetesアプリケーションのデプロイメント
- 基本的なパーティション作成、フォーマット操作
本記事における課題
以前、Raspberry Pi に軽量 Kubernetes を導入し高可用な自宅サーバーを実現するでRaspberry Pi 2/3/4でUbuntuベースのKubernetes環境を構築したが、以下の深刻なパフォーマンス問題に直面した:
- メモリ不足の頻発:特にRaspberry Pi 2/3(1GB RAM)ではOSだけでメモリを大量消費
- 起動時間の長さ:Ubuntuでは1分程度の起動時間でレスポンスが悪い
- 運用継続困難:主にメモリ不足からくるパフォーマンスの悪化により、前回記事の運用開始後、Raspberry Pi 2/3を除外していた
これらの課題を解決するため、Alpine Linuxベースの"超"軽量環境を検討し、劇的な改善を実現した経験を共有する。
やったこと
1. Alpine Linux SDカード準備とヘッドレスセットアップ
Alpine LinuxのSDカード準備手順
従来のRaspberry Pi Imagerではなく、ヘッドレス(キーボード+モニタなし)でのAlpine Linuxセットアップを行う。ここでは有線LANが必要である。
1. Alpine Linuxイメージのダウンロード
Alpine LinuxのダウンロードページからRaspberry Pi用のイメージをダウンロードする。
- Raspberry Pi 4/3: aarch64版をダウンロード
- Raspberry Pi 2: armv7版をダウンロード
2. ヘッドレスインストール用Bootstrapのダウンロード
alpine-linux-headless-bootstrapの最新バージョンをダウンロードする。各バージョンごとに headless.apkovl.tar.gz
が準備されている。
3. SDカードのパーティション作成
microSDカードに以下のパーティション構成を作成する:
- パーティション1: 256MB FAT32(ブート用)
- パーティション2: 残り容量 ext4(データ用)
この作業は一般的なパーティション管理ツール(fdisk、gparted等)で実行可能である。
4. Alpine Linuxファイルの展開とコピー
ダウンロードしたAlpine Linuxイメージを展開し、展開後のファイル一式をFAT32パーティションにコピーする。
5. Bootstrapファイルの配置
headless.apkovl.tar.gz
を圧縮ファイルのままFAT32パーティションにコピーする。
最終的に、FAT32パーティションには以下が配置される:
- Alpine Linuxイメージの展開ファイル一式
-
headless.apkovl.tar.gz
(圧縮ファイルのまま)
6. 初回起動とIP特定
# SDカードをRaspberry Piに挿入し、有線LANを接続して電源投入
# SSH接続マシンからRaspberry PiのIPを特定
# 方法1: arp-scanを使用
sudo arp-scan -I eth0 192.168.xxx.0/24
# 方法2: ルーターの管理画面でDHCP払出し状況を確認
7. 初回SSH接続
# 特定したIPアドレスにSSH接続(初回はパスワードなし)
ssh root@192.168.xxx.xxx
2. Alpine Linux初期セットアップ
基本設定(setup-alpine実行)
# SSH接続(初回)
ssh root@192.168.xxx.xxx
# Alpine Linuxセットアップウィザード実行
setup-alpine
セットアップウィザードでの設定内容:
- Hostname: お好きな名前
-
Network Interface: eth0(静的IP設定)
- IP address:
192.168.xxx.xxx
- Netmask:
255.255.255.0
- Gateway:
192.168.xxx.xxx
- IP address:
-
DNS:
192.168.xxx.xxx
- Root Password: お好きなパスワード
-
Timezone:
Asia/Tokyo
-
APK Mirror:
57
(ftp.udx.icscoe.jp) - User: お好きなユーザー名
-
SSH Server:
openssh
-
Disk: Boot media
/media/mmcblk0p1
使用
SSH設定調整と永続化
# rootログインを許可
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
# 設定を永続化用パーティションに書き込み可能にする
mount -o remount,rw /media/mmcblk0p1
# 不要なファイル削除
rm /media/mmcblk0p1/*.apkovl.tar.gz
# 設定をコミット
lbu add /etc/init.d
lbu add /root/.ssh
lbu add /usr/local/bin # for k3s binary
lbu commit -d
# 再起動して設定反映
reboot
:::note alert
rootにパスワードログインできてしまうことは望ましくないので、よりセキュアに運用する場合は鍵認証を推奨する。
:::
3. 軽量ストレージ戦略の実装
データディスク設定
# SDカードパーティション確認
blkid
# データ用パーティションのマウントポイント作成
mkdir /media/mmcblk0p2
# fstabに基本マウント設定追加
echo "/dev/mmcblk0p2 /media/mmcblk0p2 ext4 rw,relatime 0 0" >> /etc/fstab
# マウント実行
mount -a
バインドマウントによるメモリ効率化
Alpine Linuxのlbu(Local Backup Utility)は軽量性を重視した設計であり、大容量データの管理には不適切である。そのため、K3sやTailscaleの大容量データを外部ストレージにバインドマウントする手法を採用した。
# K3s用ディレクトリ作成
mkdir -p /media/mmcblk0p2/k3s/lib
mkdir -p /media/mmcblk0p2/k3s/kubelet
# Tailscale用ディレクトリ作成
mkdir -p /media/mmcblk0p2/tailscale/lib
# fstabにバインドマウント設定追加
cat >> /etc/fstab << 'EOF'
/media/mmcblk0p2/k3s/lib /var/lib/rancher none bind 0 0
/media/mmcblk0p2/k3s/kubelet /var/lib/kubelet none bind 0 0
/media/mmcblk0p2/tailscale/lib /var/lib/tailscale none bind 0 0
EOF
起動時マウント設定
# 起動時スクリプト作成(K3s用)
cat > /etc/local.d/rancher.start << 'EOF'
#!/bin/sh
mkdir -p /var/lib/rancher
mkdir -p /var/lib/kubelet
mount /var/lib/rancher
mount /var/lib/kubelet
EOF
chmod +x /etc/local.d/rancher.start
# Tailscale用起動スクリプト
cat > /etc/local.d/tailscale.start << 'EOF'
#!/bin/sh
mkdir -p /var/lib/tailscale
mount /var/lib/tailscale
EOF
chmod +x /etc/local.d/tailscale.start
# localサービス有効化
rc-update add local
lbu commit -d
4. Tailscale VPN接続設定
# Tailscale公式インストールスクリプト実行
curl -fsSL https://tailscale.com/install.sh | sh
# VPN接続(認証URLが表示されるのでブラウザで認証)
tailscale up
# 接続状態確認
tailscale status
# tailscaleのバイナリ保存
lbu commit -d
5. Kubernetes対応設定
カーネルパラメータ調整
# ブートパーティションを書き込み可能にマウント
mount -o remount,rw /media/mmcblk0p1
# cmdline.txtを編集
vi /media/mmcblk0p1/cmdline.txt
cmdline.txtの設定内容:
modules=loop,squashfs,sd-mod,usb-storage quiet console=tty1 cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
cgroupsとマウント設定
# OpenRCでcgroupsモード設定
echo 'rc_cgroup_mode="unified"' >> /etc/rc.conf
# cgroup v2用マウント設定
echo 'cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0' >> /etc/fstab
# cgroupsサービス有効化
rc-update add cgroups default
# マウント共有設定
cat > /etc/local.d/mount-shared.start << 'EOF'
#!/bin/sh
mount --make-rshared /
EOF
chmod +x /etc/local.d/mount-shared.start
# 設定保存
lbu commit -d
6. K3s Agentインストール
# K3s agentインストール
curl -sfL https://get.k3s.io | \
K3S_TOKEN="XXXXXX" \
K3S_KUBECONFIG_MODE=644 \
sh -s - agent \
--server https://[K3s serverのIPまたはドメイン]:6443 \
--flannel-iface tailscale0
# 設定保存
lbu commit -d
7. パフォーマンス確認
# システムメモリ使用状況確認
free -h
# プロセス別メモリ使用量確認
htop
正確に測ってないが、概ね以前と比べて以下の違いが出た。
Ubuntu 22.04環境:
- 起動時間: 約60秒
- OS基本メモリ使用量: 約100-200MB
- K3s agent + Tailscale込みメモリ使用量: 約400-500MB
- Raspberry Pi 2/3での動作: メモリ不足で実質運用不可
Alpine Linux環境:
- 起動時間: 約10-20秒
- OS基本メモリ使用量: 約80MB
- K3s agent + Tailscale込み: 約300MB
- Raspberry Pi 2/3での動作: 快適に動作
以下はRaspberry Pi 2におけるhtopの実行結果。
一通りセットアップを終えた後、Kuberenetesクラスターに参加し、RedisやCoreDNS、Node Exporter、Promtailなどを動作させている。
この改善により、運用から外れていたRaspberry Pi 2/3でも実用的なKubernetes環境を構築できるようになった。
まとめ・所感
Alpine Linux + K3sの組み合わせにより、前回のUbuntu環境と比較して劇的なパフォーマンス改善を実現できた。特に以下が顕著である:
- 基本コンポーネント(OS+Tailscale+K3s agent)のメモリ使用量の大幅削減: Ubuntu比で40%以上の削減(500MB→300MB)
- 起動時間の短縮: 1分→10-20秒へと大幅改善
- Raspberry Pi 2/3の実用化: 以前は運用困難だったが、今回は快適に動作
特にRaspberry Pi 2/3での動作改善は予想以上で、1GB RAMでも十分な余裕を持って動作している。これにより、古いRaspberry Piも有効活用でき、コストパフォーマンスが大幅に向上した。
従来のUbuntu環境では「使えるが重い」状態だったが、Alpine Linux環境では「軽快で実用的」な環境を実現できている。同様の課題(これまでのイベントで貰ったRaspberry Piを持ち腐らせている?)を抱える方にとって、本手順が参考になれば幸いである。
Discussion