VyOS 上でコンテナを動かしてみる

# はじめに

VyOS は、Linux ベースのソフトウェアルーターで、単なるルーティング以外にも、豊富な機能を持っているので、自身やチームのラボを構築する際に、非常に便利です。
個人的には、vSphere のラボを構築する際にも、必須級のソフトウェアになっています。

↓こちらの記事で、簡単な紹介もしています。

https://qiita.com/iwaseyusuke/items/0ac51439f476a36fb3ff

普通にルーターとして使っていても便利なのですが、実は VyOS 上では、[Podman](https://podman.io/) でコンテナを実行できます！しかも、お馴染みのコマンド VyOS の管理 CLI 経由で、設定を恒久化できます！

「え？コンテナが動くなら、実質、なんだって動かせちゃうじゃん」ということで、VyOS を単なるルーターで終わらない可能性を感じています。
よって、今回は、VyOS のコンテナ実行機能で遊んでみたいと思います。


# 手順

参考にしている VyOS 公式ドキュメントは、こちらです。

https://docs.vyos.io/en/latest/configuration/container/index.html


## TL;DR;

例によって、VyOS の操作が分かる人には、実際の設定を見ていただく方が早いかと思います。
が、今回に限っては、これを実行するだけでも、何回か詰まった部分があるので、そこも含めて記載して行きます。

```text: フォーマット
container {
    name <name> {
        allow-host-networks
        image <image>
    }
}
```

```text: 設定例
container {
    name nginx {
        allow-host-networks
        image docker.io/library/nginx:latest
    }
}
```

## (Optional) Registry にログイン

環境によってはやらなくても良いのですが、例えば、Docker Hub のように[レートリミット制限](https://docs.docker.com/docker-hub/download-rate-limit/)がある場合、これに阻まれて、コンテナ イメージが Pull できない可能性があります。
なので、先にログインしておきましょう。

あまり適切な気がしないのですが、podman コマンドの実行に sudo が必要なようです。

```text: フォーマット
sudo podman login [REGISTRY]
```

```text: 実行例
sudo podman login
Username: USERNAME
Password: PASSWORD
````


## (Optional) コンテナ イメージを Pull

利用するコンテナイメージを Pull しておきます。
コンテナ起動時に、自動で Pull されるので、その意味では Optional なのですが、前述の通り、Registry との認証やレート制限で問題が起きると面倒なので、細かくステップを踏んで行きます。

コンテナ イメージの操作に関するコマンドは Operational Mode (`configure` を打つ前のモード) で実行することに注意してください。

```text: フォーマット
add container image <image>
```

```text: 実行例
add container image docker.io/library/nginx:latest
```

今回は、お試しで、nginx を動かすだけなので、Docker Hub で提供されている nginx の最新版を利用しています。

また、このコマンドは、成功時に特に何も出力しないので、本当に取得できているかは、下記のコマンドで確認しておきます。

```text: フォーマット
show container image
```

```text: 実行例
$ show container image
REPOSITORY               TAG         IMAGE ID      CREATED      SIZE
docker.io/library/nginx  latest      eea7b3dcba7e  2 weeks ago  191 MB
```

ちなみに、特定のコンテナを削除する場合には、下記のコマンドになります。

```text: フォーマット
delete container image <image>
```

## コンテナの起動設定

ここまで出来ていれば、おおよそトラップは回避できていると思うので、いよいよコンテナを起動するための設定を行なって行きます。
感覚としては、Docker Compose の設定をしているようなイメージでしょうか。

まずは、Configuration Mode に移行します。

```text
vyos@vyos:~$ configure
[edit]
vyos@vyos#
```

次に、実行するコンテナ イメージをしてします。

```text: フォーマット
set container name <name> image <image>
```

```text: 実行例
set container name nginx image docker.io/library/nginx:latest
```

そのまんまですが、`<name>` は実行する際のコンテナ名で、`<image>` が実行するコンテナ イメージになります。

そして、コンテナのネットワークに関する設定を投入します。

```text: フォーマット
set container name <name> allow-host-networks
```

```text: 実行例
set container name nginx allow-host-networks
```

この部分は `podman run` や `docker run` コマンドの `--network host` に相当する設定になります。
これは賛否ある設定ではあると思いますが、ここでは簡単のため、このオプションを利用しています。

`show` コマンドで設定を確認し、意図した通りに設定が投入されていれば OK です。

```text: 実行例
vyos@vyos# show
+container {
+    name nginx {
+        allow-host-networks
+        image docker.io/library/nginx:latest
+    }
+}
...(略)...
```


## コンテナ起動

`commit` コマンドで設定を反映させると、コンテナが起動します。

```text: 実行例
vyos@vyos# commit
[edit]
vyos@vyos#
```

成功している場合、特に出力は無いので、`show` コマンドを使って確認してみます。
そのためには、Operational Mode に戻る (Configuration Mode を `exit` で抜ける) 必要があるので、注意してください。

```text: 実行例
vyos@vyos# exit
Warning: configuration changes have not been saved.
exit
vyos@vyos:~$
```

コンテナ起動を確認するコマンドは下記の通りです。

```text: フォーマット
show container
```

```text: 実行例
vyos@vyos00:~$ show container
CONTAINER ID  IMAGE                           COMMAND               CREATED         STATUS             PORTS       NAMES
4a8f1f854697  docker.io/library/nginx:latest  nginx -g daemon o...  40 seconds ago  Up 40 seconds ago              nginx
```

## 動作確認

VyOS の持ついずれかの IP アドレスに対して、ブラウザからアクセスして、お馴染みの `Welcome to nginx!` が表示されれば成功です。


## (参考) bridge ネットワークの利用

先ほど `--network host` は賛否あると言いました。
では、一般的に好ましいと言われる `--network <network-name>` 指定する bridge ネットワークを利用する場合には、どうしたら良いのか、設定例を示しておきます。

```text: フォーマット
container {
    name <name> {
        image <image>
        network <networkname> {
            address <address>
        }
        port <portname> {
            destination <portnumber>
            protocol <tcp | udp>
            source <portnumber>
        }
    }
    network <networkname> {
        prefix <prefix>
    }
}
```

```text: 設定例
container {
    name nginx {
        image docker.io/library/nginx:latest
        network internal {
            address 172.20.0.2
        }
        port http {
            destination 80
            protocol tcp
            source 8080
        }
    }
    network internal {
        prefix 172.20.0.0/16
    }
}
```

こちらの設定例では、VyOS の持ついずれかの IP アドレス + 8080番ポートにアクセスすると、お馴染みの nginx の画面になるはずです。

設定箇所において、注意が必要そうなところは、↓このあたりです。

* `<networkname>`
    * `bridge` という名称はダメのようです。
    * システムで使われている名称らしく、エラーしました...
* `port <portname>` の `destination` と `source`
    * `podman run` や `docker run` コマンドの `--port destination:source` オプションに相当します。


# まとめ

一言で便利！

ただ...
Podman の設定を全て網羅できている訳では無いので、直接、Podman を実行した方が使い勝手が良い面もありそうです...

とは言え！コンテナが実行できることによって、VyOS 上で実行できるアプリの幅が、ぐっと広がりますので、何か便利な使い方を探って行きたいと思います！