Redian新闻
>
拿捏Docker 网络 bridge 驱动

拿捏Docker 网络 bridge 驱动

公众号新闻


dokcer0 网桥

在 Ubuntn 上安装 docker 后,宿主机上默认被创建了一个名为 docker0 的网卡,其 IP 为 172.17.0.1/16:

有了这个网卡,宿主机还会在内核的路由表中添加一条到达相应网络的静态路由记录:

这条路由信息表示所有目的 IP 为 172.17.0.0/16 的数据包都会从 docker0 网卡发出。接下来我们创建一个名为 mycon 的容器,并观察其网络配置:

在 mycon 容器内可以看到两块网卡:lo 和 eth0。其中 lo 是容器的回环网卡,eth0 是容器与外界通信的网卡,eth0 的 IP 信息为 172.17.0.2/16,和宿主机上的网卡 bridge0 在同一网段中。查看 mycon 的路由信息:

mycon 容器的默认网关正是宿主机的 docker0 网卡。通过 ping 命令测试与外网的连通性,此时容器 mycon 是可以连通外网的,这就说明 mycon 的 eth0 网卡与宿主机的 docker0 网卡是连通的。

下面我们来查看宿主机的网络设备:

发现多了一个以 "veth" 开头的网卡,这是一个 veth 设备。而 veth 设备总是成对出现的,那么与 veth7537a16 配对的就应该是 mycon 容器中的 eth0 了。既然 mycon 容器中的 eth0 是与 docker0 连通的,那么 veth7537a16 也应该是与 docker0 连通的。因此 docker0 并不是一个简单的网卡设备,而是一个网桥!下图展示了 docker bridge 网络模式的拓扑图:

事实上,docker 创建了 docker0 网桥,并以 veth pair 连接各个容器的网络,容器中的数据通过 eth0 发送到 docker0 网桥上,并由 docker0 网桥完成转发。这里网桥的概念等同于交换机,为连在其上的设备转发数据帧。网桥上的 veth 网卡设备相当于交换机上的端口,可以将多个容器连接在它们上面,这些端口工作在二层,所以是不需要配置 IP 信息的。上图中的 docker0 网桥就为连在其上的容器转发数据帧,使得同一台宿主机上的 docker 容器之间可以相互通信。既然 docker0 是二层设备,那么它为什么还需要 IP 呢?其实,docker0 是一个普通的 linux 网桥,是可以为它配置 IP 的,我们可以认为它的内部有一个可以用于配置 IP 的网卡。Docker0 的 IP 地址作为所连接的容器的默认网关地址

docker0 网桥是在 docker daemon 启动时自动创建的,其默认 IP 为 172.17.0.1/16,之后通过 bridge 驱动创建的容器都会在 docker0 的子网范围内选取一个未占用的 IP 使用,并连接到 docker0 网桥上。Docker daemon 提供了如下参数可以帮助用户自定义 docker0 的设置。

  • --bip=CIDR:设置 docker0 的 IP 地址和子网范围,使用 CIDR 格式,如 192.168.1.0/24。这个参数仅仅是配置 docker0 的,对用户自定义的网桥无效。

  • --fixed-cidr=CIDR:限制 docker 容器可以获取的 IP 地址范围。Docker 容器默认可以获取的 IP 范围为 docker 网桥的整个子网范围,此参数可以将其缩小到某个子网范围内,所以这个参数必须在 docker 网桥的子网范围内。

  • --mtu=BYTES:指定 docker0 网桥的最大传输单元(MTU)。

除了使用 docker0 网桥外,用户还可以使用自定义的网桥,然后通过 --bridge=BRIDGE 参数传递给 docker daemon。比如我们可以创建一个自定义网桥 br0:

$ sudo ip link add name br0 type bridge$ sudo ifconfig br0 188.18.0.1

然后在启动 docker daemon 时设置参数 --bridge=br0 即可。

iptables 规则

