前言

在服务器地址为:

172.24.9.117

执行 docker ps -a 得到如下信息:

服务容器端口宿主机端口外部访问端口
MySQL33063130631306
MongoDB270173101731017

于是就产生一个问题:

访问 MySQL:
172.24.9.117:31306
这是 MySQL 容器的 IP 吗?

答案:

❌ 不是
✅ 这是服务器(宿主机)的 IP + 映射端口


一、172.24.9.117:31306 到底是什么?

当你访问:

172.24.9.117:31306

本质流程是:

外部客户端
      ↓
宿主机 172.24.9.117:31306
      ↓(Docker NAT 转发)
容器在 Docker 网络的 3306端口

也就是说:

  • 172.24.9.117 是服务器 IP
  • 31306 是宿主机端口
  • 3306 是容器端口(容器应用监听的端口)
  • Docker 在宿主机上将端口 31306 的流量通过 NAT 转发到容器在 Docker 网络的 3306端口

这叫:

端口映射(Port Mapping)

配置通常类似:

ports:
  - "31306:3306"

格式是:

宿主机端口:容器端口

二、容器在 Docker 网络的 IP

每个容器会被 Docker 分配一个虚拟 IP,用于容器间通信,例如:

172.18.0.2

可以用命令查看:

docker inspect mysql
"Networks": {
    "heyun_net": {
        "IPAddress": "172.18.0.2"
    }
}

⚠ 注意:

  • 这个 IP 只在 Docker 网络内可见
  • 外部机器无法直接访问
  • NAT 转发规则会把外部访问引到这个 IP

三、容器 IP 是自动分配的吗?

是的。Docker 创建网络时会生成一个子网,例如:

172.18.0.0/16

容器加入网络时自动分配 IP:

  • mysql → 172.18.0.2
  • redis → 172.18.0.3
  • app → 172.18.0.4

完全自动完成,无需手动干预。


四、容器 IP 会变吗?

会。如果容器:

  • 被删除
  • 被重建
  • 网络被重建

IP 很可能变化:

172.18.0.2 → 172.18.0.5

所以:

❌ 不应该在代码里写死容器 IP


五、容器间通信

容器之间通常不写 IP,而是用:

mysql:3306

Docker 内置 DNS 会解析:

mysql → 172.18.0.2

然后发起 TCP 连接。类似访问公网网站:

google.com → 142.xxx.xxx.xxx

前提条件:容器必须在同一个 Docker 网络,Docker 内置 DNS 只解析同一网络下的服务名。如果容器 A 在 network-a,容器 B 在 network-b,默认无法通过服务名互访


六、容器可以有多个 IP

前提:容器加入多个网络,例如:

docker network connect net-a mysql
docker network connect net-b mysql

此时 mysql 有:

  • net-a 的 IP
  • net-b 的 IP

相当于一台服务器插了两张网卡,可以看到多个网络接口。

docker inspect mysql

在 Docker 中,容器的应用端口是固定的,例如 MySQL 的 3306,但容器可以加入多个网络,每个网络分配不同的 IP,因此同一个端口在不同网络中可以同时存在而不冲突。

对于外部访问,用户无需关心容器的网络或 IP,只需使用宿主机的 IP 和映射端口即可。 Docker 会通过 NAT 自动将流量转发到容器对应网络的端口,因此无论容器 IP 如何变化,只要宿主机端口不变,访问就稳定可靠。


七、Docker 可以有多个虚拟网络

docker network create backend-net
docker network create db-net

不同网络默认隔离:

  • app 在 backend-net
  • mysql 在 db-net

它们默认无法通信。除非:

  • 放到同一个网络
  • 或让一个容器同时加入两个网络

八、外部访问与开发环境

外部机器访问容器服务总是通过:

宿主机 IP + 映射端口

例如:

MYSQL_DB_HOST=172.24.9.117
MYSQL_DB_PORT=31306
  • 与容器在 Docker 网络的 IP 无关
  • 即使容器 IP 改变,也不会影响
  • Docker NAT 规则保证端口映射稳定

九、总结

  1. 172.24.9.117:31306 不是容器 IP

    • 是宿主机 IP + 映射端口
  2. 容器在 Docker 网络有自己的 IP

    • 只在 Docker 网络内部可见
  3. 容器 IP 是自动分配的,可能会变

    • 不要写死在代码里
  4. 容器可以加入多个网络,拥有多个 IP

    • 外部访问仍通过宿主机端口
  5. 端口映射规则不会变

    • 保证外部访问稳定
  6. 开发者应该使用服务名访问容器

    • 外部访问:宿主机 IP + 映射端口
    • 容器间访问:容器名 + 容器端口

更多推荐