端口映射的常用用法
绑定服务器的所有网卡:
docker run -itd -p 80:80 --name nginx nginx
使用udp协议作为随机端口映射:
docker run -itd -p 80:80/udp --name nginx nginx
暴露容器的多端口:
docker run -itd -p 80:80 -p 8080:8080 --name nginx nginx
自动随机端口映射:
docker run -itd -p 80 --name nginx nginx
端口映射原理
-
我们在启动docker的时候会多出一块docker0网卡:
这是一个 Linux 网桥(虚拟交换机),默认地址为 172.17.0.1/16。它的作用是:
- 作为 Docker 默认网络(bridge 模式)的网关,为容器分配 172.17.0.0/16 段的 IP(如 172.17.0.2)。
- 在宿主机和容器之间中转网络流量。
- 当容器访问外部网络时,通过 iptables 规则进行源地址转换(SNAT),使外部看到的是宿主机的 IP。
- 默认情况下,所有连接到 docker0 的容器处于同一局域网,可以互相通信。
ip -br a lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 10.0.0.123/24 fe80::216:3eff:fe2f:b63e/64 docker0 UP 172.17.0.1/16 fe80::42:15ff:fe6f:4e56/64 -
在我们启动容器时又会多出一块网卡(vethX):
这是一个 虚拟以太网设备对(veth pair) 的一端,另一端在容器内部(如 eth0@if4)。它的作用是:
- 连接容器与网桥:veth 设备对像一根虚拟网线,一端挂在 docker0 网桥上,另一端作为容器的 eth0 网卡。
- 跨命名空间通信:容器运行在独立的网络命名空间,veth 突破了命名空间隔离,使得容器内的流量能通过 docker0 转发。
- 动态创建:每启动一个容器,Docker 会创建一对 veth,删除容器时自动清理。
ip -br a lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 10.0.0.123/24 fe80::216:3eff:fe2f:b63e/64 docker0 UP 172.17.0.1/16 fe80::42:15ff:fe6f:4e56/64 veth0dce5f5@if4 UP fe80::c9:e6ff:fe8b:f8c7/64 -
在启动容器时指定了端口映射会自动生成相应的iptables规则
docker run -d -p 80:80 --name nginx nginxiptables -nL -t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL #(所有目标地址为宿主机本地 IP(非转发流量)的流量,跳转到自定义的 DOCKER 链处理。) Chain INPUT (policy ACCEPT) target prot opt source destinationChain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL # (宿主机自身发出的、目标为非环回地址的本地 IP 的流量,跳转到 DOCKER 链。) Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80 # (规则 1:对来自 172.17.0.0/16(Docker 默认网段)的出向流量进行源地址伪装(SNAT)。效果:容器访问外网时,源 IP 被替换为宿主机 IP,外网回包能正确返回。) # (规则 2:针对容器 172.17.0.2:80 的特殊 MASQUERADE 规则(通常由端口映射或特定网络配置生成)。) Chain DOCKER (2 references) target prot opt source destination RETURN all -- 0.0.0.0/0 0.0.0.0/0 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 # (规则 1(RETURN):默认放行所有流量,不匹配时返回上级链继续处理。) # (规则 2(DNAT):将访问宿主机任意 IP 的 80 端口的流量,转发到容器 172.17.0.2:80。)

docker端口映射详解