探索 Docker bridge 的正确姿势 小白亲测有效! - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
daocloud

探索 Docker bridge 的正确姿势 小白亲测有效!

  •  
  •   daocloud
    DaoCloud Mar 2, 2017 3259 views
    This topic created in 3371 days ago, the information mentioned may be changed or developed.

    上一回合,小白折腾了 Docker 架构,铁要趁热我开始学习 Docker 容器网络。此刻的心情,是激动的,也是不安的。激动是因为终于要面对 Docker 的第一座大山 :网络,不安是因为网络问题一直以来都是小白的软肋,那些年我们一起学过的网络知识,如今。。。

    硬着头皮翻开《 Docker 进阶与实战》开始 Docker 网络初探,里面讲述了 Docker 容器网络的好几种模式。其中 “ bridge “ 模式成功的吸引了我的注意。 bridge 模式俗称桥接模式,关于它的定义小白早就忘了,但不难理解的是 bridge 的作用,bridge 可以连接不同的东西

    早期的二层网络中, bridge 可以连接不同的 LAN 网,如下图所示。当主机 1 发出一个数据包时, LAN 1 的其他主机和网桥 br0 都会收到该数据包。网桥再将数据包从入口端复制到其他端口上(本例中就是另外一个端口)。因此, LAN 2 上的主机也会接收到主机 A 发出的数据包,从而实现不同 LAN 网上所有主机的通信。

    随着网络技术的发展,传统 bridge 衍生出适用不同应用场景的模式,其中最典型要属 Linux bridge 模式,它是 Linux Kernel 网络模块的一个重要组成部分,用以保障不同虚拟机之间的通信,或是虚拟机与宿主机之间的通信,如下图所示 :

    依葫芦画瓢, Docker bridge 十有八九是用来连接不同容器,或是连接容器与宿主机的。

    带着疑问,我快速浏览了这个章节,结果是大惊从早到晚失色,书中的介绍比我预想的复杂很多, Docker bridge 模式不仅使用了 veth pair技术,还使用了网络命名空间技术,更令我吃惊的是, Docker bridge 模下竟然采用了 NAT方式。 Docker bridge 和 Linux bridge 二者,初看如出一辙,再看又相去甚远,还真是傻傻分不清楚。没想到我的容器网络学习计划,刚起步便遭遇了滑铁卢。

    没有搞清楚 Docker bridge 与 Linux bridge 的区别前,这书简直没法看了。依小白的经验,云里雾里的时候摸清楚基本概念最有效,先从 Linux bridge 模式的基本工作原理入手,再从 Docker bridge 模式下的 “黑科技” ( veth pair 、网络命名空间技术、 NAT )入手 ,或许能找出点头绪。压抑住内心的愤懑,我翻开了《深入理解 LINUX 网络技术的内幕》,找寻这些关键字的足迹。

    Linux bridge 模式

    Linux bridge 模式下, Linux Kernel 会创建出一个 虚拟网桥,用以实现主机网络接口虚拟网络接口间的通信。从功能上来看, Linux bridge 像一台虚拟交换机,所有桥接设置的虚拟机分别连接到这个交换机的一个接口上,接口之间可以相互访问且互不干扰,这种连接方式对物理主机而言也是如此。

    在桥接的作用下,虚拟网桥会把主机网络接口接收到的网络流量转发给虚拟网络接口,于是后者能够接收到路由器发出的 DHCP (动态主机设定协议,用于获取局域网 IP )信息及路由更新。这样的工作流程,同样适用于不同虚拟网络接口间的通信。具体的实现方式如下所示:

    虚拟机与宿主机通信: 用户可以手动为虚拟机配置 IP 地址、子网掩码,该 IP 需要和宿主机 IP 处于同一网段,这样虚拟机才能和宿主机进行通信。

    虚拟机与外界通信: 如果虚拟机需要联网,还需为它手动配置网关,该网关也要和宿主机网关保持一致。

    除此之外,还有一种较为简单的方法,那就是虚拟机通过 DHCP 自动获取 IP ,实现与宿主机或宿主机以外的世界通信,小白亲测有效。

    Docker bridge 模式

    大致清楚 Linux bridge 模式后,再来看 Docker bridge 模式,小白也有了信心。再次翻开《 Docker 进阶与实战》,仔细阅读后小白了解到在该 bridge 模式下, Docker Daemon 会创建出一个名为 docker0 的虚拟网桥,用来连接宿主机容器,或者连接不同的容器,书中的介绍与小白之前的假设也不谋而合。

    Docker 利用 veth pair [注释 1]技术,在宿主机上创建了两个虚拟网络接口 veth0 和 veth1 ( veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会无条件地传输给另一方)。

    容器与宿主机通信 : 在桥接模式下, Docker Daemon 将 veth0 附加到 docker0 网桥上,保证宿主机的报文有能力发往 veth0 。再将 veth1 添加到 Docker 容器所属的网络命名空间[注释 2],保证宿主机的网络报文若发往 veth0 可以立即被 veth1 收到。

    容器与外界通信 : 容器如果需要联网,则需要采用 NAT [注释 2] 方式。准确的说,是 NATP (网络地址端口转换) 方式。 NATP 包含两种转换方式: SNAT 和 DNAT 。

    • 目的 NAT (Destination NAT , DNAT): 修改数据包的目的地址。

    当宿主机以外的世界需要访问容器时,数据包的流向如下图所示:

    由于容器的 IP 与端口对外都是不可见的,所以数据包的目的地址为 宿主机ip端口,为 192.168.1.10:24 。

    数据包经过路由器发给宿主机 eth0 ,再经 eth0 转发给 docker0 网桥。由于存在 DNAT 规则,会将数据包的目的地址转换为容器ip端口,为 172.17.0.n:24 。

    宿主机上的 docker0 网桥识别到容器 ip 和端口,于是将数据包发送附加到 docker0 网桥上的 veth0 接口, veth0 接口再将数据包发送给容器内部的 veth1 接口,容器接收数据包并作出响应。

    • 源 NAT (Source NAT , SNAT): 修改数据包的源地址。

    当容器需要访问宿主机以外的世界时,数据包的流向为下图所示:

    此时数据包的源地址为容器ip端口,为 172.17.0.n:24 ,容器内部的 veth1 接口将数据包发往 veth0 接口,到达 docker0 网桥。

    宿主机上的 docker0 网桥发现数据包的目的地址为外界的 IP 和端口,便会将数据包转发给 eth0 ,并从 eth0 发出去。由于存在 SNAT 规则,会将数据包的源地址转换为宿主机ip端口,为 192.168.1.10:24 。

    由于路由器可以识别到宿主机的 ip 地址,所以再将数据包转发给外界,外界接受数据包并作出响应。这时候,在外界看来,这个数据包就是从 192.168.1.10:24 上发出来的, Docker 容器对外是不可见的。

    ##小结

    小白的容器网络学习只是刚刚开了头,竟也能折腾出这么多玩儿意,有 veth pair ,有网络命名空间, 还有 NAT 。虽说 docker bridge 模式仅仅是容器网络的冰山一角,后面的学习之路仍然且行且艰辛,但小白也掌握了一些学习经验,那就是面对错综复杂的网络模式,首先需要识其筋骨胜肉,抓住本质含义。小白就是凭着对 bridge 的理解,才展开了一系列大胆的假设,带着问题最终在书中得到求证。 Disappointing, but not fatal 。

    [注释 1] veth pair 是用于不同 network namespace 间进行通信的方式, veth pair 将一个 network namespace 数据发往另一个 network namespace 的 veth 。

    [注释 2] 网络命名空间是用于隔离网络资源(/proc/net 、 IP 地址、网卡、路由等)。由于一个物理的网络设备最多存放在一个网络命名空间中,所以通过 veth pair 在不同的网络命名空间中创建通道,才能达到通信的目的。

    [注释 3] NAT 为网络地址转换( Network Address Translation )的缩写,是一种在 ip 数据包通过路由器或防火墙时重写来源 ip 地址或目的 ip 地址的技术。

    作者介绍 | Evelyn

    DaoCloud 容器技术开源团队成员,曾在 Intel DCG 部门担任 Cloud Engineering, 对分布式调度框架 Mesos 有深入学习,对集群资源管理有一定经验,目前致力于 Docker 容器技术的研究和实践。 Evelyn 所在的容器技术开源团队,在 DaoCloud 主要负责容器生态的开源工作。

    No Comments Yet
    About     Help     Advertise     Blog     API     FAQ     Solana     5558 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 62ms UTC 08:27 PVG 16:27 LAX 01:27 JFK 04:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86