0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

QNAP NASのDocker NetworkでIPv6のコンテナを動かす。

Posted at

はじめに

QNAP NASのContainer Stationで動かすDockerコンテナをIPv6対応させたかったので、IPv6対応させるために行った作業についてまとめます。

QNAP NASのDocker Networkについて

QNAP NASのコンテナネットワークはQNAP NASのコンテナサービスとなる「Container Station」と仮想ネットワーク等を管理する「ネットワークと仮想スイッチ」サービスを使ってQNAP NASのコンテナとネットワークは管理されております。

また、QNAP NASではqnetというDockerの専用ドライバを使用することでQNAP NASが所属するネットワークにNAT、IPマスカレード無しでコンテナを接続することができるため、「Container Station」で作成したDockerコンテナサービスを直接公開することができます。

そのため、私も今までIPv4アドレスを割り振ったサービスをローカルでいくつか公開して使っていたのですが、qnetドライバは現状IPv6に対応していないようなので、qnetドライバでIPv6に対応したネットワークを作成できませんでした。

調べた結果、qnetドライバではIPv6を有効化できませんが、bridgeであればIPv6対応したネットワークを作成することができたため、今回は以下のようなネットワークを作っていきたいと思います。

network.png

Docker NetworkでのbridgeタイプのIPv4とIPv6の動作について

Dockerで仮想スイッチを作成する際、bridgeタイプで作成した場合、Dockerコンテナから外のネットワークへの通信はIPマスカレードでの通信となることから、Dockerコンテナに割り振られているIPv4アドレスに対して、外から直接アクセスすることはできません。

但し、現状のDockerのBridgeドライバではIPv6はアドレス変換が行われずに直接ルーティングでアクセスできるようになっております。

アドレス変換を行わずにIPv6ネットワークを使用する方法はbridge以外でもmacvlanのドライバを使用する方法もありますが、macvlanドライバを使用した場合はコンテナを動作させているホストマシン(今回の例で言うとQNAP NAS)と直接通信することが不可となるため、QNAP NASで実行しているサービスを利用できなくなることから、今回はbridgeドライバでネットワークを作成しようと思います。

IPv6通信用bridgeネットワークの作成

IPv6を使えるように有効化したbridgeネットワークを作成します。

IPv6を有効化したbridgeネットワークは「Container Station」や「ネットワークと仮想スイッチ」からでは作成できないため、QNAP NASにSSH接続を行い、コマンド操作でIPv6対応したbridgeネットワークを作成します。

IPv6通信用bridgeネットワークの作成
docker network create \
  --driver bridge \
  --scope local \
  --opt iface=eth0 \
  --ipv6 \
  --ipam-opt iface=eth0 \
  --ipam-driver default \
  --subnet fd00:0:0:2::/64 \
  --gateway fd00:0:0:2::1 \
  bridge-ipv6-eth0

create後の結果が以下となります。

qnet-static-eth0-fab139が元々作成済みのIPv4通信用ネットワーク、bridge-ipv6-eth0がIPv6用に作成したネットワークとなります。

docker network create後のネットワーク状態
$ docker network ls
NETWORK ID     NAME                      DRIVER    SCOPE
c69ee8ec48f0   bridge                    bridge    local
85bee7f2bb05   bridge-ipv6-eth0          bridge    local
172cc8f12d59   host                      host      local
3e1cc3fb4df2   none                      null      local
b62342c908aa   qnet-static-eth0-fab139   qnet      local

今回作成したbridge-ipv6-eth0はIPv6用なのでIPv4の設定は行いませんでしたが、IPv4を無効化することはできないようなので、作成後docker network inspectコマンドで確認すると自動でIPv4のネットワークも割り当てられていることが確認できます。

