dockerを使用した、ネットワーク通信シミュレーション

## はじめに
Bさん : 「サブネットは、とりあえず ``` /24 ``` にします。」
Cさん : 「ポートは、良くわからないので、8080で設定してます。」

今回もインフラ関係の記事を書いていきます。
今回までに、理解してきたIPアドレスを活用してネットワーク通信シミュレーションを作成していこうと思います。

## 目次
1. 最小ネットワーク構成を考える
1. コンテナの作成と起動
1. pingテスト

## 1. 最小ネットワーク構成を考える
今回は、以下のようなdocker networkを作成していこうと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625910/50640227-7892-db90-c085-332455f63b91.png)


## 2.コンテナの作成と起動
まず、2つの異なるサブネット (192.168.101.0/26 と 192.168.102.0/26) にそれぞれ対応する macvlan ネットワークを作成します。

```bash:使用コマンド
# net101 ネットワークを作成
docker network create -d macvlan \
  --subnet=192.168.101.0/26 \
  --gateway=192.168.101.1 \
  -o parent=eth0.101 net101

# net102 ネットワークを作成
docker network create -d macvlan \
  --subnet=192.168.102.0/26 \
  --gateway=192.168.102.1 \
  -o parent=eth0.102 net102
```

補足
- subnetは、前回説明したサブネットの設定です。
- gatewayは、外の世界（外部ネットワーク）と通信するためのゲートウェイです。
- o parent=eth0 はホストの物理インターフェース(if)を指定します。

#### ルーターコンテナを作成してネットワークを接続
次に、router-container を作成し、両方の macvlan ネットワークに接続します。

```bash: 使用コマンド
# ルーターコンテナを作成
docker run -itd --name router-container --privileged alpine

# net101 と net102 に接続
docker network connect --ip 192.168.101.2 net101 router-container
docker network connect --ip 192.168.102.2 net102 router-container

# host-container1 の作成と接続
docker run -itd --name host-container1 --network net101 --ip 192.168.101.62 --privileged alpine

# host-container2 の作成と接続
docker run -itd --name host-container2 --network net102 --ip 192.168.102.62 --privileged alpine
```

``` Attch shell(docker exec -it コンテナ名　/bin/sh) ```で作成されたdockerコンテナ内に入ります。はじめに、``` host-container1 ```に入ります。
``` ip route ```コマンドをコンテナ内で使用します。
```:ip route
default via 192.168.101.1 dev eth0 
192.168.101.0/26 dev eth0 scope link  src 192.168.101.62 
```

上記から分かるようにDGW(デフォルトゲートウェイ)が外界の世界に繋がっています。DGWとは、特定のIPアドレスに向けて通信を行う場合、一番初めにパケットを送信するものです。今回のネットワーク設計では、routerを経由してc1とc2が接続されているのでDWGは、routerのif（interface）になります。したがって、以下のように設定します。

```:ip route add/del
#host-container1 
#DGWを削除する
ip route del default via 192.168.101.1 dev eth0

# デフォルトゲートウェイを設定
ip route add default via 192.168.101.2 dev eth0
```

補足：
- viaは、何処を経由してきたか
- devは、どこのifに接続されているのか

以下、同様にc2コンテナを作成してください
```:ip route add/del
#host-container2
#DGWを削除する
ip route del default via 192.168.102.1 dev eth0

# デフォルトゲートウェイを設定
ip route add default via 192.168.102.2 dev eth0
```

上記の設定をすることで、ルータを挟んだ通信ができるようになります。

## pingテスト
設定が正常であれば以下のようになっています。
```shell:c1
/ # ping 192.168.101.2
PING 192.168.101.2 (192.168.101.2): 56 data bytes
64 bytes from 192.168.101.2: seq=0 ttl=64 time=0.177 ms
64 bytes from 192.168.101.2: seq=1 ttl=64 time=0.050 ms
64 bytes from 192.168.101.2: seq=2 ttl=64 time=0.081 ms
64 bytes from 192.168.101.2: seq=3 ttl=64 time=0.049 ms
^C
--- 192.168.101.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.049/0.089/0.177 ms

/ # ping 192.168.102.62
PING 192.168.102.62 (192.168.102.62): 56 data bytes
64 bytes from 192.168.102.62: seq=0 ttl=63 time=0.290 ms
64 bytes from 192.168.102.62: seq=1 ttl=63 time=0.074 ms
64 bytes from 192.168.102.62: seq=2 ttl=63 time=0.055 ms
64 bytes from 192.168.102.62: seq=3 ttl=63 time=0.054 ms
^C
--- 192.168.102.62 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.054/0.118/0.290 ms
```

```shell:c2
/ # ping 192.168.102.2
PING 192.168.102.2 (192.168.102.2): 56 data bytes
64 bytes from 192.168.102.2: seq=0 ttl=64 time=0.194 ms
64 bytes from 192.168.102.2: seq=1 ttl=64 time=0.096 ms
64 bytes from 192.168.102.2: seq=2 ttl=64 time=0.065 ms
64 bytes from 192.168.102.2: seq=3 ttl=64 time=0.047 ms
^C
--- 192.168.102.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.047/0.100/0.194 ms

/ # ping 192.168.101.62
PING 192.168.101.62 (192.168.101.62): 56 data bytes
64 bytes from 192.168.101.62: seq=0 ttl=63 time=0.128 ms
64 bytes from 192.168.101.62: seq=1 ttl=63 time=0.090 ms
64 bytes from 192.168.101.62: seq=2 ttl=63 time=0.093 ms
64 bytes from 192.168.101.62: seq=3 ttl=63 time=0.063 ms
^C
--- 192.168.101.62 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.063/0.093/0.128 ms
```

```shell:router
/ # ping 192.168.101.62
PING 192.168.101.62 (192.168.101.62): 56 data bytes
64 bytes from 192.168.101.62: seq=0 ttl=64 time=0.081 ms
64 bytes from 192.168.101.62: seq=1 ttl=64 time=0.049 ms
64 bytes from 192.168.101.62: seq=2 ttl=64 time=0.047 ms
64 bytes from 192.168.101.62: seq=3 ttl=64 time=0.048 ms
^C
--- 192.168.101.62 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.047/0.056/0.081 ms

/ # ping 192.168.102.62
PING 192.168.102.62 (192.168.102.62): 56 data bytes
64 bytes from 192.168.102.62: seq=0 ttl=64 time=0.078 ms
64 bytes from 192.168.102.62: seq=1 ttl=64 time=0.132 ms
64 bytes from 192.168.102.62: seq=2 ttl=64 time=0.122 ms
64 bytes from 192.168.102.62: seq=3 ttl=64 time=0.081 ms
^C
--- 192.168.102.62 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.078/0.103/0.132 ms
```

## まとめ
今回の記事では、Dockerを活用したネットワーク通信シミュレーションを実施しました。

- サブネットとゲートウェイの重要性
ネットワーク通信の構築では、サブネットとゲートウェイの設定が最重要となります。それらが正しく設定されていれば、異なるネットワーク間の通信も可能です。

- Dockerのmacvlanの活用
macvlanドライバを使用することで、ホストとコンテナ間の通信が容易になり、実際の物理ネットワークに近いシミュレーションを行うことが可能です。

- ルーター設定の基本
コンテナ間の通信にはルーティングの設定が必要です。適切なデフォルトゲートウェイを設定することで、ルーターを通じた通信が実現できます。

今回構築したネットワーク環境を活用して、NATやDNSなどを設定し、より複雑な通信シミュレーションを実施できます。引き続きネットワーク技術を実践的に学びながら、理解を深めていきましょう！