Kubernetes网络模型

Kubernetes旨在在一组机器集群上运行分布式系统。分布式系统的本质使网络成为Kubernetes部署的核心和必要组成部分,而且了解Kubernetes网络模型将使您可以正确运行,监视和故障排除在Kubernetes上运行的应用程序。html

网络是一个拥有许多成熟技术的广阔空间,对于不熟悉该领域的人们来讲,这可能会感到不舒服,由于大多数人都对网络已有先入为主的概念,而且有不少新旧概念均可以理解并融合在一块儿。本文包含不少技术点,可能包括网络名称空间,虚拟接口,IP转发和网络地址转换等技术。本指南旨在经过讨论每种与Kubernetes相关的技术以及如何使用这些技术的说明来揭开Kubernetes网络神秘面纱,从而理解Kubernetes网络模型。node

咱们首先讨论一些基本的Kubernetes术语,以确保在整个指南中正确使用术语,而后讨论Kubernetes的网络模型以及它所施加的设计和实现决策。随后是本指南,该指南至关长,分为几个部分。本指南中最长,最有趣的部分:深刻讨论如何使用几种不一样的用例在Kubernetes中路由流量。linux

若是您不熟悉任何网络术语,则本指南附有网络术语词汇表。git

1 Kubernetes 基础

Kubernetes是基于几个核心概念构建而成的,这些核心概念被组合在一块儿并具备愈来愈强大的功能。本节列出了这些概念中的每个,并提供了简要的概述以帮助促进讨论。Kubernetes的功能远不止此处列出的内容。应该做为入门,让读者能够在后面的部分中继续学习。若是您已经熟悉Kubernetes,请随时跳过本部分。github

1.1 Kubernetes API server

在Kubernetes中,一切都是由Kubernetes API服务器(kube-apiserver)提供服务的API调用。API服务器是etcd数据存储的网关,可维护您的应用程序集群的所需状态。要更新Kubernetes集群的状态,您能够对描述您所需状态的API服务器进行API调用。docker

1.2 Controllers

控制器是用于构建Kubernetes的核心抽象。一旦您使用API​​服务器声明了集群的所需状态,控制器就会经过持续观察API服务器的状态并对任何内容作出反应来确保集群的当前状态与所需状态匹配控制器中的更改经过一个简单的循环进行操做,该循环不断地根据集群的所需状态检查集群的当前状态。若是存在任何差别,控制器将执行使当前状态与所需状态匹配的任务。api

while true:
  X = currentState()
  Y = desiredState()

  if X == Y:
    return  # Do nothing
  else:
    do(tasks to get to Y)

例如,当您使用API​​服务器建立新的Pod时,Kubernetes调度程序(一个控制器)会注意到更改并决定将Pod放置在集群中的位置,而后使用API​​服务器将状态更改写入,而后,kubelet(控制器)注意到新的更改并设置了所需的网络功能,以使Pod在群集中可访问。在这里,两个单独的控制器对两个单独的状态更改作出反应,以使群集的实际状况匹配用户的意图。安全

1.3 Pods

Pod是Kubernetes的原子,Kubernetes是构建应用程序的最小可部署对象。单个Pod表明集群中正在运行的工做负载,并封装一个或多个Docker容器,任何须需的存储以及惟一的IP地址。被设计为位于同一机器上并位于同一位置。服务器

1.4 Nodes

节点是运行Kubernetes集群的机器,它们能够是裸机,虚拟机或其余任何东西。主机一词一般与节点互换使用。我会尝试使用术语一致性节点,但有时会使用虚拟机一词。根据上下文引用节点。网络

2 The Kubernetes 网络模型

Kubernetes对于Pod网络作出了明智的选择,尤为是Kubernetes对任何网络实现都规定了如下要求:

  • 全部Pod均可以与全部其余Pod通讯,而无需使用网络地址转换(NAT)。
  • 全部节点均可以在没有NAT的状况下与全部Pod通讯。
  • Pod看到本身的IP就是其余人看到的IP。

