JetsonNano+Docker上のコンテナをホストマシンと同じセグメントに配置した時のメモ


Jetson Nano + Docker上のコンテナに、サーバを複数作ろうとしたときにコケたのでメモ。

難しく考えていたけど下の参考記事のおかげで結構簡単に解決できた。
というかたぶんこれがなかったら解決できなかった・・感謝しかない

環境

  • 開発キット:JetPack 4.3
  • OS: 18.04.3 LTS
  • Docker: 19.03.5

作りたいもの

DockerでJetson Nano上に複数サーバを構築して、あたかもホストマシンと同じセグメント上にいるかのように見せかけたいと思い、格闘しました。
単にポート変換でも行けると思うんですが、それだとあんまりイケてないなーと感じたので戦ってみました。

ホストのネットワーク設定

まずはJetson Nanoのネットワーク(eth0)を確認します。

$ ifconfig
...
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.11  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 xxxx:xx:xxxx:xxxx:xxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x0<global>
        inet6 xxxxxxxxxxxxxxxxxxxx  prefixlen 64  scopeid 0x20<link>
        ether xxxxxxxxxxxxxxxxx  txqueuelen 1000  (Ethernet)
        RX packets 138314  bytes 105082864 (105.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42142  bytes 3724547 (3.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 151  base 0x5000
...

Dockerのネットワーク設定(macvlan)

Dockerのnetworkコマンドでネットワークの一覧を確認できますが、インストール時に構成されるネットワーク設定では上の絵の環境は作成できません。

そこで、macvlanインターフェースを作成し、コンテナ起動時にそのネットワークを利用するよう設定します。

macvlanとは?

1つの物理NICに対して、仮想的なNICを複数作成することができる機能のようです。詳細は別の方の記事を参照。

Dockerのネットワーク作成

ホストのネットワーク設定をもとに、Docker createでネットワークを作成します。以下のコマンドは、Jetson Nanoのeth0上にmacvlanのネットワークを作成します。

# ネットワークの作成
$ docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 shared_nw
# 作成したネットワークの確認
$ docker network inspect shared_nw
[
    {
        "Name": "shared_nw",
        "Id": "552a5787314480bd94c43582f7a46968d7bea985b93d7a90f3923a859be32e73",
        "Created": "2020-01-24T00:31:59.856134246+09:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "parent": "eth0"
        },
        "Labels": {}
    }
]

Dockerコンテナの起動

ネットワークが作成できたので、あとはこのネットワークを利用したコンテナを起動します。
例ということで、素のApacheサーバを192.168.1.12に起動させます。

# Jetson Nanoと同じセグメント上のIP:192.168.1.12にWebサーバを起動
$ docker run -itd --net=shared_nw --ip=192.168.1.12 httpd

Webブラウザでアクセスすると、よく見る「It Works!」を見ることができます。

制限事項

この方法でコンテナを起動した際、制限としてJetson Nanoからコンテナへのアクセスができなくなります。
(今回の場合、例えばJetson NanoからApacheサーバへWebブラウザを使ってアクセスができません)
これはmacvlanの機能上回避する方法はないみたいです。