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