Proxmoxのコンテナ(CT)でK3Sを動かす

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

multipassから撤退しました。
後から私のmultipassの記事を消しておきますがUbuntuのmultipassを結構気に入ってたんですよ。コマンドラインからサクッとVMを作れるのが便利で、起動用のシェルスクリプトとか作ってCI/CDに組み込んだりして、便利に使ってました。
しかし、multipassでネットワークをブリッジにして仮想マシンを動かそうとするとmultipassからlxdに接続してmultipassコマンドからLXDを動かすんですが、それだと何とも不安定になってしまって。動いていたと思ってホストマシンを再起動したら動かなくなったり、もうイヤ。
ってことで、proxmoxへ転びました。手元でvmware esxiを動かせるようなマシンはないですし。

そこで、Proxmoxを使ってLXCコンテナでDockerコンテナも動くので、LXCコンテナでK3Sを動かしてみました。(ググるといくつか記事も出てくるので「ググっても出てこない」ということはないですね)

# 1. 環境

ホストマシン: 4X4 BOX-V1000M
Proxmox: Virtual Environment 7.4-3
ProxmoxのコンテナOSでK3SのホストOS: Ubuntu 22.04.2 LTS

# 2. Proxmoxホストを設定する

# 2－1. ブリッジフィルタリングがオフになっているか確認する

```
cat /proc/sys/net/bridge/bridge-nf-call-iptables
```

0ならOKです

# 2-2. スワップをオフにする

```
sysctl vm.swappiness=0
swapoff -a
```

# 3. IPフォワーディングを有効化

```
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl --system
```

再起動は不要

# 2. Proxmox上でコンテナ(CT)を作る
## 2－1. コンテナ作成

`非特権コンテナ`は外して「特権コンテナ」として動かします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/0133a599-3246-bf48-85c8-b69dac6f0828.png)

パスワードはちゃんと付けましょう。
CT ID(コンテナID)は覚えておく。後で使います。

## 2-2. テンプレート

テンプレートは、`Ubuntu 22.04LTS`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/6e267260-e5f8-ba01-1065-103e10bbc111.png)

## 2-3. ディスクサイズ
ディスクサイズはお好きにどうぞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/70610630-4b79-fb9b-fda1-6d7b6e8300c2.png)

## 2-4. CPU数
CPU数もお好きにどうぞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/5099d568-d3eb-853a-14b4-c6b30d95d203.png)

## 2-5. メモリーサイズ
メモリーは、K3Sと言えども8GBぐらいあると安心です(4GB程度でも動きます)
スワップは0にしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/fe4a89ee-9194-80f3-4c6e-f0acaf4cda12.png)

## 2-6. ネットワーク
IPアドレスは静的でもDHCPでもいいですがK3SでIPアドレスが変わるのは良くないので、静的につけましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/79a92e42-4d01-9fbc-f9ef-1bb7fd938d53.png)

## 2-7. DNS
DNSも指定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/001a42a6-a84f-6ba4-6793-0096008cfb98.png)

コンテナ(CT)を作ってもまだ起動しないでください。

# 3. コンテナ(CT)を動かさず、コンテナ(CT)の設定をProxmoxホスト側で行う

Proxmoxホスト側でシェルを開きます
`/etc/pve/lxc`配下のXXX.confファイルをviで開いて編集します。
XXXはコンテナIDが入ります。今回は、103だったので、`/etc/pve/lxc/103.conf`ファイルを編集します


