注意事项 佩雷夫 :本文延续了Kubernetes网络基本设备上的系列材料,这些材料以易于访问的形式进行了描述,并带有说明性插图(但是,在此部分中实际上还没有插图)。 翻译了本系列的前两个部分,我们将它们合并为一个出版物 ,该出版物讨论了K8s网络模型(节点内和节点间的交互)和覆盖网络。 她的初步阅读是可取的(作者本人推荐)。 继续致力于Kubernetes服务以及传出和传入流量的处理。
注意 :为方便作者,在作者的文本中附加了链接(主要是K8的官方文档)。
集群动态
由于Kubernetes和整个分布式系统的不断变化的动态特性,pod(以及其IP地址)也不断变化。 造成这种情况的原因不尽相同,从为达到所需状态和导致扩展的事件而进行的传入更新到Pod或节点的意外崩溃。 因此,pod的IP地址不能直接用于通信。
Kubernetes中的
服务开始发挥作用-一个虚拟IP,它具有一组pod IP地址,这些IP地址用作端点并通过
标签选择器进行
标识 。 此类服务充当虚拟负载平衡器,其IP地址保持不变,与此同时,它提供的Pod的IP地址可以不断变化。
Kubernetes中Service对象中的标签选择器iptables规则(此虚拟IP的整个实现的背后)(最新版本的Kubernetes也具有使用IPVS
的能力 ,但这是另一个讨论的主题),它由Kubernetes组件
kube-proxy控制 。 但是,这样的名称在当今的现实中具有误导性。 在发布Kubernetes v1.0之前的几天里,Kube-proxy确实被用作代理,但是由于内核空间和用户空间之间不断的复制操作,导致大量资源消耗和刹车。 现在它只是一个控制器-像Kubernetes中的许多其他控制器一样。 它监视API服务器是否有端点更改,并相应地更新iptables规则。
根据这些iptables规则,如果数据包用于服务的IP地址,则为其执行目标网络地址转换(DNAT):这意味着其IP地址将从服务的IP更改为端点之一,即 iptables随机选择的Pod的IP地址之一。 这确保了负载在吊舱之间平均分配。
iptables中的DNAT对于这种DNAT,必要的信息存储在
conntrack中-Linux中的连接计费表(它存储iptables进行的五对转换:
protocol
,
srcIP
,
srcPort
,
dstIP
,
dstPort
)。 一切都安排成当返回响应时,可能发生反向DNAT操作(非DNAT),即 将IP源从Pod IP替换为Service IP。 有了这个客户,绝对不需要知道如何在后台处理软件包。
conntrack表中的五对(5元组)条目因此,使用Kubernetes服务,我们可以在没有任何冲突的情况下使用相同的端口(因为可以将端口重新分配给端点)。 这使服务发现非常容易。 您需要做的就是使用内部DNS并对服务主机进行硬编码。 您甚至可以将Kubernetes预先配置的变量与主机和服务端口一起使用。
提示 :通过选择第二条路径,可以节省很多不必要的DNS调用!
传出流量
上述Kubernetes服务在集群内运行。 实际上,应用程序通常需要访问某些外部API /站点。
通常,主机可以同时具有私有和公共IP地址。 为了访问Internet,为这些私有和公共IP地址提供了一对一的NAT-对于云环境尤其如此。
对于主机与外部IP地址的正常交互,源IP从专用主机IP更改为公用IP,用于传出数据包和传入数据包-方向相反。 但是,在通过Pod发起到外部IP的连接的情况下,源IP地址是Pod IP,云提供商的NAT机制不知道该IP。 因此,它将简单地丢弃源IP地址与主机IP地址不同的数据包。
您猜到了,在这里,我们将需要更多iptables! 这次,同样由kube-proxy添加的规则由SNAT(源网络地址转换)(也称为
IP MASQUERADE (伪装))执行。 而不是告诉源IP地址,而是告诉内核使用数据包来自的IP接口。 条目会出现在conntrack中,以进一步对响应执行反向操作(un-SNAT)。
传入流量
到目前为止,一切都很好。 Pod可以彼此通信,也可以与Internet通信。 但是,我们仍然缺乏主要功能-服务用户流量。 当前有两种方法可以实现它:
1. NodePort /云负载均衡器(L4级别:IP和端口)
将
NodePort
设置为服务类型将在
NodePort
范围内分配
NodePort
服务。 即使节点上没有任何Pod运行,此
nodePort
在每个节点上打开。 再次使用iptables,将此
NodePort
上的传入流量发送到其中一个pod(甚至可能出现在另一个节点上!)。
云环境中的
LoadBalancer
服务类型在所有节点的前面创建一个云负载均衡器(例如ELB),并与同一个
NodePort
进一步
NodePort
。
2.入口(L7级别:HTTP / TCP)
许多其他实现也使用相应的后端执行HTTP主机/路径映射-例如,nginx,traefik,HAProxy等。 有了它们,LoadBalancer和NodePort再次成为流量的入口点,但是这里的优点是我们只需要一个Ingress即可为所有服务的传入流量服务,而无需使用许多NodePort / LoadBalancers。
网络政策
可以将
网络策略视为Pod的安全组/ ACL。
NetworkPolicy
规则允许/拒绝Pod之间的流量。 它们的确切实现取决于网络层/ CNI,但大多数仅使用iptables。
...
仅此而已。
在前几期中,我们学习了Kubernetes中的网络基础知识以及叠加层如何工作。 现在我们知道了服务抽象如何在动态集群中提供帮助,并使服务的发现变得非常简单。 我们还研究了出站/入站流量如何流动以及哪些网络策略可用于保护群集。
译者的PS
另请参阅我们的博客: