はじめに
一般のご家庭向けです
逸般の誤家庭の方は、物理マシンでお試しください
※ YouTubeへのリンクです。音量に注意してください
この記事は
「Dockerのネットワークを使って、ネットワークの勉強をしたい」
そんな時、素早くDockerネットワークを構築できるとよい
素早くDockerネットワークを構築するための docker-compose.ymlと、その周辺フォルダー環境を書き残した記事です
コピペに次ぐコピペで、とりあえずAネットの端末からBネットの端末へPINGが通るようになります
フォルダ構成
適当な場所に適当なフォルダを作ったら
その下にdocker-compose.ymlを置く
さらに clietn1, client2, router フォルダをつくる
各フォルダの中には mnt フォルダと Dockerfile をつくる
mntフォルダにはentrypoint.shを入れる
以上!
│ docker-compose.yml
│
├─client1
│ │ Dockerfile
│ │
│ └─mnt
│ entrypoint.sh
│
├─client2
│ │ Dockerfile
│ │
│ └─mnt
│ entrypoint.sh
│
├─router
│ │ Dockerfile
│ │
│ └─mnt
Dockerfile
3つあるDockerfileの中身は共通です
Ubuntuをベースに、ネットワーク関連のパッケージをインストールしておきます
FROM ubuntu:latest
RUN apt update
RUN apt install -y vim iputils-ping iproute2 net-tools traceroute
※もっと軽量なイメージを使えばいいと思いましたが、今後実機を使うことを想定すると、無難なUbuntuがいいかなーと思いUbuntu採しました
docker-compose.yml
長ったらしく書いてますが、単に client1 が client2 に対してPING打つためだけの環境です
登場人物 | IPアドレス | 役割 |
---|---|---|
client1 | 172.23.1.10 | PING送る人 |
client1 | 172.23.2.10 | PING受ける人 |
router | 172.23.1.250, 172.23.2.250 | 2つのネットワークに所属してPING中継する人 |
version: '3.9'
services:
client1:
build: ./client1
container_name: client1
hostname: client1
tty: true
stdin_open: true
privileged: true
volumes:
- ./client1/mnt:/mnt
networks:
delay-net1:
ipv4_address: 172.23.1.10
command: bash -c "bash /mnt/entrypoint.sh && /bin/bash"
client2:
build: ./client2
container_name: client2
hostname: client2
tty: true
stdin_open: true
privileged: true
volumes:
- ./client2/mnt:/mnt
networks:
delay-net2:
ipv4_address: 172.23.2.10
command: bash -c "bash /mnt/entrypoint.sh && /bin/bash"
router:
build: ./router
container_name: router
hostname: router
tty: true
stdin_open: true
volumes:
- ./router/mnt:/mnt
networks:
delay-net1:
ipv4_address: 172.23.1.250
delay-net2:
ipv4_address: 172.23.2.250
sysctls:
- net.ipv4.ip_forward=1
networks:
delay-net1:
ipam:
driver: default
config:
- subnet: 172.23.1.0/24
delay-net2:
ipam:
driver: default
config:
- subnet: 172.23.2.0/24
いくつかのポイント説明
ボリュームをマウント
/mnt
フォルダを介して、ホストマシンでつくったシェルスクリプトなどを共有します
volumes:
- ./client1/mnt:/mnt
mntフォルダにentrypoint.shを入れておきます
ルーティング
ルーターは各クライアントのデフォルトゲートウェイとなります
デフォルトゲートウェイとなるためには、静的ルーティングを変更する必要があります(既定ではインターネットに向かってパケットを送信してしまう)
静的ルーティングを変更するには管理者権限が要るので、privileged: true
としています
また、Ubuntuは既定でポートフォワードをしてくれますが、無効にした場合の挙動もみてみたいので、あえてポートフォワードの設定を明示しています
今回はポートフォワードしてもらってPING中継するので、下記設定です
sysctls:
- net.ipv4.ip_forward=1
コンテナに入って作業するために
下記の3行は、コンテナがすぐに終了しなようにするための措置です
意味はよくわかりません
コマンドでエントリポイントのシェルスクリプトを実行したあとに、&&
でつないでbashを再度実行してます
tty: true
stdin_open: true
command: bash -c "bash /mnt/entrypoint.sh && /bin/bash"
entrypoint.sh
エントリポイントで静的ルーティングを設定します
client1,2でそれぞれゲートウェイが異なるので、2つのシェルスクリプトを掲載しますが、差異は微々たるものです
- client1
- 172.23.2.0/24に向かうパケットは172.23.1.250(ルータ)を目指して送出
#!/bin/bash
# 静的ルーティング
ip route add 172.23.2.0/24 via 172.23.1.250
- client2
- 172.23.1.0/24に向かうパケットは172.23.2.250(ルータ)を目指して送出
#!/bin/bash
# 静的ルーティング
ip route add 172.23.1.0/24 via 172.23.2.250
いざ実行
docker-compose.ymlが置いてあるフォルダで下記コマンドを実行
docker compose up --build -d
クライアント1号機のコンテナに入って作業する
docker compose exec client1 bash
クライアント2号機に向けてtraceroute
とping
をした結果
client1 | traceroute to 172.23.2.10 (172.23.2.10), 30 hops max, 60 byte packets
client1 | 1 172.23.1.250 3.333 ms 0.153 ms 0.114 ms
client1 | 2 172.23.2.10 0.486 ms 0.168 ms 0.100 ms
client1 | PING 172.23.2.10 (172.23.2.10) 56(84) bytes of data.
client1 | 64 bytes from 172.23.2.10: icmp_seq=1 ttl=63 time=1.90 ms
client1 | 64 bytes from 172.23.2.10: icmp_seq=2 ttl=63 time=0.100 ms
client1 | 64 bytes from 172.23.2.10: icmp_seq=3 ttl=63 time=0.116 ms
client1 | 64 bytes from 172.23.2.10: icmp_seq=4 ttl=63 time=0.092 ms
client1 |
client1 | --- 172.23.2.10 ping statistics ---
client1 | 4 packets transmitted, 4 received, 0% packet loss, time 3118ms
client1 | rtt min/avg/max/mdev = 0.092/0.552/1.903/0.779 ms
ちゃんとルータ(172.23.1.250)を通っていることがわかる
おわりに
Dockerを使って手軽にPING疎通テストできる環境をつくった
しかもすべてスクリプトにお任せしているので、構築・破壊が容易
1年後でも、ここからコードをコピペすれば再現できる
今回つくったdocker-compose.ymlをベースにして
次回からはルータに機能を付与していきたい
パケットをわざと遅らせてみたり・・・(その布石がymlファイルの中にも書いてある)
付録 Docker Composeコマンド集
未来の自分のための備忘録
# Dockerfileを変更したときは --build 付ける
docker compose up -d
docker compose up --build -d
# Dockerfileを変更して、かつ再起動したいときは
docker compose down -v && docker compose up --build -d
# ログを見る
docker compose logs -f
# 今日はもう作業しないよ、ってとき
docker compose down -v
# 案外使わない再起動
docker compose restart