docker network inspect bridge-ipv6-eth0
[
    {
        "Name": "bridge-ipv6-eth0",
        "Id": "85bee7f2bb050f984d61db1508172731f44a2ef7ec12539f7ee29006417b2368",
        "Created": "2025-07-21T13:48:54.828101226+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": true,
        "IPAM": {
            "Driver": "default",
            "Options": {
                "iface": "eth0"
            },
            "Config": [
                {
                    "Subnet": "172.29.0.0/24"
                },
                {
                    "Subnet": "fd00:0:0:2::/64",
                    "Gateway": "fd00:0:0:2::1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "iface": "eth0",
            "parent": "eth0"
        },
        "Labels": {}
    }
]

Dockerコンテナの作成

IPv6用ネットワークを作成したため、IPv4のネットワークとIPv6のネットワークに接続したDockerコンテナを作成します。

今回はDockerコンテナ上のインタフェースとしては2つのインタフェースを持ち、IPv4通信はqnetドライバで作成済みのネットワーク、IPv6通信は先ほど作成したbridgeドライバで作成したネットワークを使用して通信するように設定します。

Dockerコンテナの作成はQNAP NASにインストールされているContainer Stationで作成しますが、Container Stationの「コンテナ」からは2つのインタフェースを指定したコンテナの作成はできないため、「アプリケーション」からDocker Composeの形式で2つのインタフェースを設定したコンテナをデプロイします。

以下テスト用に作成したDocker Composeの例。

テスト用Docker Compose
services:
  docker-test:
    image: alpine:latest
    container_name: docker-test
    hostname: docker-test
    restart: always
    networks:
      qnet-static-eth0-fab139:
        ipv4_address: 192.168.30.100
      bridge-ipv6-eth0:
        ipv6_address: fd00:0:0:2::100
    cap_add:
      - NET_ADMIN
    command: >
      /bin/sh -c "
        ip route del default &&
        ip route add default via 192.168.30.1 &&
        while :; do sleep 10; done
      "
networks:
  qnet-static-eth0-fab139:
    external: true
    ipam:
      config:
        - subnet: 192.168.30.0/24
        - gateway: 192.168.30.1
  bridge-ipv6-eth0:
    external: true
    enable_ipv6: true
    ipam:
      config:
        - subnet: fd00:0:0:2::/64
        - gateway: fd00:0:0:2::1

それぞれのDockerネットワークに接続するためのネットワーク設定(後述で補足)と、コンテナを停止させないようにするためのwhileループ設定を入れています。

複数インタフェースが存在する場合のルーティング設定

Dockerコンテナのネットワーク設定は、コンテナ起動時にDHCPで設定されるため、Docker Compose等で指定すれば自動的にIPやデフォルトゲートウェイが設定されます。

ただ、複数のインタフェースに所属させるような場合のデフォルトゲートウェイ設定は早いもの勝ちになるようで、意図したインタフェースにデフォルトゲートウェイ設定を行うようなことが難しいようです。

今回IPv4に所属するインタフェースが2つあるため、物理ネットワークセグメント側をデフォルトゲートウェイとしたいのですが、Docker Composeの設定だけではgateway設定を行わなかった場合であっても仮想ネットワークセグメント側にデフォルトゲートウェイが設定されてしまったため、上記のようにcommandでルーティング設定を意図的に設定するようにしました。

ルータへのルーティング設定

IPv4通信で使用するインタフェースはqnetドライバのネットワークに接続していることから、Dockerホスト側(QNAP NAS)と同じネットワークに接続しているように見えます。

IPv6通信で使用するインタフェースはDockerホスト内に構成されたDockerネットワークに隔離されていることから、Dockerホストがルーティングして内部のDockerコンテナに届ける必要があるため、ルータにルーティング設定を行い、物理ネットワークとDockerネットワーク間で相互に通信できるように設定します。

私の環境では上記の構成図で言うと物理ネットワークセグメント内でヤマハルータを使用しているため、以下のようにゲートウェイをQNAP NASに指定してコマンド設定しました。

ヤマハルータでのIPv6ルーティング設定
ipv6 route fd00:0:0:2::/64 gateway fd00:0:0:1::5%lan1

テスト用Dockerコンテナからの疎通確認

一通り設定が終わったので先程作成したテスト用コンテナに接続して疎通確認してみます。

先ほど作成したテスト用コンテナへの接続
docker ps    # コンテナIDの確認
docker exec -it [先ほど作成したAlpineのコンテナID] /bin/sh

以下、今回作ったテスト用コンテナのIP状態とIPv4/IPv6ルーティングテーブル。

IP設定
# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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 ::1/128 scope host
       valid_lft forever preferred_lft forever
728: eth1@if729: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 02:42:c2:89:38:2e brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.100/24 brd 192.168.30.255 scope global eth1
       valid_lft forever preferred_lft forever
730: eth0@if731: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:1d:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.29.0.2/24 brd 172.29.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd00:0:0:2::100/64 scope global flags 02
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe1d:2/64 scope link
       valid_lft forever preferred_lft forever
IPv4ルーティングテーブル
# ip route show
default via 192.168.30.1 dev eth1
172.29.0.0/24 dev eth0 scope link  src 172.29.0.2
192.168.30.0/24 dev eth1 scope link  src 192.168.30.100

commandで設定したため、想定通りデフォルトゲートウェイが物理ネットワークセグメント側に向いています。

IPv6ルーティングテーブル
# ip -6 route show
fd00:0:0:2::/64 dev eth0  metric 256
fe80::/64 dev eth0  metric 256
default via fd00:0:0:2::1 dev eth0  metric 1024

IPv6は物理ネットワークセグメント側(qnet)ではそもそも有効化していない(できない)ため想定通りデフォルトゲートウェイが仮想ネットワークセグメント側に向いています。

物理ネットワークセグメントに存在するヤマハルータに対して、Dockerコンテナからヤマハルータに疎通確認を行った結果が以下となります。

ヤマハルータのIPv4アドレスへのPing
# ping -c 3 192.168.30.1
PING 192.168.30.1 (192.168.30.1): 56 data bytes
64 bytes from 192.168.30.1: seq=0 ttl=255 time=1.432 ms
64 bytes from 192.168.30.1: seq=1 ttl=255 time=0.221 ms
64 bytes from 192.168.30.1: seq=2 ttl=255 time=0.216 ms

--- 192.168.30.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.216/0.623/1.432 ms
ヤマハルータのIPv6アドレスへのPing
# ping6 -c 3 fd00:0:0:1::1
PING fd00:0:0:1::1 (fd00:0:0:1::1): 56 data bytes
64 bytes from fd00:0:0:1::1: seq=0 ttl=63 time=0.568 ms
64 bytes from fd00:0:0:1::1: seq=1 ttl=63 time=0.295 ms
64 bytes from fd00:0:0:1::1: seq=2 ttl=63 time=0.307 ms

--- fd00:0:0:1::1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.295/0.390/0.568 ms

ヤマハルータにルーティング設定を行ったことで、IPv4通信は直接物理ネットワークセグメント間で通信、IPv6通信はルーティングで各セグメント間を繋ぐことで想定のネットワーク設定を行うことができました。

おわりに

今回はQNAP NASに搭載されているDockerを使い、IPv6で通信できるように設定を行ってみました。

qnetドライバのように、Dockerのネットワークと物理ネットワークを直接IPv6で繋ぐことはできませんでしたが、NAT変換せずにルーティングだけでアクセスすることができるようになりました。

qnetドライバがIPv6対応して、QNAP NASが接続している物理ネットワークと直接通信できるようになればネットワーク構成がもう少しシンプルになるため、今後の対応を期待して待とうと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?