容器跨主机通信之NAT

来源:互联网 发布:应用数学就业前景知乎 编辑:程序博客网 时间:2024/05/22 09:42
NAT分为DNAT和SNAT,更多看:http://blog.daocloud.io/docker-bridge/


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


1,container -- > outside

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

$ sudo iptables -t nat -nL
[sudo] password for uta:
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

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain 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

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0


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


2,container  < -- outside

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

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


$ sudo docker run -t -i --name test  -P --expose 22  ubuntu:16.10 /bin/bash

-P 使用时需要指定 --expose 选项,指定需要对外提供服务的端口

使用 docker run -P 自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用的端口池中 (49000..49900) 自动选择,你可以通过 docker ps 、docker inspect <container_id> 或者 docker port <container_id> <port> 确定具体的绑定信息。


$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                   NAMES
3dafeabdd79a        ubuntu:16.10        "/bin/bash"         About a minute ago   Up About a minute   0.0.0.0:32768->22/tcp   test

可以看到,对外映射32768端口


在container内执行:
$ sockperf server --tcp -i 172.17.0.2 -p 22

在client执行:
$ sockperf throughput --tcp -i 129.107.126.89 -p 32768  -t 10



原理:
client访问host的ip,port;然后host的port映射到container的服务的port,然后返回。
0 0
原创粉丝点击