不使用CNI插件,打通容器网络

单节点容器网络

在不同ns中创建网卡并对接公共网桥

不使用CNI插件,打通容器网络

 1 # centos8 安装brctl命令
 2 rpm -ivh http://mirror.centos.org/centos/7/os/x86_64/Packages/bridge-utils-1.5-9.el7.x86_64.rpm
 3 
 4 # 创建ns
 5 ip netns add ns1
 6 ip netns add ns2
 7 
 8 # 创建br3
 9 brctl addbr br3
10 ip addr add 170.19.0.3/24 dev br3
11 ip link set dev br3 up
12 
13 # 创建veth00和veth01这个veth对并设置
14 ip link add veth00 type veth peer name veth01
15 brctl addif br3 veth01
16 ip link set veth00 netns ns1
17 ip netns exec ns1 ip addr add 170.19.0.1/24 dev veth00
18 ip netns exec ns1 ip link set dev veth00 up
19 ip link set dev veth01 up
20 
21 # 创建veth10和veth11这个veth对并设置
22 ip link add veth10 type veth peer name veth11
23 brctl addif br3 veth11
24 ip link set veth10 netns ns2
25 ip netns exec ns2 ip addr add 170.19.0.2/24 dev veth10
26 ip netns exec ns2 ip link set dev veth10 up
27 ip link set dev veth11 up
28 
29 # ns1中的veth00和ns2中的veth10互通
30 ip netns exec ns1 ping 170.19.0.2

不使用CNI插件,打通容器网络

 

1 # 查看ns1内自动添加的路由
2 ip netns exec ns1 route -n

不使用CNI插件,打通容器网络

 

1 # 查看虚拟机上自动添加的路由
2 route -n

不使用CNI插件,打通容器网络

解决问题1:ns内无法ping通veth自己(启动回环设备)

1 ip netns exec ns1 ip a

不使用CNI插件,打通容器网络

 

1 ip netns exec ns1 ping 170.19.0.1

不使用CNI插件,打通容器网络

 

1 # 启动回环设备
2 ip netns exec ns1 ip link set lo up
3 ip netns exec ns1 ping 170.19.0.1

不使用CNI插件,打通容器网络

 

解决问题2:ns内无法ping通宿主机网卡IP(ns内添加默认路由)

1 ip netns exec ns1 ping 10.0.4.13

不使用CNI插件,打通容器网络

 

1 # 在ns1内添加默认路由(从veth到网卡)
2 ip netns exec ns1 route add default gw 170.19.0.3 dev veth00
3 ip netns exec ns1 ping 10.0.4.13

不使用CNI插件,打通容器网络

 

解决问题3:ns内无法ping通外部虚拟机(SNAT)

不使用CNI插件,打通容器网络

 

1 # 开启转发
2 sysctl -w net.ipv4.conf.all.forwarding=1
3 # 添加SNAT规则
4 iptables -t nat -A POSTROUTING -s 170.19.0.0/24 -o eth0 -j MASQUERADE

不使用CNI插件,打通容器网络

 

1 ip netns exec ns1 ping 180.76.76.76

不使用CNI插件,打通容器网络

 

请求路径
从容器内veth00出发 -> 根据容器内路由到达docker0网桥 -> 根据宿主机路由到达宿主机的eth0网卡 -> iptables的SNAT转换 -> 到达外部主机
响应路径
响应来到宿主机的eth0网卡 -> 源地址由Linux的NAT表转换成原容器IP -> 开启FORWARD转发后,根据容器网段路由到达docker0 -> 通过veth进入容器

解决问题4:外部无法访问容器端口(DNAT)

 1 # 启动nginx容器
 2 docker pull nginx
 3 docker run -d --rm --name test nginx:latest
 4 
 5 # 进入Nginx容器,安装ping和ip以及netstat命令
 6 docker exec -it test bash
 7 apt-get update
 8 apt-get install -y inetutils-ping
 9 apt-get install -y iproute2
10 apt-get install -y net-tools
11 
12 # 查看容器IP
13 ip a s eth0

不使用CNI插件,打通容器网络

 

1 # 查看端口
2 netstat -tunlp

不使用CNI插件,打通容器网络

 

1 # 宿主机上直接访问该容器IP+80端口
2 curl 172.17.0.2:80

不使用CNI插件,打通容器网络

 

1 # 外部无法访问到该端口,因为IP ping不通
2 curl 172.17.0.2:80

不使用CNI插件,打通容器网络

 

1 ping 172.17.0.2

不使用CNI插件,打通容器网络

 

1 # 在Nginx容器所在的宿主机上,开启转发并添加DNAT规则
2 sysctl -w net.ipv4.ip_forward=1
3 iptables -t nat -A PREROUTING -p tcp -m tcp --dport 90 -j DNAT --to-destination 172.17.0.2:80
4 # 外部虚拟机可以curl通当前虚拟机的90端口,从而访问到Nginx服务
5 curl 192.168.0.103:90

不使用CNI插件,打通容器网络

 

请求路径
请求的主机向容器所在的宿主机发送请求 -> 宿主机上iptables的DNAT转换 -> 开启FORWARD转发后,根据容器网段路由到达docker0 -> 通过veth进入容器
响应路径
响应来到宿主机的eth0网卡 -> 源地址和端口由Linux的NAT表转换成宿主机网卡地址和端口 -> 通过宿主机eth0网卡把响应返回给请求的主机

上一篇:问题: ping: www.baidu.com: Name or service not known


下一篇:剑指offer_043 最近请求次数