考虑到这些限制,咱们剩下四个不一样的网络问题要解决:

  • 容器到容器网络
  • Pod到Pod的网络
  • Pod到服务的网络
  • 互联网到服务的网络

本指南的其他部分将依次讨论这些问题及其解决方案。

3 容器到容器的网络

一般,咱们将虚拟机中的网络通讯视为直接与以太网设备进行交互,如图1所示。
eth0.png
实际上,状况比这更微妙。在Linux中,每一个正在运行的进程都在网络名称空间中进行通讯,该名称空间为逻辑网络堆栈提供了本身的路由,防火墙规则和网络设备。实质上,网络名称空间提供了全新的命名空间内全部进程的网络堆栈。

做为Linux用户,可使用ip命令建立网络名称空间。例如,如下命令将建立一个名为ns1的新网络名称空间。

$ ip netns add ns1

建立名称空间后,将在/var/run/netns下建立该名称的挂载点,即便没有附加任何进程,名称空间也能够保留。

您能够经过列出/var/run/netns下的全部挂载点,或使用ip命令来列出可用的名称空间。

$ ls /var/run/netns
ns1
$ ip netns
ns1

默认状况下,Linux将每一个进程分配给根网络名称空间,以提供对外部环境的访问,如图2所示。
root-namespace.png
就Docker架构而言,一个Pod被建模为一组共享网络名称空间的Docker容器。一个Pod中的容器都具备相同的IP地址和经过分配给Pod的网络名称空间分配的端口空间,而且能够经过localhost彼此找到。咱们能够为虚拟机上的每一个Pod建立一个网络名称空间。首先pause容器,能够理解为“Pod容器”,使网络名称空间保持打开状态,而后“应用程序容器”加入到该网络命名空间,对于Docker的话,即经过docker命令 -net = container:函数加入该命名空间。图3显示了每一个Pod如何由共享命名空间中的多个Docker容器(ctr*)组成。
pod-namespace.png
Pod中的应用程序还能够访问共享卷,共享卷定义为Pod的一部分,并能够挂载到每一个应用程序的文件系统中。

4 Pod到Pod的网络

在Kubernetes中,每一个Pod都有一个真实的IP地址,每一个Pod都使用该IP地址与其余Pod通讯。当前的任务是了解Kubernetes如何使用真实IP启用Pod到Pod的通讯,不管Pod是否部署在同一主机上,咱们经过考虑调度在同一台机器上的Pod来开始讨论,以免经过内部网络进行跨节点通讯的复杂性。

从Pod的角度来看,它存在于本身的以太网名称空间中,该名称空间须要与同一节点上的其余网络名称空间进行通讯,幸运的是,名称空间可使用Linux虚拟以太网设备或由两个虚拟接口组成的veth对链接。要链接Pod名称空间,咱们能够将veth对的一侧分配给根网络名称空间,另外一侧分配给Pod的网络名称空间,每一个veth对都像跳线同样工做,将两侧链接起来并容许流量经过它们能够在咱们的计算机上复制到尽量多的Pod。图4显示了将VM上的每一个Pod链接到根名称空间的veth对。
pod-veth-pairs.png
至此,咱们已经将Pod设置为每一个都有本身的网络名称空间,以便他们相信本身具备本身的以太网设备和IP地址,而且已将它们链接到Node的根名称空间。经过根名称空间相互通讯,为此,咱们使用了网桥。

Linux以太网网桥是一种虚拟的第2层网络设备,用于将两个或多个网段结合在一块儿,透明地工做以将两个网络链接在一块儿。网桥经过检查源和目标之间的转发表并检查要传输的数据包的目标来进行操做,桥接代码经过查看网络中每一个以太网设备惟一的MAC地址来决定是桥接数据仍是丢弃数据。

