Dockerのコンテナネットワーク × WSL絡みのトラブルシュートをAIにしてもらう際に、 ASCIIで絵をかきながら説明してください。 とお願いしたらわかりやすい図がでてきた*1ので、備忘的にメモに残しておく。
ネットワークは文字よりも、図(diagram)の方が直感的に認知しやすいので、こういう形で解説してもらうのは割といいかもしれない。
┌─────────────────────────────┐
│ WSL2 Host (Linux) │
│ ┌────────────┐ ┌─────────┐ │
│ │ MySQL │<──│127.0.0.1│ │ ← ここで待ち受け
│ └────────────┘ └─────────┘ │
│ ↑ eth0:10.100.0.1 │ ← ホストの仮想 NIC
│ │ │
│ ┌───────────────┐ │
│ │docker0 bridge │ 172.17.0.1│
│ └─────┬─────────┘ │
└────────│─────────────────────┘
│
│ vethペア(仮想ケーブル)
▼
┌─────────────────────────────┐
│ Container (bridge net) │
│ eth0:172.17.0.2 │
│ ┌────────────┐ │
│ │app: curl │───┐ │
│ └────────────┘ │ │
│ │127.0.0.1│ │
│ ▼ │ │
│ ┌────────────┐ │ │
│ │loopback │ │ │
│ └────────────┘ │ │
└────────────────────┘
プロンプト
以下の説明が理解できないので、ASCIIで絵をかきながら説明してください。 # input Docker の標準ブリッジは「コンテナ専用の仮想ネットワーク(例: 172.17.0.0/16)」を作り、そこからホスト 側のネットワークへは NAT 越しに出ていきます。この環境でコンテナから 127.0.0.1 を叩くと、あくまで“コ ンテナの”ループバック宛てなので、ホスト(WSL2 内の Linux)で待っている MySQL には届きません。WSL2 の 場合でも同じで、Docker デーモンが持つ veth/ブリッジを介して NAT されるだけなので、127.0.0.1:13333 は 見えないままです。 一方 --docker-network host を付けると、コンテナはホストとネットワーク名前空間を共有する形になり、ホ スト側で待っている 127.0.0.1:13333 に直接届きます。ただし MySQL から見ると接続元は実際のインターフェ イス(WSL の仮想 NIC、今回なら 10.100.0.1 など)に変わるため、そのアドレス向けに権限がないと Access denied になります。つまり「ブリッジだとループバックに届かない」「host ネットワークだと届くが接続元 IP が変わるので権限調整が必要」という構造です。
*1:技術的な正確性は裏取りしていなので注意