概要
ProxmoxのLXCコンテナ上でK3sクラスターを構築した際の実体験をまとめる。
構築は生成AIに確認しつつ、エラーログをコピペしながら進めていった。
生成AIの言うとおりにすればすべてそのままうまくいく・・・こともなかったので
自宅ラボ環境においてk3s環境を構築するまでの手順と、実際に遭遇したトラブルの解決方法を記事にしていく。
環境・前提条件
ハードウェア環境
- Proxmox VE 9.x系
- 利用可能RAM: 16GB
- ストレージ: 50GB以上の空き容量
ネットワーク環境
- 外部ネットワーク: 192.168.100.0/24
- 内部ネットワーク(作成予定): 10.0.0.0/24
- 既存サービス: Nginx Proxy Manager等
前提知識
- 基本的なLinux操作
- コンテナ技術の概要理解
- Proxmoxの基本操作
ノード構成:
| ノード名 |
役割 |
CPU |
RAM |
ストレージ |
IP |
| k3s-master |
Control Plane |
2コア |
2GB |
10GB |
10.0.0.10 |
| k3s-node01 |
Worker |
2コア |
1.5GB |
8GB |
10.0.0.11 |
| k3s-node02 |
Worker |
1コア |
1GB |
8GB |
10.0.0.12 |
合計リソース:
- CPU: 5コア
- RAM: 4.5GB
- ストレージ: 26GB
構築手順
1. Proxmoxホスト側の準備
カーネルモジュールの有効化(重要):
# Proxmoxホストで実行
modprobe br_netfilter
modprobe overlay
# 永続化設定
echo 'br_netfilter' >> /etc/modules
echo 'overlay' >> /etc/modules
# 確認
lsmod | grep br_netfilter
lsmod | grep overlay
注意点:この手順を行わないと、後でk3sサービスが起動失敗を繰り返した。
2. LXCコンテナの作成
手動作成の場合:
- ProxmoxのWeb UI > Create CT
- Template: ubuntu-22.04-standard
- Disk: 上記表の通り設定
- CPU/Memory: 上記表の通り設定
- Network: vmbr1(内部ネットワーク用)
例外ケース:
- ネットワークブリッジが存在しない場合は事前に作成が必要
- 十分なリソースがない場合、最低限Master 1.5GB、Worker 1GBでも動作
3. 各LXCコンテナの初期設定
全ノード共通:
# パッケージ更新
apt update && apt upgrade -y
# 最低限ツールインストール
apt install -y curl
# k3s用設定ファイル作成
# curlによるk3sのinstall前に実施した場合、失敗したこともあったので
# 後に行って、k3s,k3s-agentの再起動をすると動作した事象があった。
mkdir -p /etc/rancher/k3s
tee /etc/rancher/k3s/config.yaml << EOF
kubelet-arg:
- "feature-gates=KubeletInUserNamespace=true"
- "cgroup-driver=cgroupfs"
disable:
- metrics-server
EOF
重要な注意点:LXC環境ではKubeletInUserNamespace=trueが必須です。これを設定しないと以下のエラーで起動失敗する:
Error: failed to run Kubelet: failed to create kubelet: open /dev/kmsg: no such file or directory
4. Masterノードの構築
k3sインストール:
# LXC対応オプション付きインストール
curl -sfL https://get.k3s.io | sh -
起動確認:
systemctl status k3s
kubectl get nodes
トラブルシューティング:
サービスがactivating状態で止まる場合:
# 詳細ログ確認
journalctl -u k3s -f
# カーネルモジュール問題の場合は前述の手順を実行
# その後再起動
systemctl restart k3s
成功時の出力例:
NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 1m v1.33.6+k3s1
5. Workerノードの追加
トークン取得:
# Masterノードで実行
sudo cat /var/lib/rancher/k3s/server/node-token
Workerノードでのjoin:
# 取得したトークンとMasterのIPを指定
curl -sfL https://get.k3s.io | K3S_URL=https://10.0.0.10:6443 K3S_TOKEN="<取得したトークン>" sh -
動作確認:
# Masterノードで全ノード確認
kubectl get nodes
期待される結果:
NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 10m v1.33.6+k3s1
k3s-node01 Ready <none> 5m v1.33.6+k3s1
k3s-node02 Ready <none> 2m v1.33.6+k3s1
アプリケーションデプロイとサービス公開
Nginxデプロイメント作成
# デプロイメント作成
kubectl create deployment nginx --image=nginx
# 確認
kubectl get deployments
kubectl get pods
サービス公開(LoadBalancer)
# LoadBalancerタイプで公開
kubectl expose deployment nginx --port=80 --type=LoadBalancer
# サービス確認
kubectl get svc
出力例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.43.169.93 <pending> 80:31038/TCP 10s
注意点:
- EXTERNAL-IPが<pending>表示は正常(MetalLB等が未設定のため)
- NodePort(この例では31038)経由でアクセス可能
- 全ノードのIP:NodePortでアクセスできる
外部アクセスの確認
アクセス方法:
# 任意のノードIP:NodePortでアクセス
curl http://192.168.100.20:31038 # Masterノード
curl http://192.168.100.21:31038 # Worker1ノード
curl http://192.168.100.22:31038 # Worker2ノード
発生したトラブルと解決方法
1. カーネルモジュール問題
現象:
modprobe: FATAL: Module br_netfilter not found
modprobe: FATAL: Module overlay not found
原因:LXCコンテナではホストカーネルのモジュールにアクセスできない
解決法:Proxmoxホスト側でモジュール読み込み(前述)
2. UserNamespace問題
現象:
Error: failed to run Kubelet: failed to create kubelet: open /dev/kmsg: no such file or directory
原因:LXC環境でのcgroup制限
解決法:feature-gates=KubeletInUserNamespace=true設定(前述)
3. APIサーバー接続拒否
現象:
The connection to the server 127.0.0.1:6443 was refused
原因:k3sサービスの起動失敗または完全な初期化前のアクセス
解決法:
- サービス状態確認:
systemctl status k3s
- ログ確認:
journalctl -u k3s -f
- 起動完了まで待機(通常1-2分)
4. ネットワーク疎通問題
現象:Workerノードのjoinが完了しない
原因:
解決法:
# ポート確認
ss -tlnp | grep 6443
# 疎通確認
nc -zv <master-ip> 6443
# ファイアウォール無効化テスト
ufw disable
運用上の考慮事項
リソース監視
# ノードリソース確認
kubectl top nodes
# Pod単位のリソース確認
kubectl top pods
ログ確認
# Pod ログ
kubectl logs <pod-name>
# サービスログ
journalctl -u k3s -f
バックアップ
# etcdバックアップ(k3sではSQLiteの場合)
cp /var/lib/rancher/k3s/server/db/state.db /backup/
学んだこと・今後の展開
技術的収穫
- LXC環境での制約理解:カーネルモジュールやcgroup制限への対処法を習得
- Kubernetes基礎:Pod、Service、Deploymentの実践的理解
- ネットワーク設計:クラスター内部ネットワークと外部公開の仕組み
- トラブルシューティング:ログ分析とシステムデバッグ能力の向上
今後の活用予定
- アプリケーション開発:マイクロサービスアーキテクチャの実践
- CI/CD構築:GitOps による自動デプロイ環境
- 監視システム:Prometheus + Grafana の導入
- ストレージ管理:PersistentVolume を使用したデータ永続化
まとめ
ProxmoxのLXC環境でのK3sクラスター構築は、いくつかの制約があるものの、適切な設定により安定動作させることができます。特にLXC固有の制限(カーネルモジュールアクセス、UserNamespace)への対処が重要ですが、一度理解すれば再現性の高い環境構築が可能です。
自宅ラボでKubernetesを学習する環境としては、クラウドサービスと比較してコスト面で大きなメリットがあり、実践的なインフラ運用スキルの習得に適しています。
参考: