张磊:浅谈容器网络

分享下Kubernetes社区资深成员与项目维护者「张磊」对于这个话题的思考 。
张磊:浅谈容器网络
文章图片
你好 , 我是张磊 。 今天我和你分享的主题是:浅谈容器网络 。
在前面讲解容器基础时 , 我曾经提到过一个Linux容器能看见的“网络栈” , 实际上是被隔离在它自己的NetworkNamespace当中的 。
张磊:浅谈容器网络】而所谓“网络栈” , 就包括了:网卡(NetworkInterface)、回环设备(LoopbackDevice)、路由表(RoutingTable)和iptables规则 。 对于一个进程来说 , 这些要素 , 其实就构成了它发起和响应网络请求的基本环境 。
需要指出的是 , 作为一个容器 , 它可以声明直接使用宿主机的网络栈(–net=host) , 即:不开启NetworkNamespace , 比如:
$dockerrun–d–net=host--namenginx-hostnginx
在这种情况下 , 这个容器启动后 , 直接监听的就是宿主机的80端口 。
像这样直接使用宿主机网络栈的方式 , 虽然可以为容器提供良好的网络性能 , 但也会不可避免地引入共享网络资源的问题 , 比如端口冲突 。 所以 , 在大多数情况下 , 我们都希望容器进程能使用自己NetworkNamespace里的网络栈 , 即:拥有属于自己的IP地址和端口 。
这时候 , 一个显而易见的问题就是:这个被隔离的容器进程 , 该如何跟其他NetworkNamespace里的容器进程进行交互呢?
为了理解这个问题 , 你其实可以把每一个容器看做一台主机 , 它们都有一套独立的“网络栈” 。
如果你想要实现两台主机之间的通信 , 最直接的办法 , 就是把它们用一根网线连接起来;而如果你想要实现多台主机之间的通信 , 那就需要用网线 , 把它们连接在一台交换机上 。
在Linux中 , 能够起到虚拟交换机作用的网络设备 , 是网桥(Bridge) 。 它是一个工作在数据链路层(DataLink)的设备 , 主要功能是根据MAC地址学习来将数据包转发到网桥的不同端口(Port)上 。
当然 , 至于为什么这些主机之间需要MAC地址才能进行通信 , 这就是网络分层模型的基础知识了 。 不熟悉这块内容的读者 , 可以通过这篇文章来学习一下 。
而为了实现上述目的 , Docker项目会默认在宿主机上创建一个名叫docker0的网桥 , 凡是连接在docker0网桥上的容器 , 就可以通过它来进行通信 。
可是 , 我们又该如何把这些容器“连接”到docker0网桥上呢?
这时候 , 我们就需要使用一种名叫VethPair的虚拟设备了 。
VethPair设备的特点是:它被创建出来后 , 总是以两张虚拟网卡(VethPeer)的形式成对出现的 。 并且 , 从其中一个“网卡”发出的数据包 , 可以直接出现在与它对应的另一张“网卡”上 , 哪怕这两个“网卡”在不同的NetworkNamespace里 。
这就使得VethPair常常被用作连接不同NetworkNamespace的“网线” 。
比如 , 现在我们启动了一个叫作nginx-1的容器:
$dockerrun–d--namenginx-1nginx
然后进入到这个容器中查看一下它的网络设备:
#在宿主机上$dockerexec-itnginx-1/bin/bash#在容器里root@2b3c181aecf1:/#ifconfigeth0:flags=4163mtu1500inet172.17.0.2netmask255.255.0.0broadcast0.0.0.0inet6fe80::42:acff:fe11:2prefixlen64scopeid0x20ether02:42:ac:11:00:02txqueuelen0(Ethernet)RXpackets364bytes8137175(7.7MiB)RXerrors0dropped0overruns0frame0TXpackets281bytes21161(20.6KiB)TXerrors0dropped0overruns0carrier0collisions0lo:flags=73mtu65536inet127.0.0.1netmask255.0.0.0inet6::1prefixlen128scopeid0x10looptxqueuelen1000(LocalLoopback)RXpackets0bytes0(0.0B)RXerrors0dropped0overruns0frame0TXpackets0bytes0(0.0B)TXerrors0dropped0overruns0carrier0collisions0$routeKernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIfacedefault172.17.0.10.0.0.0UG000eth0172.17.0.00.0.0.0255.255.0.0U000eth0