同一主机下两个容器间进行通信(二)2021.07

这次使用桥接方式


1.新建两个无网络容器:

docker run -itd --net=none --privileged=true --name=test1 ubu /bin/bash

docker run -itd --net=none --privileged=true --name=test2 ubu /bin/bash

其中ubu为装了网络命令的Ubuntu系统

网络设置为无网络

必须特殊root权限否则修改不了网络设置

2.查看容器的网络空间号,并在ip命令netns下建立软连接

pid1=$(docker inspect -f {{.State.Pid}} test1)

pid1=`docker inspect -f {{.State.Pid}} test1`

ln -s /proc/$pid1/ns/net /var/run/netns/test1

3.新建两对veth-pair和一个linux网桥

ip link add tap1 type veth peer name tapb1

ip link add tap2 type veth peer name tapb2

ip link add name br0 type bridge

4.连接容器和网桥

ip link set tapb1 master br0

ip link set tapb2 master br0

ip link set tap1 netns test1

ip link set tap2 netns test2

5.激活设备和分配ip地址

ip link set br0 up

ip link set tapb1  up

ip link set tapb2  up

ip netns exec test1 ip link set tap1 up

ip netns exec test2 ip link set tap2 up

ip netns exec test1 ip addr add 10.0.0.1/24 dev tap1

ip netns exec test2 ip addr add 10.0.0.2/24 dev tap2

ip addr add 10.0.0.3/24 dev br0(网桥分不分配ip地址与容器通信无关,但分配地址后主机可以直接访问容器ip,主机的路由表也会增加网桥一项)

6.使用ping命令验证容器是否相通

ip netns exec test1 ping 10.0.0.2

ip netns exec test2 ping 10.0.0.1

7.网络故障排查

这里的实际建立过程中可能会出现ping不通的情况,可以使用以下命令排查:

tcpdump -i tap1 -nne查看网络流量(-nn可以直接显示ip地址而非端口名和网络名 -e 在输出行打印出数据链路层的头部信息 -i 指定监听的网络接口)

route -v 查看路由表

iptables-save查看防火墙规则

我遇到的是容器流量可以到网桥,但是不能到另一个容器,实际上是我的主机防火墙的FORWORD规则中默认策略(policy)为DROP,而网桥又何主机共享网络名字空间,导致流量在网桥上被丢弃了

使用命令修改即可:

iptables -P FORWRAD ACCEPT

事实上,使用OVS来实现则不会出现这种问题


8.容器访问外界

由于容器1相连的网桥是使用的主机NetworkNamesapce,所以让流量直接走网桥和主机即可,要做的就是设置网络访问规则:

(1)首先使test1的流量默认从网桥出去

ip netns exec test1 ip route add default via 10.0.0.3(容器访问主机)

(2)防火墙设置FILTER表的规则(iptables -nL)

从网桥br0进而不从br0出的流量放行

iptables -A FORWARD -i br0 ! -o br0 -j ACCEPT

允许回包,响应会原路返回,主机对外接口ens3拿到响应后,会经过prerouting链,因为响应的目标地址不是主机(是test1),所以走FORWARD链转给br0,conntrack是状态跟踪

iptables -A FORWARD -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

(3)防火墙设置NAT表的规则(iptables -t nat -nL)

把所有来自10.0.0.0/24网段的请求(且出口不是br0的)请求进行转发(! -o br0可以省略)

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -o br0 -j MASQUERADE

MASQUERADE是地址伪装,算是SNAT中的一种特例,可以实现自动化的SNAT,也可以手动指定snat的地址:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --to 10.10.4.253

参考源:https://www.jianshu.com/p/bf0805821f46

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 使用veth-pair直接连接容器 1.新建两个无网络容器: docker run -itd --net=none...
    DengDD阅读 3,283评论 0 0
  • 引言 ------------------------------------------------------...
    NEOLV阅读 4,592评论 0 0
  • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
    R_X阅读 5,854评论 0 7
  • linux虚拟网络 neutron的使命 ‘实现服务和相关库以提供按需、可伸缩和技术无关的网络抽象’ tap 操作...
    why_not_阅读 6,298评论 0 0
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 128,158评论 2 7

友情链接更多精彩内容