microk8sを用いたcontainer routeの構築

ubuntu: 22.04

# microk8s構築
基本は下記urlの公式サイトに従っている。

https://microk8s.io/docs/getting-started

普段はpackage managerに`apt`を用いているのですが、今回は文献の関係で`snap`を用いる。
```shell
sudo snap install microk8s --classic
sudo groupadd microk8s
sudo usermod -aG mircok8s $USER
mkdir ~/.kube
chmod 700 ~/.kube
```
userにloginしなおしてmicrok8sのgroupsに所属させる。
```shell
microk8s status --wait-ready
```

これで`microk8s kubectl`が使えるようになったが長いので.bashrcに追記する。

```shell
alias kubectl='microk8s kubectl'
```

microk8sにaddonを適当なaddonを追加しておく。
```shell
microk8s enable dns
microk8s enable community
```

# multusをinstall
今回のcontainer routerの肝となるmultusをinstallする。
基本は下記urlの公式サイトに従っている。

https://microk8s.io/docs/getting-started

multusとはcontainerに対してinterfaceを複数持たせることのできるcniである。
詳細はぜひ調べてみてほしい。
今回、普段用いているkubeadmではなくmicrok8sを選択した理由はmultusの動作確認が行えていて、installが簡単だからである。

```shell
microk8s enable multus
kubectl get pod -A

#下記が確認できると思う
kube-system   kube-multus-ds-8ngjd                     1/1     Running            1 (148m ago)   6h12m
```

# vyosのcontainer imageを作成
まず最初にdockerをinstallする。
これは適当なサイトで調べて行って欲しい。

なぜdockerをinstallするのかというとvyosのcontainer imageを作成するためである。
docker hubから持ってきたimageでは失敗したためお勧めしない。
一応、最後に追記として失敗した方法を記述しておく。

dockerをinstallしたらvyosのiso imageからcontainer imageを作成する。
これも下記urlの公式サイトに従って進める。

https://docs.vyos.io/en/latest/installation/virtual/docker.html

```shell
mkdir vyos && cd vyos
wget https://github.com/vyos/vyos-rolling-nightly-builds/releases/download/1.5-rolling-202406270020/vyos-1.5-rolling-202406270020-amd64.iso
mkdir rootfs
sudo mount -o loop vyos-1.5-rolling-202406270020-amd64.iso rootfs
sudo apt install -y squashfs-tools
mkdir unsquashfs
sudo unsquashfs -f -d unsquashfs/ rootfs/live/filesystem.squashfs
sudo tar -C unsquashfs -c . | sudo docker import - vyos:1.5-rolling-202406270020
```

これらのcommandは自分も詳細はわかっていないが大まかに説明する。
まず`wget`でisoを入手している。
次に`mount`でisoを展開している。
最後に、`unsqashfs`というcommandで`filesystem.squashfs`というSquashFSによって圧縮させられているfileを解凍して`docker import`に送っている。
SquashFSとは圧縮されたread onlyなfile systemらしい。

https://qiita.com/stc1988/items/41d9da92ea02fc3d15a3

なにわともあれ、これでdocker内にvyosのcontainer imageが作成できた。
`docker images`を実行すれば確認できると思う。
これをmicrok8sに取り込む。
これも下記urlの公式サイトに従う。

https://microk8s.io/docs/registry-images

```shell
sudo docker save vyos > vyos-image.tar
microk8s ctr image import vyos-image.tar
microk8s ctr images list

# 下記が確認できると思う
docker.io/library/vyos:1.5-rolling-202406270020    application/vnd.oci.image.manifest.v1+json    sha256:2192db0fffe0323eda3841f503e997a08d34f5ef7c24b05df293cd7c4f28c6ab 1.5 GiB   linux/amd64     io.cri-containerd.image=managed
```

このimageでvyosをk8s上で構築する。の前にmultusを構築する。

# multusの構築
multusの数あるtypeの中でも今回はmacvlanを使用する。
multusのtypeについては下記urlを参照するとわかりやすい。
検証なども行われているのでmultusを用いいるときは参照したい。

https://rheb.hatenablog.com/entry/multus_introduction

multusのmanifestは下記のようになった。
```yaml
#macvlan-config.yml
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-conf
spec:
  config: '{
            "cniVersion": "0.3.1",
            "plugins": [
                {
                    "type": "macvlan",
                    "capabilities": { "ips": true },
                    "master": "eno1",
                    "mode": "bridge",
                    "ipam": {
                        "type": "static"
                    }
                }, {
                    "capabilities": { "mac": true },
                    "type": "tuning"
                } ]
        }'
```

今回はmasterがeno1だがこれはそれぞれの環境に合わせて欲しい。
このmanifestをapplyする。

```shell
kubectl create -f macvlan-config.yml
```

# vyosの構築
multusの構築が終わったのでvyosの構築を行う。

manifestは下記のようになった。
```yaml
# vyos-pod.yml
---
apiVersion: v1
kind: Pod
metadata:
  generateName: vyos-pod
  labels:
    app: vyos
  annotations:
    k8s.v1.cni.cncf.io/networks: '[
      {
        "name": "macvlan-conf",
        "interface": "eth1",
        "ips": [ "192.168.0.1/24" ]
      }
    ]'
spec:
  containers:
  - name: multus-vyos
    image: docker.io/library/vyos:1.5-rolling-202406270020
    command:
    - /sbin/init
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /lib/modules
      name: module-volume
  volumes:
  - name: module-volume
    emptyDir: {}
```

注意点としてinterface nameは必ず`eth?`の形式にしないとvyosがinterfaceを認識しない。

vyosを構築する。
```
kubectl create -f vyos-pod.yml
kubectl exec -it vyos-pod -- su - vyos

ip a
```

出力
```plaintext
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 fe80::200:ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if786: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 9e:cb:34:92:a7:be brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.1.71.45/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9ccb:34ff:fe92:a7be/64 scope link
       valid_lft forever preferred_lft forever
4: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether be:6a:30:aa:76:f9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.0.1/24 brd 192.168.0.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::bc6a:30ff:feaa:76f9/64 scope link
       valid_lft forever preferred_lft forever
5: pim6reg@NONE: <NOARP,UP,LOWER_UP> mtu 1452 qdisc noqueue state UNKNOWN group default qlen 1000
    link/pimreg
```

通常のinterfaceのeth0に加えeth1が認識されていることがわかる。
これでcontainer routerが作成された。

routingを行い時は別のmacvlanをさらに構築したりしてvyosに新たな別のnetworkに所属したinterfaceを構築することで行えるようになる。
ここから先はぜひ自分で試してみてほしい。

# 追記

https://hub.docker.com/r/2stacks/vyos

docker hubに落ちていたこのimageではvyosが存在しておらず、さまざまな操作を行うことができなかった。
root userで行おうとしても下記のようなerrorが発生する。

```shell
root@vyos-v92mm:/# configure
You are attempting to enter configuration mode as root.
It may have unintended consequences and render your system
unusable until restart.
Please do it as an administrator level VyOS user instead.
```