网桥实施ARP协议以发现与给定IP地址关联的链路层MAC地址。当网桥接收到数据帧时,网桥将帧广播到全部链接的设备(原始发送方除外)和具备相同IP地址的未来流量将使用查找表来发现正确的MAC地址,以将数据包转发到该地址。
pods-connected-by-bridge.png

4.1 同一节点,不一样Pod的数据包传输

有了将每一个Pod隔离到其本身的网络堆栈的网络名称空间,将每一个名称空间链接到根名称空间的虚拟以太网设备以及将名称空间链接在一块儿的网桥,咱们终于能够在同一节点上的Pod之间发送流量了。如图6所示。
pod-to-pod-same-node.gif
在图6中,Pod 1向其本身的以太网设备eth0发送一个数据包,该设备可做为Pod的默认设备使用。对于Pod 1,eth0经过虚拟以太网设备链接到根名称空间veth0(1)。数据包到达网桥后,网桥将使用ARP协议(3)解析正确的网络段以将数据包发送至— veth1。当数据包到达虚拟设备veth1时,将为br配上veth0并为其链接一个网段。它将直接转发到Pod 2的名称空间和该名称空间中的eth0设备(4)。在此通讯流中,每一个Pod仅与localhost上的eth0通讯,并将通讯路由到正确的Pod。是开发人员指望的默认行为。

Kubernetes的网络模型规定Pod必须经过其跨节点的IP地址能够访问,也就是说,Pod的IP地址对于网络中的其余Pod始终可见,而且每一个Pod都将本身的IP地址视为与其余Pod相同Pod看到了,咱们如今转向在不一样节点上的Pod之间路由流量的问题。

4.1 不一样节点,Pod到Pod的数据包传输

在肯定了如何在同一节点上的Pod之间路由数据包以后,咱们继续在不一样节点上的Pod之间路由流量。Kubernetes网络模型要求Pod IP在整个网络上都是可访问的,但并未指定必须如何实现。实际上,这是特定于网络的,可是已经创建了一些模式来简化此过程。

一般,为群集中的每一个节点分配一个CIDR块,以指定该节点上运行的Pod可用的IP地址。目的地为CIDR块的流量一旦到达该节点,则该节点负责将流量转发到正确的Pod。假设网络能够将CIDR块中的流量路由到正确的节点,则这是两个节点之间的流量。
pod-to-pod-different-nodes.gif
图7以与图6相同的请求开头,除了此次,目标Pod(以绿色突出显示)与源Pod(以蓝色突出显示)位于不一样的节点上。该数据包首先经过Pod 1的以太网设备发送它与根名称空间中的虚拟以太网设备配对(1)。最终,数据包最终到达根名称空间的网络桥接器(2)。ARP将在桥接器处失败,由于没有设备链接到具备正确名称的网桥数据包的MAC地址。若是发生故障,网桥会将数据包发送到默认路由-根名称空间的eth0设备。这时,该路由离开Node进入网络(3)。咱们如今假设网络能够路由根据分配给节点(4)的CIDR块将数据包发送到正确的节点。数据包进入目标节点的根名称空间(VM 2上的eth0),而后经过网桥将其路由到正确的虚拟以太网设备( 5)。最后,路线com经过流过Pod 4的命名空间(6)中的虚拟以太网设备对来完成。通常来讲,每一个节点都知道如何将数据包传递到其中运行的Pod。一旦数据包到达目标节点,数据包的流动方式与它们相同在同一节点上的Pod之间路由流量。

咱们方便地回避了如何配置网络以将Pod IP的流量路由到负责这些IP的正确节点的过程。这是特定于网络的,可是查看特定示例将提供一些有关问题的看法,例如,借助AWS,亚马逊为Kubernetes维护了一个容器网络插件,该容器插件可以使用容器网络接口(CNI)插件 在Amazon VPC环境中运行节点到节点网络。

