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

veth pair patch port方式


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.创建 ovs 网桥

ovs-vsctl add-br br0

4.新建两对veth-pair,并连接网桥和容器

ip link add tap1 type veth peer name tapb1

ip link add tap2 type veth peer name tapb2

ovs-vsctl add-port br0 tapb1

ovs-vsctl add-port br0 tapb2

ip link set tap1 netns test1

ip link set tap2 netns test2

5.激活设备

ip netns exec test1 ip link set dev tap1 up

ip netns exec test2 ip link set dev tap2 up

ip link set dev tapb1 up

ip link set dev tapb2 up

ip link set br0 up

6.设置IP

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(非必要)




internal port


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.创建 ovs 网桥

ovs-vsctl add-br br0

4.创建 ovs internal 端口

ovs-vsctl add-port br0 tap1 -- set Interface tap1 type=internal

ovs-vsctl add-port br0 tap2 -- set Interface tap2 type=internal

5.将端口放入容器中

ip link set tap1 netns test1

ip link set tap2 netns test2

6.启用设备

ip netns exec test1 ip link set dev tap1 up

ip netns exec test2 ip link set dev tap2 up

ip link set br0 up

7.分配ip

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(非必要,设置后主机可访问容器)



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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容