基于虚拟设备搭建Docker Container网络模式
Docker命令
# 创建一个nginx
[root@docker ~]# docker run -d -P --net=bridge --name nginx nginx
b6119c06485a68c5c5a0a17e6d74072ff02569e2d850ed2e1144e89495f8ee4d
# 由于mysql要与nginx进行关联,所以不能在物理主机上进行端口映射
[root@docker ~]# docker run -d --net=container:nginx --name mysql -e MYSQL_ROOT_PASSWORD=password mysql
ecd7f4f348bd3d9e86cabcea4b6f4b0578e5d58b883cf74558167f48dfe851d5
# 查看mysql和nginx的监听端口信息
[root@docker ~]# ip netns exec 013bdc631644 netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3218/nginx: master
tcp6 0 0 :::33060 :::* LISTEN 3554/mysqld
tcp6 0 0 :::3306 :::* LISTEN 3554/mysqld
tcp6 0 0 :::80 :::* LISTEN 3218/nginx: master
创建namespace和veth
# 创建nginx namespace用来模拟网络,mysql的其他资源由Linux其他机制隔离(所以不用创建mysql namespace),这里不做讨论
ip netns add nginx
# 创建veth
ip link add veth1 type veth peer name eth1
# 将eth1接入nginx
ip link set eth1 netns nginx
# 开启veth设备
ip link set veth1 up
ip netns exec nginx ip link set eth1 up
# 配置eth1 ip
ip netns exec nginx ip addr add 172.168.1.11/24 dev eth1
# 开启lo
ip netns exec nginx ip link set lo up
添加Bridge
# 创建网桥
ip link add br0 type bridge
# 将veth1添加到br0
ip link set veth1 master br0
# 查看bridge接口连接信息
[root@boy ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.a6431e15151d no veth1
# 为br0添加IP
ip addr add 172.168.1.1/24 dev br0
ip link set br0 up
添加路由
# 添加路由,将去172.168.0.0/24的流量全部导入br0
route add -net 172.168.1.0/24 dev br0
# 在nginx中添加路由
ip netns exec nginx ip route add default via 172.168.1.1 dev eth1
# 开启ip_forward转发
sysctl -w net.ipv4.ip_forward=1
# nginx ping 192.168.0.10
[root@boy ~]# ip netns exec nginx ping 192.168.0.10
PING 192.168.0.10 (192.168.0.10) 56(84) bytes of data.
64 bytes from 192.168.0.10: icmp_seq=1 ttl=64 time=0.021 ms
^C
--- 192.168.0.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.021/0.021/0.021/0.000 ms
# nginx ping 192.168.0.2(网关,有去无回)
[root@boy ~]# ip netns exec nginx ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
^C
--- 192.168.0.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2015ms
添加masqurade
# 添加masqurade,masqurade会把从br0出来的数据包(并且这个数据包要访问本机以外机器)的源地址换成ens33的地址,目标地址不变
iptables -t nat -A POSTROUTING -s 172.168.1.0/24 -o ens33 -j MASQUERADE
添加DNAT
由于nginx暴露端口到主机了,故而nginx那条规则需要添加,而mysql是公用nginx网络,这里不需要加DAT规则
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 172.168.1.11:80
添加forward规则
# 这里iptables默认允许filter forward链流量通过,做完上述操作后,结果如下:
[root@boy ~]# ip netns exec nginx ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=127 time=34.2 ms
^C
--- 114.114.114.114 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 34.238/34.238/34.238/0.000 ms
# 在nginx namespace下添加服务用来模拟nginx和mysql服务
ip netns exec nginx python3 -m http.server 80
ip netns exec nginx python3 -m http.server 3306
# 测试nginx是否能通
C:\Users\xx>tcping 192.168.0.10 80
Probing 192.168.0.10:80/tcp - Port is open - time=1.297ms
Control-C
Ping statistics for 192.168.0.10:80
1 probes sent.
1 successful, 0 failed. (0.00% fail)
Approximate trip times in milli-seconds:
Minimum = 1.297ms, Maximum = 1.297ms, Average = 1.297ms
# 测试mysql是否能通
C:\Users\xx>tcping 192.168.0.10 3306
Probing 192.168.0.10:3306/tcp - No response - time=2012.008ms
Probing 192.168.0.10:3306/tcp - No response - time=2001.444ms
Control-C
# 如果forward chian的默认规则为DROP需要做如下变更
iptables -t filter -P FORWARD DROP
# nginx ping 114.114.114.114(当nginx的流量在到达协议栈后,经过FOWARD过滤时,协议栈会将这些包丢弃,从而导致ping不通)
[root@boy ~]# ip netns exec nginx ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
^C
--- 114.114.114.114 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1003ms
# 添加规则
iptables -t filter -A FORWARD -i br0 -j ACCEPT #因为协议栈只连在br0,所以不写
iptables -t filter -A FORWARD -d 172.168.1.11/32 ! -i br0 -o br0 -j ACCEPT
# iptables -t filter -A FORWARD -d 172.168.1.11/32 ! -i br0 -o br0 -p tcp -m tcp --dport 80 -j ACCEPT
# 测试nginx ping 114.114.114.114
[root@boy ~]# ip netns exec nginx ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=127 time=79.7 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=127 time=36.6 ms