容器网络接口(CNI)提供了用于将容器链接到外部网络的通用API。做为开发人员,咱们想知道Pod可使用IP地址与网络进行通讯,而且咱们但愿此操做的机制透明。由AWS开发的CNI插件试图知足这些需求,同时经过AWS提供的现有VPC,IAM和安全组功能提供安全和可管理的环境,解决方案是使用弹性网络接口。

在EC2中,每一个实例都绑定到一个弹性网络接口(ENI),而且全部ENI都在VPC内链接— ENI能够相互访问,而无需付出额外的努力。默认状况下,每一个EC2实例都部署有单个ENI,可是您能够自由建立多个ENI并将其部署到您认为合适的EC2实例。Kubernetes的AWS CNI插件经过为部署到节点的每一个Pod建立一个新的ENI来利用这种灵活性。由于VPC中的ENI已在现有内部链接在AWS基础设施上,这使得每一个Pod的IP地址均可以在VPC内本地寻址。当CNI插件部署到集群时,每一个Node(EC2实例)都会建立多个弹性网络接口并为这些实例分配IP地址,从而造成CIDR块部署Pods时,做为DaemonSet部署到Kubernetes集群的小型二进制文件会收到来自Nodes本地kubelet进程的将Pod添加到网络的任何请求。从节点的可用ENI池中得到可用的IP地址,并经过链接虚拟以太网设备和Linux内核中的网桥,将其分配给Pod,如在同一节点内将Pod联网时所描述的那样。

5 Pod到Service的网络

咱们已经展现了如何在Pod及其关联的IP地址之间路由流量,这在咱们须要处理更改以前很是有用。Pod IP地址不是持久性的,而且会随着规模的扩大或缩小,应用程序崩溃或出现而消失节点重启。这些事件中的每个均可以使Pod IP地址更改而不会发出警告。Kubernetes中内置了服务来解决此问题。

Kubernetes服务管理一组Pod的状态,使您能够跟踪随时间动态变化的Pod IP地址集。服务充当Pod的抽象,并为一组Pod IP地址分配一个虚拟IP地址寻址到服务虚拟IP的任何流量都将被路由到与虚拟IP关联的Pod集合。这容许与服务关联的Pod集合随时更改-客户端只须要知道服务的虚拟IP,不会更改。

建立新的Kubernetes服务时,将表明您建立一个新的虚拟IP(也称为集群IP)。在集群中的任何位置,寻址到该虚拟IP的流量将负载均衡到与该虚拟IP相关联的一组支持Pod。服务实际上,Kubernetes会自动建立并维护一个分布式集群内负载均衡器,该负载均衡器将流量分配给与服务相关联的健康Pod,让咱们仔细看看它是如何工做的。

5.1 netfilter 和 iptables

为了在群集内执行负载平衡,Kubernetes依赖于Linux内置的网络框架netfilter; Netfilter是Linux提供的框架,它容许以自定义处理程序的形式实现与网络相关的各类操做。数据包筛选,网络地址转换和端口转换的操做,提供了经过网络引导数据包所需的功能,并提供了禁止数据包到达计算机网络内敏感位置的功能。

iptables是一个用户空间程序,它提供了一个基于表的系统,用于定义使用netfilter框架处理和转换数据包的规则。在Kubernetes中,iptables规则由kube-proxy控制器配置,该控制器监视Kubernetes API服务器的更改。更改成服务或Pod会更新服务的虚拟IP地址或Pod的IP地址,更新iptables规则以将定向到服务的流量正确路由到后备Pod。iptables规则监视发往服务虚拟的流量IP,并从一组可用的Pod中随机选择一个Pod IP地址,而且iptables规则将数据包的目标IP地址从服务的虚拟IP更改成所选Pod的IP。换句话说,iptables已在计算机上完成了负载平衡,以将定向到服务IP的流量变为实际流量。iptables规则集已更新以反映集群状态的变化。

在返回路径上,该IP地址来自目标Pod。在这种状况下,iptables再次重写IP标头,用服务的IP替换Pod IP,以便Pod认为它一直在与服务的IP进行通讯。

5.2 IPVS

Kubernetes的最新版本(1.11)包括用于集群内负载均衡的第二个选项:IPVS。IPVS(IP虚拟服务器)也基于netfilter构建,并做为Linux内核的一部分实现传输层负载均衡。集成到LVS(Linux虚拟服务器)中,它在主机上运行,​​并充当真实服务器群集以前的负载均衡器。IPVS能够将对基于TCP和UDP的服务的请求定向到真实服务器,并进行真实服务器的服务在单个IP地址上显示为虚拟服务,这使得IPVS天然适合Kubernetes Services。

声明Kubernetes服务时,您能够指定是否要使用iptables或IPVS完成集群内负载均衡。IPVS专为负载均衡而设计,并使用更高效的数据结构(哈希表),几乎能够无限扩展建立使用IPVS均衡的服务负载时,会发生三件事:在节点上建立虚拟IPVS接口,将服务的IP地址绑定到虚拟IPVS接口,并为每一个服务IP地址建立IPVS服务器。

未来,IPVS有但愿成为集群内负载均衡的默认方法。此更改仅会影响群集内负载均衡,在本指南的其他部分中,您能够安全地用IPVS替换iptables以实现集群内负载均衡影响剩下的讨论。如今让咱们来看一看集群内负载均衡服务的数据包传输。

5.3 Pod到Service的数据包传输

pod-to-service.gif
在Pod和Service之间路由数据包时,过程以与之前相同的方式开始。数据包首先经过链接到Pod网络名称空间(1)的eth0接口离开Pod,而后经过虚拟以太网设备到达网桥(2)。网桥上运行的ARP协议不了解服务,所以它经过默认路由eth0(3)将数据包传输出去,这里发生了一些变化。在eth0接受以前,数据包是收到数据包后,iptables使用kube-proxy响应服务或Pod事件使用在节点上安装的规则,将数据包的目标从服务IP重写到特定的Pod IP(4)。如今注定要到达Pod 4而非服务的虚拟IP。iptables充分利用了Linux内核的conntrack实用程序,以记住作出的Pod选择,以便未来的流量被路由到相同的Pod(除非有任何扩展事件)。本质上,iptables直接在节点上完成了集群内负载均衡,而后使用咱们已经研究过的Pod到Pod路由将流量流到Pod。

5.4 Service到Pod的数据包传输

service-to-pod.gif
接收到该数据包的Pod会作出响应,将源IP标识为本身的IP,将目标IP标识为最初发送该数据包的Pod(1)。进入节点后,数据包流经iptables,后者使用conntrack来记住此处先前已作出选择,并将数据包的源重写为服务的IP而不是Pod的IP(2)。今后处,数据包经过网桥流到与Pod的命名空间(3)配对的虚拟以太网设备,并到达如咱们以前所见(4)。

5.5 使用DNS

Kubernetes能够选择使用DNS以免将服务的群集IP地址硬编码到您的应用程序中。Kubernetes DNS做为在群集上部署的常规Kubernetes服务运行,它配置在每一个Node上运行的kubelet,以便容器使用DNS服务的IP地址以解析DNS名称。群集中定义的每一个服务(包括DNS服务器自己)都分配有DNS名称。DNS记录根据须要将DNS名称解析为服务的群集IP或POD的IP。 SRV记录用于指定运行服务的特定命名端口。

CoreDNS与kubedns的工做原理类似,但使用的插件体系结构使其更加灵活。从Kubernetes 1.11开始,CoreDNS是Kubernetes的默认DNS实现。

6 互联网到Service网络

到目前为止,咱们已经研究了如何在Kubernetes集群中路由流量。在某些时候,您但愿将服务公开给外部流量。此需求突出了两个相关的问题:(1)将Kubernetes服务的流量发送到Internet,以及(2)将Internet的流量发送到Kubernetes服务。

