Docker コンテナ上のサービスに外部からアクセスするためには、 ポートマッピングや、ホストネットワークモードを使用する方法がありますが、 これらの方法では他のコンテナとポートがぶつからないように気をつける必要があります。
しかし、例えば、検証のために同一環境だが別々のコンテナを立ち上げて同時に使用したい等の場合には、他のコンテナがどのポートを使用しているかは意識したくはありません。
そこで、ルータへの static route の追加と、Docker ホストへの簡単な設定のみで、 ホストのポートを意識せずにコンテナを立ち上げて使用できるようにしてみます。
- 構成のイメージ
WAN
|
+-------------------------------+
| Router |
+-------------------------------+
| |
| 192.168.1.3 | 192.168.1.2
+---------+ +--------------+
| client | | Ubuntu 18.04 |
+---------+ | |
| (Docker Host)|-----------------+
+--------------+ |
| | 172.17.0.0/16 |
| +--------------+ |
| | | |
| +---------+ +---------+ |
| | Docker | | Docker | |
| |container| |container| |
| +---------+ +---------+ |
+------------------------------+
EdgeRouter X をルータとして使用します。
今回準備した Docker ホストのアドレスは 192.168.1.2 です。
また、docker0 はデフォルトでは 172.17.0.0/16 ですので、この設定のまま使用してみます。
$ # EdgeRouter X の設定
$ configure
# set protocols static route 172.17.0.0/16 next-hop 192.168.1.2
# commit
# save
設定方法は使用するルータのドキュメントを確認してください。
次に Docker ホスト側の設定です。
パケット転送を有効にします。
# echo 1 > /proc/sys/net/ipv4/ip_forward
コンテナを立ち上げるため、docker context を使用して、上記で設定した Docker ホストに切り替えておきます。
$ docker context create --docker "host=ssh://hexa@192.168.1.2" advent-calendar
advent-calendar
Successfully created context "advent-calendar"
$ docker context use advent-calendar
advent-calendar
Current context is now "advent-calendar"
- nginx を別々のコンテナで立ち上げます。
$ docker container run -it --rm --name nginx-1 nginx:1.19.6
$ docker container run -it --rm --name nginx-2 nginx:1.19.5
- 各コンテナの IP アドレスを確認します。
$ docker container inspect nginx-1 | jq -r .[].NetworkSettings.IPAddress
172.17.0.2
$ docker container inspect nginx-2 | jq -r .[].NetworkSettings.IPAddress
172.17.0.3
- curl で 80 番ポートにアクセスできるか確認してみます。
$ # 自分の IP アドレスを確認
$ ifconfig en0 inet | grep -i inet | awk '{ print $ 2 }'
192.168.1.3
$ curl -I -X GET http://172.17.0.2:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Fri, 25 Dec 2020 08:47:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 15 Dec 2020 13:59:38 GMT
Connection: keep-alive
ETag: "5fd8c14a-264"
Accept-Ranges: bytes
$ curl -I -X GET http://172.17.0.3:80
HTTP/1.1 200 OK
Server: nginx/1.19.5
Date: Fri, 25 Dec 2020 08:47:38 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 24 Nov 2020 13:02:03 GMT
Connection: keep-alive
ETag: "5fbd044b-264"
Accept-Ranges: bytes
両方のコンテナともに 80 番ポートで接続出来ることが確認できました。
iptables 等で FORWARD を DROP している場合があるので、ACCEPT に変更します。