• 映射容器端口到宿主主机的实现
    • 容器访问外部实现
    • 外部访问容器实现

    映射容器端口到宿主主机的实现

    默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。

    容器访问外部实现

    容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址。这是使用 iptables 的源地址伪装操作实现的。

    查看主机的 NAT 规则。

    1. $ sudo iptables -t nat -nL
    2. ...
    3. Chain POSTROUTING (policy ACCEPT)
    4. target prot opt source destination
    5. MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16
    6. ...

    其中,上述规则将所有源地址在 172.17.0.0/16 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。

    外部访问容器实现

    容器允许外部访问,可以在 docker run 时候通过 -p-P 参数来启用。

    不管用那种办法,其实也是在本地的 iptable 的 nat 表中添加相应的规则。

    使用 -P 时:

    1. $ iptables -t nat -nL
    2. ...
    3. Chain DOCKER (2 references)
    4. target prot opt source destination
    5. DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80

    使用 -p 80:80 时:

    1. $ iptables -t nat -nL
    2. Chain DOCKER (2 references)
    3. target prot opt source destination
    4. DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80

    注意:

    • 这里的规则映射了 0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 -p IP:host_port:container_port-p IP::port 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。

    • 如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容。

    1. {
    2. "ip": "0.0.0.0"
    3. }