6.1 Egress — 路由流量到Internet

从节点到公共Internet的流量路由是特定于网络的,而且实际上取决于将网络配置为发布流量的方式。为了使本节更具体,我将使用AWS VPC讨论任何特定的细节。

在AWS中,Kubernetes集群在VPC内运行,其中为每一个节点分配了一个私有IP地址,该IP地址可从Kubernetes集群内访问。要使从集群外的访问变得可行,请将Internet网关链接到VPC。有两个目的:在VPC路由表中为可路由到Internet的流量提供目标,并对已分配了公共IP地址的任何实例执行网络地址转换(NAT)。NAT转换负责更改节点的IP地址。集群专用的内部IP地址到公用Internet上可用的外部IP地址。

有了Internet网关后,VM能够自由地将流量路由到Internet。不幸的是,存在一个小问题:Pod拥有本身的IP地址,该IP地址与托管Pod的节点的IP地址不一样。 Internet网关上的NAT转换仅适用于VM IP地址,由于它不了解哪些Pod在哪些VM上运行-网关不支持容器。让咱们看看Kubernetes如何使用iptables解决这个问题(再次)。

6.1.1 Node到Internet的数据包传输

在下图中,数据包起源于Pod的名称空间(1),并通过链接到根名称空间(2)的veth对。一旦在根名称空间中,因为IP为IP,数据包从网桥移动到默认设备。在到达根名称空间的以太网设备(3)以前,iptables会处理数据包(3)。在这种状况下,数据包的源IP地址是Pod,若是将源保持为Pod,Internet网关将拒绝它,由于网关NAT仅了解链接到VM的IP地址。解决方案是让iptables执行源NAT(更改数据包源),以便数据包彷佛即将到来从虚拟机而不是Pod。有了正确的源IP,数据包如今能够离开虚拟机(4)到达Internet网关(5)。Internet网关将执行另外一个NAT,从VM内部重写源IP IP到外部IP。一般,数据包将到达公共Internet(6)。在回程中,数据包遵循相同的路径,而且任何源IP处理都将被撤消,以便系统的每一层都接收其可以理解的IP地址:VM-internal位于节点或VM级别,以及Pod名称空间中的Pod IP。
pod-to-internet.gif

6.2 Ingress — 路由Internet流量到Kubernetes

Ingress(将流量传入您的集群)是一个很是棘手的问题,一样,它特定于您所运行的网络,但总的来讲,Ingress分为两种解决方案,它们可在网络堆栈的不一样部分工做:(1 )Service LoadBalancer和(2)Ingress controller。

6.2.1 4层: LoadBalancer

建立Kubernetes服务时,能够选择指定一个LoadBalancer来配合使用。LoadBalancer的实现由知道如何为服务建立负载平衡器的云控制器提供。建立服务后,它将发布负载平衡器的IP地址。做为最终用户,您能够开始将流量定向到负载平衡器,以开始与服务进行通讯。

借助AWS,负载均衡器能够了解其目标组中的节点,并将平衡群集中全部节点上的流量。一旦流量到达节点,先前在整个群集中为您的服务安装的iptables规则将确保流量到达Pod您感兴趣的服务。

6.2.2 LoadBalancer到Service数据包传输

让咱们看一下它是如何工做的。一旦部署了服务,您正在使用的云提供商将为您建立一个新的负载均衡器(1)。因为负载均衡器不支持容器,所以一旦流量达到负载-balancer,它分布在组成群集的全部VM中(2)。每一个VM上的iptables规则会未来自负载均衡器的传入流量定向到正确的Pod(3)-这些是与IP规则相同的规则在服务建立过程当中(前面已经讨论过)。从Pod到客户端的响应将返回Pod的IP,可是客户端须要具备负载均衡器的IP地址.iptables和conntrack用于在返回路径上正确地重写IP,例如咱们以前看到了。

下图显示了在托管Pods的三个VM以前的网络负载平衡器,传入流量(1)定向到Service的负载平衡器。一旦负载平衡器收到数据包(2),它将随机选择一个VM。在这种状况下,咱们从病理上选择了没有运行Pod的VM:VM 2(3)。在此,在VM上运行的iptables规则将使用安装到群集中的内部负载平衡规则将数据包定向到正确的Pod。 kube-proxy.iptables执行正确的NAT,并将数据包转发到正确的Pod(4)。
internet-to-service.gif

6.2.3 7层: Ingress Controller

第7层网络Ingress在网络堆栈的HTTP/HTTPS协议范围内运行,而且构建在服务之上。启用Ingress的第一步是使用Kubernetes中的NodePort服务类型在服务上打开端口。服务的类型字段到NodePort,Kubernetes主服务器将在您指定的范围内分配一个端口,而且每一个Node都会将该端口(每一个Node上的相同端口号)代理到您的Service中,也就是说,任何定向到Node端口的流量都会服务到Pod的路由遵循了咱们已经在将流量从服务路由到Pod时使用iptables规则转发到服务时使用的内部集群负载均衡模式。

若要将Node的端口暴露给Internet,请使用Ingress对象.Ingress是将HTTP请求映射到Kubernetes Services的高级HTTP负载均衡器.Ingress方法将有所不一样,具体取决于Kubernetes云提供商控制器如何实现HTTP负载平衡器(像第4层网络负载平衡器同样)仅了解节点IP(而非Pod IP),所以流量路由一样利用kube-proxy在每一个节点上安装的iptables规则提供的内部负载均衡。

在AWS环境中,ALB入口控制器使用Amazon的第7层应用程序负载平衡器提供Kubernetes入口,下图详细说明了该控制器建立的AWS组件,还演示了入口流量从ALB到Kubernetes集群的路线。
ingress-controller-design.png
建立后,(1)Ingress Controller监视来自Kubernetes API服务器的Ingress事件,当发现知足其要求的Ingress资源时,便开始建立AWS资源.AWS使用Application Load Balancer(ALB)(2)负载均衡器与用于将请求路由到一个或多个已注册节点的目标组协同工做。(3)在AWS中为入口资源描述的每一个惟一的Kubernetes服务建立了目标组。(4)一个侦听器是ALB进程使用您配置的协议和端口检查链接请求。Ingress控制器为Ingress资源注释中详细说明的每一个端口建立侦听器。最后,为Ingress资源中指定的每一个路径建立目标组规则。这样能够确保将到特定路径的流量路由到正确的Kubernetes服务(5)。

6.2.4 Ingress到Service数据包传输

流经Ingress的数据包的传输与LoadBalancer的传输很是类似,主要区别在于Ingress知道URL的路径(容许并能够根据其路径将流量路由到服务)以及初始链接入口和节点之间的链接是经过每一个服务在节点上公开的端口实现的。

让咱们看一下它在实际中是如何工做的。一旦部署了服务,您正在使用的云提供商将为您建立一个新的Ingress负载均衡器(1)。因为负载均衡器不支持容器,所以一旦流量到达负载均衡器,它经过服务的公告端口分布在组成群集(2)的全部VM上。每一个VM上的iptables规则会未来自负载均衡器的传入流量定向到正确的Pod(3)-如咱们所见从Pod到客户端的响应将随Pod的IP返回,可是客户端须要具备负载均衡器的IP地址。iptables和conntrack用于正确地在返回路径上重写IP,如咱们以前所见。
ingress-to-service.gif第7层负载平衡器的优势之一是它们能够识别HTTP,所以能够了解URL和路径,这使您能够按URL路径对服务流量进行细分。它们一般还能够在X-Forwarded中提供原始客户端的IP地址。 -对于HTTP请求的标头。

相关文章
相关标签/搜索