```shell
cd /etc/pve/lxc/
vi 103.conf
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/c15f30e6-79aa-9ef0-851b-18afae870f99.png)

viで開いたファイルの一番下に以下の4行を追加します

```
lxc.apparmor.profile: unconfined
lxc.cgroup.devices.allow: a
lxc.cap.drop:
lxc.mount.auto: "proc:rw sys:rw"
```

# 4. コンテナ(CT)を起動して、コンテナ(CT)の設定をProxmoxホスト側で行う

コンテナ(CT)を動かしてカーネルブート設定をProxmoxホストからコンテナ側にコピーします

Proxmoxホストのシェルで以下のコマンドを実行します
```
pct push <container id> /boot/config-$(uname -r) /boot/config-$(uname -r)
```

今回コンテナIDは`103`なので以下のようにしました
```
pct push 103 /boot/config-$(uname -r) /boot/config-$(uname -r)
```

`can only push files to a running CT`と出たらコンテナ(CT)が動いていないので起動してください。

# 5. コンテナ(CT)を起動して、コンテナ(CT)内で/dev/kmsgを作るサービスを設定する

Kubernetes(kubelet)では、/dev/kmsgへログを出力するのですが、コンテナ(CT)では存在しないので、/dev/consoleからシンボリックリンクを張ります。

/dev/kmsgがなければ、/dev/consoleへシンボリックリンクを張るスクリプトを作ります。

```shell:/usr/local/bin/conf-kmsg.sh
#!/bin/sh -e
if [ ! -e /dev/kmsg ]; then
    ln -s /dev/console /dev/kmsg
fi

mount --make-rshared /
```

これをsystemdでコンテナ(CT)起動時に呼び出されるようにします。

```systemd:/etc/systemd/system/conf-kmsg.service
[Unit]
Description=Make sure /dev/kmsg exists

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/local/bin/conf-kmsg.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target
```
ファイルができたら、以下のコマンドで実行権限を付けてサービスを有効化します。

```shell
chmod +x /usr/local/bin/conf-kmsg.sh
systemctl daemon-reload
systemctl enable --now conf-kmsg
```

念のため、`/dev/kmsg`ができているか確認します。

```
ls -la /dev/kmsg
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/08663600-3376-7fe2-f983-6425064b304e.png)

問題なさそうです。

# 6. コンテナ(CT)にK3Sをインストールする
お待ちかねのK3Sです。

## 6-1. コンテナ(CT)内での下準備

root権限でずっと操作するのも何なので、アカウントを追加してターミナルで操作します。
ついでにcurlコマンドも入れておきます。

Proxmoxのコンテナ(CT)内のシェルでuserというユーザーを追加し、sudoグループへ追加
```shell
adduser user
usermod -aG sudo user
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/2c1bf624-aa97-17e0-a656-5401b981c183.png)

curlコマンドも追加しておきます

```shell
apt update
apt install -y curl
```

以降は、ubuntuに作ったuserユーザーで操作します。

## 6-2. k3supをインストール

k3supバイナリをダウンロード

```shell
curl -sLS https://get.k3sup.dev | sh
```

k3supファイルを`/usr/local/bin`へ配置

```shell
sudo cp k3sup /usr/local/bin/k3sup
```

`k3sup version`でバージョン確認

```shell
k3sup version
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/72012569-fb03-068f-0419-644482c44d02.png)

## 6-3. k3sup installでK3Sをインストール

```
k3sup install --local --user=$USER --local-path ./kubeconfig --k3s-version=v1.26.6+k3s1
```

## 6-4. K3Sデプロイ状況確認

journalctlコマンドでK3Sのログを見ます

```shell
sudo journalctl -u k3s -f
```

以下のようなメッセージが出たらセットアップ終了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/8faa24c3-ee8c-e57d-49bd-7dd16eefa6c7.png)

# 7. K3S動作確認

以下のコマンドで動作を確認します

```shell
# Test your cluster with:
export KUBECONFIG=/home/user/kubeconfig
kubectl config use-context default
kubectl get node -o wide
```
以下のようになれば動いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/cb4591bf-990d-1c11-003a-2bb260155d7c.png)


# 参考文献

k3s in LXC on Proxmox
https://gist.github.com/triangletodd/02f595cd4c0dc9aac5f7763ca2264185?permalink_comment_id=3998596

Rancher K3s: Kubernetes on Proxmox Containers | Garrett Mills
https://garrettmills.dev/blog/2022/04/18/Rancher-K3s-Kubernetes-on-Proxmox-Container/

ProxmoxVEのLXCでKubernetesクラスタを構築する。
https://zenn.dev/ddpn08/articles/d85176619f3fdd#general