继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

容器网络简介

周萝卜
关注TA
已关注
手记 53
粉丝 27
获赞 85

今天我们来简单谈一谈容器的网络知识,这其实是一个很有意思且非常重要的知识点!

在容器内,可以看见的“网络栈”其实就是隔离在该容器内 Network Namespace 当中的,其中就包括了网卡(Network Interface)、回环设备(Loopback Device)、路由表(Routing Table)和iptables 规则。这些要素,就构成了网络请求的基本环境。

host 模式

对于 docker 容器来说,可以在启动的时候声明直接使用宿主机的网络栈,即不开始 Network Namespace

docker run -d -net=host --name nginx-host nginx

像上面的这种启动方式,会直接监听宿主机的80端口,虽然这种情况下,可以为容器提供良好的网络性能,但也不可避免的引入共享网络资源的问题,比如端口冲突等。

所以在大多数情况下,我们都希望容器进程能使用自己的 Network Namespace 里的网络栈,即拥有自己的 IP 地址和端口。

Network Namespace 模式

那么在介绍这种网络模式前,我们需要首先解决一个问题,就是这个被隔离的容器进程,该怎么和其他 Network Namespace 里的容器进程进行交互呢?

为了解决这个问题,我们可以把每一个容器看做一台主机,那么现在的问题就变成了如何让两台主机进行通信,其实解决方案就是把两台主机分别连接到一台交换机上就可以了。

那么在 Linux 系统中,能够起到虚拟交换机作用的网络设备,就是网桥(Bridge)。他是一个工作在数据链路层的设备,主要功能是根据 MAC 地址学习来将数据包转发到网桥的不同端口上。

为了实现上面的目的,Docker 项目会默认在宿主机上创建一个名叫 dokcer0 的网桥,凡是连接在 docker0 网桥上的容器,都可以通过它来进行通信。

那么下面我们就来看看这个 docker0 又是如何工作的,是怎么实现网桥的作用的呢?

在这里使用到了一个虚拟设备:Veth Pair,它的特点就是被创建出来后,总是以两张虚拟网卡(Veth Peer)的形式成对出现,并且从其中一个“网卡”发出的数据包,直接可以出现在与它对应的另一张“网卡”上,即使这两个网卡在不同的 Network Namespace 当中。

下面我们来用一个例子来具体看看这个过程

我们启动一个 nginx-1 的容器

docker run -d --name nginx-1 nginx

然后我们进入到该容器,查看一下它的网络设备

# 宿主机
docker exec -it nginx-1 sh
# 容器中
#ifconfig

图片描述
可以看到,在容器里有一张 eth0 的网卡,它就是 Veth Pair 设备在容器当中的一端,而通过 route 命令可以看到,容器的路由表里,eth0 网卡是这个容器里的默认路由设备:所有对 172.17.0.0/16 网段的请求,都会被交给 eth0 来处理。

而这个 Veth Pair 设备的另一端,就在宿主机上。

# 宿主机
ifconfig

图片描述
也可以看到,在宿主机上,Veth Pair 设备是一张虚拟网卡,叫做 vetha59a54c。
那么我们如何来确定这张虚拟网卡就是对应与容器中的 eth0 呢,我们可以通过如下的两个命令来确认
图片描述

如果此时我们再在宿主机上启动一个容器,那么这两个容器默认一定是互通的,其实原理也很简单,因为在容器中发出的数据包,默认都会通过 Veth Pair 设备出现在 docker0 网桥上,因为这是一个网桥,所有“查在”其上面的设备都是互通的,所以两个容器默认网络也是互通的。

以上,就是最为基本的容器网络知识,当然,对于 K8S 项目,会存在更加复杂的网络插件,我们在后面的文章中在慢慢介绍吧!

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP