我们今天发布的翻译材料专门针对Kubernetes炉膛网络交互的功能。 它适用于已经使用Kubernetes的人。 如果您还不熟悉Kubernetes,那么在阅读本材料之前值得阅读此Kubernetes教程,因为该材料适合初学者使用。

豆荚
Kubernetes(pod)下有什么? Sub是一个实体,由一个或多个托管在同一主机上的容器组成,并配置为共享网络堆栈资源和其他资源(例如卷)。 Pod是构成在Kubernetes平台上运行的应用程序的基本构建块。 Pod共享一个网络堆栈。 实际上,这意味着组成炉床的所有容器都可以通过
localhost
相互通信。 如果炉膛中有一个运行nginx的容器,侦听端口80,另一个运行scrapyd的容器,则该容器可以访问位于
http://localhost:80
的第一个容器。 看起来并不困难。 现在让我们问问自己这是如何工作的。 让我们看一下在本地计算机上启动Docker容器时的典型情况。
在本地计算机上运行的Docker容器如果您从上到下查看此方案,结果发现存在一个物理网络接口
eth0
。
docker0
网桥已
docker0
,
docker0
虚拟网络接口已
veth0
到该网桥。 请注意,
docker0
和
veth0
位于同一网络上,在本示例中为
172.17.0.0/24
。 在该网络上,为
docker0
分配了IP地址
172.17.0.1
,此接口是
veth0
的
默认网关 ,该
网关被分配了地址
172.17.0.2
。 由于启动容器时设置网络名称空间的特殊性,容器内的进程仅看到
veth0
接口,并通过
docker0
和
eth0
接口与外界交互。 现在运行第二个容器。
在本地计算机上运行的两个Docker容器如上图所示,新的虚拟网络接口
veth1
被分配给第二个容器,该容器与第一个容器连接到同一桥
docker0
。 这是对实际发生情况的简要描述。 另外,应该注意的是,容器和网桥之间的连接是通过一对连接的虚拟以太网接口建立的,其中一个在容器名称空间中,另一个在根网络名称空间中。 可以在
这里找到有关此内容的详细信息。
所有这些都很好,但是它还没有描述我们应用于Kubernetes Pod的“共享网络堆栈”。 幸运的是,名称空间具有高度的灵活性。 Docker可以启动一个容器,而不是为其创建一个新的虚拟网络接口,而是使其与其他容器一起使用现有接口。 使用这种方法,我们将不得不更改上述方案,如下所示。
容器使用通用的网络接口现在,第二个容器与已经存在的
veth0
接口进行交互,而不是像前面的示例中那样与它自己的
veth1
接口进行交互。 使用这种方案会导致多种后果。 首先,我们现在可以说两个容器在外部都可以在同一地址
172.17.0.2
看到,并且每个容器内部都可以访问由另一个容器打开的
localhost
上的端口。 另外,这意味着这些容器不能打开相同的端口。 当然,这是一个限制,但在几个进程在同一主机上打开端口的情况下,它与类似的限制没有不同。 使用这种方法,一组进程可以获得与在容器中运行这些进程相关的所有优势,例如连通性和隔离性较差,但是同时,进程可以在最简单的现有网络环境中组织协作。
Kubernetes通过为每个炉膛创建一个专用容器来实现这种模式,其唯一目的是为其他炉膛容器提供网络接口。 如果您连接到
ssh
分配了特定子项的Kubernetes集群的节点并运行docker
docker ps
,则将看到至少有一个使用
pause
命令运行的容器。 该命令暂停当前进程,直到
SIGTERM
信号到达。 这样的容器绝对不做任何事情,它们处于“睡眠”状态,正在等待该信号。 尽管“挂起”的容器无能为力,但可以说,它们是炉床的“心脏”,为其他容器提供了虚拟网络接口,它们可用于彼此交互或与外界交互。 结果,事实证明,在类似于以下的假设环境中,我们以前的方案看起来像下面所示的方案。
假想的容器炉网
一个装满容器的容器是某个系统的基本组成部分,但到目前为止,还不是该系统本身。 Kubernetes体系结构基于以下要求:炉床应该能够与其他炉床进行交互,而不管它们在同一台计算机上还是在不同的机器上运行。 为了了解所有这些工作原理,我们需要进入更高的抽象层次,并讨论节点在Kubernetes集群中如何工作。 在这里,我们将讨论网络路由和路由的主题。 考虑到它太复杂,通常在此类材料中避免使用此主题。 找到一个易于理解且时间不长的IP路由指南并不容易,但是如果您希望对此问题进行简要概述,则可以阅读
此材料。
Kubernetes集群由一个或多个节点组成。 节点是一个物理或虚拟的主机系统,其中包含各种软件工具及其依赖项(主要是Docker)以及多个Kubernetes系统组件。 该节点已连接到网络,从而可以与群集中的其他节点交换数据。 这是一个简单的两节点群集的外观。
一个简单的两节点集群如果有问题的群集在GCP或AWS之类的云环境中运行,则此方案可以相当准确地传达单个项目的默认网络架构的实质。 为了演示,在此示例
10.100.0.0/24
使用了专用网络
10.100.0.0/24
。 结果,将地址
10.100.0.1
分配给
10.100.0.1
,并将地址
10.100.0.2
和
10.100.0.3
两个节点。 使用此体系结构,每个节点都可以使用其
eth0
网络接口相互交互。 现在让我们回想一下,在主机上运行的Under不在此专用网络上。 它以完全不同的网络连接到网桥。 这是仅存在于特定节点内的虚拟网络。 为了更清楚,让我们重画以前的方案,并在上面添加所谓的炉床。
吊舱和节点该图左侧的主机具有一个
eht0
接口,其地址为
10.100.0.2
,其默认网关为地址为
10.100.0.1
的路由器。 地址为
172.17.0.1
的
docker0
桥连接到此接口,并通过地址为
172.17.0.2
的
veth0
虚拟接口连接到该接口,在这里我们称为炉床。
veth0
接口是在挂起的容器中创建的。 通过共享的网络堆栈在所有三个容器中都可见。 由于在创建网桥时配置了本地路由规则,因此到达
eth0
且目标地址为
172.17.0.2
任何数据包都将被重定向到网桥,然后将其转发到
veth0
虚拟接口。 虽然所有这些看起来都不错。 如果已知我们正在讨论的主机的地址为
172.17.0.2
,则可以在路由器设置中添加一条规则,该规则描述该地址的下一个转换为
10.100.0.2
,之后应将来自该地址的数据包重定向到
veth0
。 太好了 现在,让我们看一下另一台主机。
右图所示的主机具有一个物理接口
eth0
,其地址为
10.100.0.3
。 它使用相同的默认网关
10.100.0.1
,并且再次将其连接到地址为
172.17.0.1
的
docker0
桥。 有种感觉,事情进展并不顺利。 实际上,该地址可能与左侧主机上使用的地址不同。 为了说明最糟糕的情况,此处的桥地址相同,例如,如果您只是安装了Docker并使其按需工作,则可能会发生这种情况。 但是,即使所讨论的网络不同,我们的示例也突出显示了一个更深层次的问题,即节点通常不知道将哪些专用地址分配给位于其他节点的网桥。 我们需要了解这一点-以便能够将数据包发送到这些网桥,并确保它们将到达所需的位置。 显然,这里我们需要某种实体,它可以确保不同节点中地址的正确配置。
Kubernetes平台为我们提供了针对此问题的两步式解决方案。 首先,该平台为每个节点中的网桥分配一个公共地址空间,然后根据网桥所在的节点在此空间中为网桥分配地址。 其次,Kubernetes将路由规则添加到位于本例中位于
10.100.0.1
的网关。 这些规则定义用于路由发往每个网桥的数据包的规则。 也就是说,它们描述了可以通过哪个物理接口
eth0
与每个网桥联系。 虚拟网络接口,网桥和路由规则的这种组合通常称为
覆盖网络 。 说到Kubernetes,我通常将此网络称为“炉床网络”,因为它是覆盖网络,它允许位于不同节点的Pod相互通信。 这是Kubernetes机制开始运作后的前一张图的样子。
炉网它立即引起注意,网桥名称从
docker0
更改为
cbr0
。 Kubernetes不使用标准的Docker桥接器。 我们
cbr
所谓的
cbr
是“自定义桥”的缩写,也就是说,我们正在谈论一些特殊的桥。 我尚未准备好完整列出在Pod中启动Docker容器与在普通计算机上运行它们之间的区别,但是我们在这里谈论的是重要的相似区别之一。 另外,您需要注意以下事实:在此示例中,分配给网桥的地址空间是
10.0.0.0/14
。 该地址来自我们部署在Google Cloud平台上的其中一个暂存群集,因此上述内容是一个炉底网络的非常真实的示例。 您的群集可能会分配一个完全不同的地址范围。 不幸的是,目前无法使用
kubectl
实用程序获取有关这些地址的信息,但是,例如,如果使用GCP,则可以运行诸如
gcloud container clusters describe <cluster>
类的命令,并查看
clusterIpv4Cidr
属性。
通常,应该指出的是,您通常不必考虑炉床网络的工作方式。 当子与另一个炉床交换数据时,通常是通过Kubernetes服务进行的。 这有点像软件定义的代理。 但是,炉床的网络地址显示在日志中。 在某些情况下,尤其是在调试过程中,可能需要在炉床网络中显式设置路由规则。 例如,默认情况下,不使用NAT处理将Kubernetes绑定到10.0.0.0/8范围内的任何地址的流量。 因此,如果您与位于具有相同地址范围的另一个专用网络上的服务进行交互,则可能需要配置路由规则,以允许您组织正确的数据包传递。
总结
今天,我们讨论了Kubernetes Pod及其网络功能。 我们希望本文能帮助您采取正确的步骤,在Kubernetes网络上实现复杂的炉床交互方案。
亲爱的读者们! 本文是Kubernetes网络系列的
第一篇。 此循环
的第二部分已被
翻译 。 我们正在考虑是否要翻译
第三部分。 我们要求您在评论中对此发表评论。
