Kubernetes是现代容器化应用不可或缺的强大、可靠的基础平台。本文将介绍Kubernetes中与网络相关的组件,正是这些组件支撑Kubernetes成为云原生应用的首选基础设施。原文: Networking in Kubernetes

网络是Kubernetes中非常值得理解的重要主题,它帮助Kubernetes集群上的应用能够相互通信,以及支持应用与外部服务的通信。

在Kubernetes集群中,每个pod都有自己唯一的IP地址,该IP地址在集群内可路由。这个IP地址通常由Kubernetes网络插件分配,该插件负责配置集群网络。网络插件是Kubernetes网络架构的关键组件,有多种选择,如Calico、Flannel和Weave Net。

除了网络插件,Kubernetes还包括许多与网络相关的组件,如负责跨多个pod平衡网络流量的kube-proxy,以及为一组pod提供稳定的IP地址和DNS名称的Service对象。

网络对集群上运行的应用程序性能和可靠性有重要影响,因此对于任何使用Kubernetes的人来说,了解网络在Kubernetes中的工作方式非常重要。

Ingress

流量-ingress控制器-ingress服务-服务pod

在Kubernetes中,Ingress是一类API对象,提供了从外部访问集群内服务的配置方式。Ingress资源通常定义一组规则,指定如何根据传入请求的主机和路径将传入流量路由到适当的服务,从而将来自集群外的HTTP和HTTPS路由给集群内的服务。

当请求进入Kubernetes集群时,首先到达Ingress控制器,该控制器负责根据Ingress资源中定义的规则管理和路由流量。Ingress控制器基于Ingress资源中定义的一组规则来确定流量应该路由到哪里。为了使Ingres有效工作,需要使用Nginx,AWS之类的Ingress控制器。

一旦Ingress控制器确定了要将流量路由到哪个服务,就会将请求转发到服务的ClusterIP(这是由Kubernetes网络插件分配给服务的内部IP地址),然后该服务基于自己的规则来确定将流量转发到哪个pod。

流量到达目标pod后,由pod内运行的应用程序处理。然后,响应通过相同的路径(通过服务和Ingress控制器)发送回原始请求发送方。

需要注意的是,Ingress资源只负责将流量路由到集群内的服务,而不处理任何身份验证或安全性。因此,通常需要与其他安全措施(如TLS终端或Web应用程序防火墙(WAF))结合使用,以提供安全可靠的服务。

DNS

DNS(Domain Name System)是服务和pod之间相互发现和通信的一种方式,是一种负责将服务名称转换或解析为IP地址的服务。Kubernetes集群中的每个pod都被分配了唯一的主机名,该主机名由pod名及其命名空间组成。默认情况下,每个主机名都可以在集群DNS命名空间中解析。

当在Kubernetes中创建服务时,会分配一个稳定的DNS名称,用于从集群内的其他pod和服务访问该服务。

DNS名称的格式通常为servicename.namspace.svc.cluster.local,其中servicename是服务名,namespace为服务所在的Kubernetes命名空间,cluster.local为集群默认的DNS域。

当pod想要与服务通信时,可以简单的通过服务的DNS名称连接。Kubernetes DNS服务将把DNS名称解析为分配给该服务的相应ClusterIP,并将流量路由到适当的pod。

除了解析服务的DNS名称外,Kubernetes还支持自定义DNS配置,允许指定解析DNS查询时应使用的其他DNS服务器或搜索域。如果需要在Kubernetes集群之外解析DNS名称,例如访问外部服务或API,就会非常有用。

总之,DNS是Kubernetes网络的关键组件,允许服务和pod相互发现和通信,并且是在Kubernetes集群上部署可靠和可扩展应用程序的基础设施的重要组成部分。

Core DNS

CoreDNS是Kubernetes中用于服务发现和DNS解析的流行的DNS服务实现,是Kubernetes的默认DNS服务,并确保pod和服务都有FQDN(Fully Qualified Domain Name)。CoreDNS是灵活、可扩展的DNS服务,可以很容易被集成到Kubernetes集群中,并且可以自定义以支持广泛用例。没有CoreDNS,集群通信将无法工作。

在Kubernetes中,CoreDNS通常作为pod部署在集群中,负责解析服务和pod的DNS查询。CoreDNS使用Kubernetes API检索有关服务和pod的信息,并自动为每个服务和pod生成DNS记录。

在Kubernetes中使用CoreDNS的好处之一是它是高度可配置的,并且可以扩展以支持自定义插件和DNS供应商。例如,可以使用CoreDNS插件来添加对自定义DNS域的支持,或者与外部DNS供应商集成。

CoreDNS的另一个好处是,它提供了比Kubernetes中以前的默认DNS服务kube-dns更好的性能和可伸缩性。CoreDNS由Go语言编写,其设计更轻量、高效,非常适合在高流量的Kubernetes环境中处理大量DNS查询。

要在Kubernetes集群中使用CoreDNS,可以通过Kubernetes manifest文件或Helm chart将其部署为pod。部署后,可以配置CoreDNS服务以满足特定需求,例如添加自定义DNS供应商、定义自定义DNS域,或与其他Kubernetes组件(如Ingress或ExternalDNS)集成。

总之,CoreDNS是强大灵活的DNS服务实现,非常适合应用在Kubernetes集群中,并为现代云原生应用的服务发现和DNS解析提供了坚实的基础。

探针(Probes)

在Kubernetes中,探针用于确定pod中运行的容器健康状况,是Kubernetes自我修复和自动扩容功能的关键部分,为集群提供了一种自动检测和从不健康的容器中恢复的方法,可用于检测容器状态。

Kubernetes提供了三种类型的探针:

存活状态探针(Liveness Probe)

此类型探针用于确定容器是否仍在运行并且运行正常。该探针定期向容器发送请求,如果容器没有响应或响应错误,探针将把容器标记为不健康并触发重启。

如果应用正在运行但无法完成任何工作,存活状态探针可以捕获死锁,重新启动容器,从而在容错的前提下提高应用的可用性。

就绪状态探针(Readiness Probe)

这种类型的探针用于确定容器是否准备好开始接收流量。就绪探针定期向容器发送请求,如果容器成功响应,则将其标记为准备好接收流量。如果容器响应失败或错误,将被标记为未准备好,并且在再次准备好之前不会接收任何流量。

启动探针(Startup Probe)

这种类型的探针用于确定容器是否处于启动过程中。启动探针定期向容器发送请求,如果容器响应成功,将被标记为准备好接收流量。如果容器响应失败或错误,启动探针将继续发送请求,直到容器准备好,或者达到可配置的超时时间。

Kubernetes的探针定义在pod规范中,通过YAML进行配置,每个探针都由一组参数定义,例如探针类型、要探测的端点、超时时间、周期以及成功和失败阈值。

总之,探针是Kubernetes的强大功能,使容器能够在发生故障或无响应的情况下收到监控并重新启动,有助于提高在Kubernetes集群上运行的应用程序的可靠性和可用性。

Netfilter

在Kubernetes中,Netfilter用于实现网络策略,以控制集群中pod之间的网络流量。网络策略是Kubernetes对象,定义了流量如何在pod之间流动的规则,并通过Netfilter规则来执行这些策略。

当Kubernetes集群应用了网络策略后,Kubernetes API服务与网络插件通信,网络插件负责在底层网络基础设施中配置网络规则,并生成Netfilter规则来执行网络策略。

网络插件生成的Netfilter规则基于网络策略中指定的选择器,用于确定哪些pod应该受到策略的影响,选择可以基于广泛的标准,例如pod标签、命名空间或IP地址。网络插件生成与指定选择器匹配的Netfilter规则,对匹配的报文执行策略中指定的动作。

例如,可以定义一个网络策略,允许流量仅在具有特定标签的pod之间流动。网络插件将生成Netfilter规则来匹配带有该标签的pod之间的数据包,然后允许这些数据包通过网络。类似的,可以定义网络策略拒绝两个特定pod之间的流量,在这种情况下,网络插件将生成Netfilter规则丢弃这些pod之间的数据包。

总之,Netfilter是Kubernetes中网络策略实现的关键组件,允许对集群中pod之间的网络流量进行细粒度控制,并提供强大机制来执行安全和访问控制策略。

IPTables

IPTables是基于linux的防火墙工具,提供配置和管理网络过滤规则的功能。在Kubernetes中,IPTables用于实现网络策略,控制pod和服务之间的流量。

在Kubernetes中创建网络策略时,kube-proxy组件创建IPTables规则强制执行该策略。当网络流量通过pod或服务所在的节点时,这些将被规则应用于网络流量。

Kubernetes基于网络策略选择器和规则生成IPTables规则,选择器确定策略应用于哪些pod,而规则定义允许或拒绝哪些流量。例如,可以创建只允许流量发送到带有特定标签的pod上的特定端口的规则。

Kubernetes生成的IPTables规则被插入到内核的IPTables链中,从而用于决定如何处理网络流量。这些链以特定顺序进行匹配,第一个匹配的规则将决定对数据包采取的操作。

Kubernetes还通过IPTables实现Kubernetes服务,为访问一组pod提供稳定的IP地址和DNS名称。当在Kubernetes中创建服务时,kube-proxy会创建一个IPTables规则,根据服务选择器将流量转发到适当的pod。

总之,IPTables是在Kubernetes中实现网络策略和服务的重要工具,允许对网络流量进行细粒度控制,并为负载均衡和服务发现提供可靠且可扩展的机制。

IPVS

IPVS(IP Virtual Server)是提供网络负载均衡功能的Linux内核模块。在Kubernetes中,IPVS被用作kube-proxy和IPTables的替代品来实现服务。

当在Kubernetes中创建服务并且服务类型设置为"LoadBalancer"时,就会通过IPVS为服务创建虚拟IP地址(VIP)。VIP用作客户端流量的目标地址,并与一组提供实际服务的pod相关联。

IPVS的工作原理是拦截进入VIP的流量,并通过负载均衡算法将其分配到可用pod。在IPVS中有几种可用的负载均衡算法,包括轮询、最小连接和加权最小连接。

IPVS还提供健康检查,以确保流量只发送到健康的pod。当pod通过健康检查失败时,IPVS将其从可用pod列表中删除,并在剩余的健康pod之间重新分配流量。

与kube-proxy和IPTables相比,IPVS有几个优点,包括更好的可伸缩性和性能,以及更灵活的负载均衡算法。IPVS可以处理大量连接,并针对高吞吐量和低延迟进行了优化,还支持更高级的负载均衡特性,例如会话持久化和连接排放(connection draining)。

然而,与kube-proxy和IPTables相比,IPVS需要额外的配置,并且可能与网络环境有兼容性问题。IPVS需要内核的支持,并不是在所有Linux发行版上都可用。

Proxy

代理是一个服务端应用,充当请求资源的客户机和提供资源的服务器之间的中介。

Kubectl Proxy

Kubectl Proxy是一个命令行工具,允许用户在本地机器和Kubernetes API服务之间创建安全隧道,通过这种方式访问Kubernetes API服务器,可以避免访问网络以及复杂的身份验证配置。Kubectl Proxy可用于各种场景,例如访问Kubernetes Dashboard或对远程集群使用Kubectl命令。

例如,假设用户想要访问运行在远程集群上的Kubernetes Dashboard,可以使用Kubectl Proxy创建安全隧道,通过本地web浏览器访问Dashboard。

Kube-Proxy

Kube-Proxy是运行在Kubernetes集群中的每个节点上的组件,负责实现Kubernetes服务。Kube-Proxy侦听对Services的更改,更新本地IPTables或IPVS规则,确保将流量正确路由到集群中适当的pod。

例如,假设在Kubernetes中创建了一个服务,映射到一组标签为“app=myapp”的pod。Kube-Proxy将创建IPTables或IPVS规则,根据服务选择器将流量引导到适当的pod。

Kubectl Proxy和Kube-Proxy有各自的优点和局限性。Kubectl Proxy设置简单,并提供对Kubernetes API服务的安全访问,但可能很慢,不适合生产环境。

Kube-Proxy是可靠、可伸缩的,但是配置比较复杂,并且不适合所有网络环境。

Envoy

除了Kube-Proxy,Kubernetes中另一个流行的代理是Envoy。Envoy是一种高性能代理,提供高级流量管理和负载均衡功能,可以作为Kube-Proxy的替代品来实现Kubernetes服务,也可以作为独立组件提供高级流量管理功能。

Envoy可以应用于许多生产环境,提供诸如高级负载均衡算法、断路、分布式跟踪等功能。

但是,与Kube-Proxy相比,Envoy需要额外的配置,并且可能与网络环境不兼容。此外,Envoy通常用于更复杂的场景,例如多集群或多云环境,对于简单用例可能过于复杂。

容器网络接口(Container Networking Interface)

容器网络接口(Container Networking Interface, CNI)是一组规范和工具,用于在容器化环境(如Kubernetes提供的环境)中配置网络。CNI的目标是为网络插件提供通用标准,以便容器运行时和编排系统可以与任何支持CNI API的网络解决方案一起工作。

CNI为容器运行时(如Docker或CRI-O)定义了一种调用网络插件来配置容器网络接口的标准方法。插件负责为容器创建和配置网络接口、配置网络命名空间和路由表。

在Kubernetes中,kubelet使用CNI来配置pod的网络接口。创建pod时,kubelet调用CNI插件来配置pod的网络。然后,CNI插件为pod创建并配置网络接口,设置必要的路由规则,并将pod的IP地址添加到对应的网络命名空间中。

CNI插件既可以内置于容器运行时,也可以作为独立的二进制文件提供。有许多可用的CNI插件,每个插件都有自己的优缺点,流行的CNI插件包括Calico、Flannel和Weave Net。

在容器化环境中使用CNI有如下好处。首先,CNI提供了可以被多个容器运行时和编排系统使用的通用标准,因此可以独立于容器运行时或编排系统进行开发,从而提高灵活性和兼容性。

其次,CNI提供了模块化和可扩展的体系架构,允许与其他网络解决方案轻松集成,使用户能够为特定用例选择最佳网络解决方案,并避免供应商锁定。

最后,CNI为配置容器网络提供了简单而灵活的API,开发人员可以轻松根据自己的需求创建和部署定制的网络解决方案。


你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。微信公众号:DeepNoMind

本文由mdnice多平台发布


俞凡
21 声望14 粉丝

你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起...