在安装 docker 时,会默认在宿主机中添加一些 iptables 规则,用于 docker 容器之间已经容器与外界的通信。我们可以通过 iptables-save 命令查看到 nat 表上 POSTROUTING 链上的有这么一条规则:

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
这条规则关系着 docker 容器与外界的通信,其含义是将不是从网卡 docker0 发出的且源地址为 172.17.0.0/16 的数据包(容器中发出的数据包)做 SNAT。这样一来,从 docker 容器中访问外网的流量,在外部看来就是从宿主机上发出的,外部感觉不到 docker 容器的存在。

当外界想要访问 docker 容器运行的服务时该怎么办呢?接下来我们将启动一个简单的 web 服务器:

$ docker run -d -p 3000:3000 --name=myweb ljfpower/nodedemo
然后观察 iptables 规则的变化:


$ sudo iptables-save*nat-A DOCKER ! -i docker0 -p tcp -m tcp --dport 3000 -j DNAT --to-destination 172.17.0.3:3000*filter-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT


可以看到,在 nat 表和 filter 表中的 DOCKER 链中分别增加来一条规则,这两条规则将访问宿主机 3000 端口的请求转发到 172.17.0.3 的 3000 端口上(提供服务的 docker 容器的 IP 和端口),所以外界访问 docker 容器是通过 iptables 做 DNAT 实现的。
Docker 默认的 forward 规则允许所有的外部 IP 访问容器,我们可以通过在 filter 的 DOCKER 链上添加规则来对外部的 IP 访问做出限制,比如只允许源 IP 为 192.168.21.212(笔者是在局域网内演示的)的数据包访问容器,添加的规则如下:

$ sudo iptables -I DOCKER -i docker0 ! -s 192.168.21.212 -j DROP
不仅仅是与外界通信,docker 容器之间相互通信也受到 iptables 规则的限制。同一台宿主机上的 docker 容器默认都连在 docker0 网桥上,它们属于同一个子网,这是满足通信的第一步。同时,docker daemon 会在 filter 表的 FORWARD 链中增加一条  ACCEPT 的规则(--icc=true):
-A FORWARD -i docker0 -o docker0 -j ACCEPT
这是满足容器间相互通信的第二步。当 docker daemon 的启动参数 -icc(icc 参数表示是否允许容器间相互通信) 设置为 false 时,上面的规则被设置为 DROP,容器间的相互通信就被禁止了,这时如果想让两个容器通信就需要在 docker run 命令中使用 --link 选项。

在 docker 容器和外界的通信过程中,还涉及了数据包在多个网卡之间的转发(比如从 docker0 网卡到宿主机 eth0 网卡),这需要内核将 ip forward 功能打开,就是把内核参数 ip_forward 设置为 1。Docker daemon 在启动的时候会执行这个操作,我们可以通过下面的命令进行检查:

$ cat /proc/sys/net/ipv4/ip_forward

返回的结果为 1,表示内核的 ip forward 功能已经打开。

容器的 DNS 和主机名(hostname)

使用同一个 docker 镜像可以创建很多个 docker 容器,但是这些容器的 hostname 并不相同,也就是说 hostname 并没有被写入到镜像中。实际上容器中的 /etc 目录下有 3 个文件是在容器启动后被虚拟文件覆盖掉的,分别是 /etc/hostname、/etc/hosts 和 /etc/resolv.conf,通过在容器中运行 mount 命令可以看到它们:

# mount/dev/mapper/ubuntu--vg-root on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)/dev/mapper/ubuntu--vg-root on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)/dev/mapper/ubuntu--vg-root on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)

这种方式既能解决主机名的问题,同时也能让 DNS 及时更新(改变 resolv.conf)。由于这些文件的维护方法会随着 docker 版本的升级而不断变化,所以尽量不要修改这些文件,而是通过 docker 提供的相关参数进行设置,其参数配置方式如下。

  • -h HOSTNAME 或者 --hostname=HOSTNAME:设置容器的 hostname,此名称会写入到 /etc/hostname 和 /etc/hosts 文件中,也可以在容器的 bash 提示符中看到。

  • --dns=IP_ADDRESS…:为容器配置 DNS,会被写入到 /etc/resolv.conf 文件中。

这两个参数都是针对容器的需要在创建容器时进行设置。比如下面的 demo:

$ docker run -it --name mycon -h lion --dns=8.8.8.8 ubuntu:14.04

总结

本文主要通过演示 docker0 网桥相关的功能来探索 docker 网络中的 bridge 驱动的实现机制。从本文中不难看出,linux 系统中,docker 的 bridge 驱动是依赖于系统的 ip forward 以及 iptables 等核心功能的。因此在学习 docker 的过程中,适当的补充 linux 相关的知识也是十分必要的!

链接:https://www.cnblogs.com/sparkdev/p/9217310.html

(版权归原作者所有,侵删)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
如何使用DOCKER部署一个GO WEB应用程序英国nike/Coach限时5折!Fresh/雅诗兰黛7折!Emma Bridgewater定制杯子8折!明明长相很相似,一个成顶流,一个却死活红不了,纤维丛不一样Docker三剑客之Docker Swarm投资性价比最高选择,自住投资两相宜--多家庭别墅推荐--Boston/Cambridge/WatertownAWS Cloudshell 现在可以访问 Docker Engine上岸笔记 | 恭喜 美本学员 斩获 BlackRock 全职 offerShanghai Study Unlocks Key to Better Pancreatic Cancer TreatmentWest 8 景观总监 Donna Bridgeman:对抗千篇一律的“相似性”|ASLA'23 专访千人进营!Docker 镜像构建—保姆级入门实战看电视连续剧《三大队》Windows 版 Arc Browser 正式发布1.0,可以取代 Edge?高级运维必备docker x86下面构建arm镜像方法【高级公寓】Cambridge Park|Cambridge|城市花园中温馨的家素食美味:香辣爽脆的干煸手撕杏鲍菇,口感滑嫩,嚼劲十足美股基本面 - 2024_01_30 * 晚报 * 担心美联储决策导致债市抛售?历史表明上涨可能性更大。美消费者信心升至202Bridgewater/Citadel开启新的里程碑! 对于留学生的好消息是…网测大更新!最强资管BlackRock开放2025 Summer Internship9.1入住|Cambridge近红线地铁站Porter 步行8分钟优质一室一厅租金2600,包热水考题大变!最强资管BlackRock开放2025 Summer Internship[评测]ASUS GeForce RTX 4080 Super 16GB GDDR6X Noctua OC Edition 评测Docker Desktop 4.29 带来增强的容器隔离性、改进的错误管理界面以及与 Moby 26 的集成推荐 巴黎云中君博士 美国巡回演讲 第二场 蔚蓝人文堂主办 亚洲2024 2 月 4 日晨 = 美东 2月 3日晚 9 PM投资回报率超高之选,本周热门地段多家庭推荐---Boston/Everett/Cambridge堪称最优秀的Docker可视化管理工具——Portainer你真的会用吗?Databricks开源大模型DBRX,以及这对Databricks公司的商业,估值,上市等方面的影响。。。被开除了,因为用了Docker。。China’s Colleges Are Locked in a Heated Debate … About Curtainsspring是“春天”,chicken是“鸡”,那spring chicken什么意思?k8s WebTerminal 开发实战(文末送Docker书籍)Windows版Arc Browser正式发布1.0,可以取代Edge?【无忧买房】Cambridge三室公寓出售,全新翻修,近哈佛和MIT,室内自然光线充足,享受私人露台docker-compose部署Prometheus+Alertmanager并配置企业微信告警How a Student’s Fake Exercise Book Broke the Chinese Internet投资性价比最高选择,自住投资两相宜--多家庭别墅推荐--Boston/Cambridge/Watertown/Waltham
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。