自己动手实现 Docker bridge network
条评论最近详细了解了 Docker 的网桥网络的工作原理, 便想一步一步地实现 Docker 地网桥网络.
Docker 网桥网络工作原理
Docker 的网络实现主要会用到以下功能:
- Network Namespace: 用于隔离容器和宿主机之间地网络;
- Veth 设备对: 用于连接宿主机和容器, 每个容器都会有一对 Veth 设备, 一个在容器内, 一个在宿主机内;
- 网桥: 通过网桥可以很方便地管理宿主机上的多个 veth 设备, 同时实现不同容器之间地互联;
- Iptables/NetFilter: SNAT 以实现容器内对外网的访问; 实现容器地端口映射等;
- 路由
详细原理如下图所示 (转自这篇博客):
创建 Network Namespace
通过命令 sudo ip netns add ns1
即可创建名为 ns1 的 network namespace, 我们可以通过下面地命令查看当前系统中已有的 network namespace:
[ec2-user@ip-10-24-254-11 ~]$ sudo ls -1 /var/run/netns |
Note: 我们可以通过命令 sudo ip netns del ns1
来删除之前创建地 network namespace.
创建 veth 设备对
通过下面的命令创建:
[ec2-user@ip-10-24-254-11 ~]$ sudo ip link add veth0 type veth peer name veth1 |
我们把 veth1 移动到 ns1 namespace 里: sudo ip link set veth1 netns ns1
. 现在我们在宿主机中就看不到 veth1 了:
[ec2-user@ip-10-24-254-11 ~]$ ip addr show | grep veth |
当我们切换到 ns1 就可以查看到 veth1 了:
[ec2-user@ip-10-24-254-11 ~]$ sudo ip netns exec ns1 bash |
Note: 可以通过 sudo ip del link veth0
来删除这个设备对.
创建网桥并实现 veth1 和宿主机的互联
我们在系统默认 namespace 创建网桥 br-demo
, 并将 veth0 加入到网桥中:
|
我们给网桥添加 ip 地址: sudo ifconfig br-demo 172.8.0.1
. 同时启动 veth0 sudo ip link set dev veth0 up
. 再登录进 ns1 namespace 给 veth1 设置 ip 地址:
[root@ip-10-24-254-11 ec2-user]# ifconfig veth1 172.8.0.8 |
这时我们便可以 ping 通 br-demo 的地址了:
[root@ip-10-24-254-11 ec2-user]# ping -c 1 172.8.0.1 |
给 veth1 添加外网访问
在宿主机上编辑 iptables , 添加以下规则:
sudo iptables -t filter -A FORWARD -i br-demo ! -o br-demo -j ACCEPT |
在 ns1 namespace 里测试是否可以连通外网:
[root@ip-10-24-254-11 ec2-user]# ping baidu.com -c1 |
映射 ns1 内部端口到宿主机
我们现在 ns1 内部通过 python 启动一个简单地 http server:
[root@ip-10-24-254-11 ec2-user]# python -m SimpleHTTPServer |
在宿主机上我们可以通过 veth1 的 ip 地址访问这个服务:
[ec2-user@ip-10-24-254-11 ~]$ curl -I 172.8.0.8:8000 |
从别的机器直接访问宿主机映射后的端口
把下面地规则加入到 iptalbe 里, 我们便可以通过宿主机的 8088 端口访问到这个 service 了:
[ec2-user@ip-10-24-254-11 ~]$ sudo iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8088 -j DNAT --to-destination 172.8.0.8:8000 |
注意这里必须要在别地机器上访问宿主机的 8088 端口!
直接在宿主机上访问映射后的端口
添加如下两条 iptables 规则后即可直接在本机地址上访问:
[ec2-user@ip-10-24-254-11 ~]$ sudo iptables -t nat -A OUTPUT -p tcp -m tcp --dport 8088 -j DNAT --to-destination 172.8.0.8:8000 |
References
推荐文章(由hexo文章推荐插件驱动)
- 本文链接:https://hiberabyss.github.io/2018/02/02/docker-bridge-network-practice/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!