通常の使い方ではMTUを設定する必要はありません。ただ、仮想マシンの中でDockerを動かさなければならないとか、そういう時にMTUを変更しないといけない場合があります。
例えばこれはOpenStackインスタンスの中でpingを実行しているところです。コンピュートエンジンとしてはLinux KVM、ネットワークはOVNを使っています。Linuxは特に設定を変更しない限りMTU 1500がデフォルトです。
$ ping -M do -s 1500 -c 4 google.com PING google.com (142.251.222.46) 1500(1528) bytes of data. ping: local error: Message too long, mtu=1442 ping: local error: Message too long, mtu=1442 ping: local error: Message too long, mtu=1442 ping: local error: Message too long, mtu=1442 --- google.com ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3071ms $ ping -M do -s 1412 -c 3 google.com PING google.com (142.251.42.142) 1412(1440) bytes of data. 1420 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=1 ttl=112 time=5.96 ms 1420 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=2 ttl=112 time=4.15 ms 1420 bytes from nrt12s45-in-f14.1e100.net (142.251.42.142): icmp_seq=3 ttl=112 time=2.59 ms --- google.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 2.589/4.233/5.960/1.377 ms
MTUが適切ではないと何が起きるか
例えば上記のような特殊な環境でコンテナーや仮想マシン内で外部との通信が通らなくなります。具体的にいうとpipツールなどでモジュールをインストール、更新するときに接続できなかったり、apt, yum, dnfなどが通らなかったりします。
DockerのデフォルトのインターフェイスのMTUを変更する
Dockerは何も指定しない限り、デフォルトで生成されるdocker0のインターフェイスから外のネットワークを通信します。 このdocker0のMTUを変える方法は次のような方法です。
$ sudo mkdir -p /etc/docker
$ sudo vi /etc/docker/daemon.json
{
"mtu": 1412
}
$ sudo systemctl restart docker
$ ip a s docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1412 qdisc noqueue state DOWN group default
link/ether 02:42:ac:01:f1:44 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
MTUが変わりました。
ただ、これでは docker network createで作ったネットワークのMTUは1500のままです。
Docker Networkで作成したインターフェイスのMTUを変更する
すでに作ったネットワークの変更をするのはできないようです。 新しくMTUを指定したDocker Networkを作って、それを使ってコンテナを起動し直しましょう。
ネットワークは次のように作成します(指定するMTUの最適値はpingで確認しましょう)。
docker network create com.docker.network.driver.mtu=1412 yugaplus-network2
作ったインターフェイスを確認してみると、brとついたインターフェイスが生成されます。docker network createでドライバーを指定しないと生成されるのはブリッジです。ただこのブリッジは仮想マシンでよく使われるLinuxブリッジとは異なり、外部からコンテナーに直接アクセスできるようなインターフェイスではありません。
67: br-20e6136cf94d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1412 qdisc noqueue state UP group default
link/ether 02:42:d0:e1:d0:07 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global br-20e6136cf94d
valid_lft forever preferred_lft forever
inet6 fe80::42:d0ff:fee1:d007/64 scope link
valid_lft forever preferred_lft forever
あとは例えばdocker-compose.ymlでこのネットワークを使ってコンテナを実行するようにすれば良いというわけです。
例えばこのような感じですね。
services: yugabyte1: image: software.yugabyte.com/yugabytedb/yugabyte:2.25.0.0-b489 restart: unless-stopped command: bin/yugabyted start --background=false ports: - "15433:15433" - "5433:5433" volumes: - yugabyte1-vol:/home/yugabyte/yb_data networks: - yugaplus-network2 volumes: yugabyte1-vol: networks: yugaplus-network2: external: true
あとは次のコマンドで起動し直すだけです。
docker compose down docker compose up -d
コンテナ作成後に作ったインターフェイスを確認してみると...br-から始まるのがDocker Networkで作ったブリッジ、vethから始まるのが各コンテナーのインターフェイスです。それぞれMTU 1412が割り当てられています。
67: br-20e6136cf94d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1412 qdisc noqueue state UP group default
link/ether 02:42:d0:e1:d0:07 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global br-20e6136cf94d
valid_lft forever preferred_lft forever
inet6 fe80::42:d0ff:fee1:d007/64 scope link
valid_lft forever preferred_lft forever
213: veth78d9ada@if212: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1412 qdisc noqueue master br-20e6136cf94d state UP group default
link/ether ca:84:dc:bb:fe:94 brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::c884:dcff:febb:fe94/64 scope link
valid_lft forever preferred_lft forever