Kubernetes 网络入门

原文作者:Brina Ehlert of F5

原文链接:Kubernetes 网络入门- NGINX

转载来源:NGINX 官方网站



NodePort、LoadBalancer、Ingress controller(Ingress 控制器) ……,Kubernetes 组件简直令人眼花缭乱。

当我们与客户和社区讨论生产级 Kubernetes 部署时,他们经常会问的一个问题是:我需要 Ingress controller 吗?这个问题不能简单地用“是”或“否”来回答,我们要先了解将流量路由到 pod 的几种不同方式。本文介绍了 Kubernetes 网络的基础知识,可帮助您就是否以及何时需要 Ingress controller 做出明智的决策。

Kubernetes 提供了多种方法和层级用于将外部流量路由到 pod —— 但它们各有不同。默认的模型是 kube-proxy,不过它既不是代理,也不是为实施流量负载均衡、控制 API 或监控 service 行为而设计。

幸运的是,我们还可以使用其他方法来管理外部流量。但在展开讨论之前,我们先来快速回顾一下 Kubernetes 组件:

  • Kubernetes 部署由节点(node)组成,这些节点或为物理机或为虚拟机。
  • 节点相互连接构成一个集群(cluster)
  • 每个集群都会管理pod。从 Kubernetes 网络和基础架构级别来看,pod 是可部署的最小计算单元。一个或多个 pod 可构成一个 service。
  • 每个 pod 内部都有一个或多个容器(取决于应用的大小)。

Kubernetes 负责监测构成 service 的 pod,并根据需要对其进行扩展以满足应用的需求。但是如何将流量路由到 pod 呢?这就要用到两种类型的 Kubernetes 对象:service 和 Ingress controller。

什么是 Kubernetes Service?

根据Kubernetes 文档,一个 service 是“用于暴露运行应用的一组 pod的一种抽象方式”。service 连接着一个集群或一个容器网络中的所有 pod,这使得 pod 在任意节点都不会有影响。也就是说即使它们的位置发生变化,甚至被销毁或重启,外部流量也可以被路由到特定的 pod。可以说 service 就像一个具有最基本功能的反向代理。

Kubernetes 中有多种类型的 service,而service 对象的类型与将外部流量路由到 Kubernetes 相关。不同类型的 service 对象经常被混淆,但实际上它们的功能大不相同,因此我们有必要回顾一下它们的功能、用途和缺点。

ClusterIP

ClusterIP 是默认的 service,它在 Kubernetes 内提供了集群内其他 service 可以访问的 service。ClusterIP 不支持从集群外部访问。暴露 ClusterIP service 的唯一方法是使用 kube-proxy 之类的模型,但有必要这样做的场景不多。少数几个这样的情况包括访问笔记本电脑上的 service、调试 service 或查看一些监控和指标。

NodePort

NodePort service 会在集群中的每个节点上打开一个特定端口,并将发送到该端口节点的任何流量转发到相应的应用。这是将流量路由到应用的一个非常基本的方法,但在实际的流量管理用例中,这种方法存在许多局限性。比如每个 NodePort 只能对应一个 service,并且只能使用 30000 到 32767 范围的端口。2768 个端口虽然听起来很多,但大规模运行 Kubernetes 的企业很快就能用完。此外,NodePort 使用四层路由规则和 Linux iptables 实用程序,七层应用路由受限。

除了路由限制之外,使用 NodePort 还有三大缺点:

  • 下游客户端必须知道节点的 IP 地址才能与其连接 —— 如果节点的 IP 地址或虚拟机主机发生变化,则无法建立连接。
  • NodePort 无法将流量转发到多个 IP 地址。
  • 如下图所示,NodePort 没有在 Kubernetes 集群中提供负载均衡,因此流量会被随机分发给各个 service。这可能会导致 service 过载和端口耗尽。

Exposing Services with NodePort 使用 NodePort 暴露 service
Client
Request to pine.color.com on port 30001
客户端
 pine.color.com 的 30001 端口发送请求
DNS:port DNS:端口
1 The client is programmed with the service IP address and the DNS name and port. 1 客户端使用右侧图中 service 的 IP 地址以及 DNS 名称和端口进行编程。
2 DNS can round robin load balance traffic to nodes. 2 对去向节点的流量,DNS 能够以轮询的方式实施负载均衡。
3 Load balancing within Kubemetes is not possible so traffic is distributed randomly, causing service overload and port exhaustion. 3在 Kubernetes 内部是无法进行负载均衡的,因此流量会被随机分发,而这可能会导致 service 过载和端口耗尽。
Kubernetes cluster Kubernetes 集群
Node 1 节点 1
NodePort Service
Pine port: 30001
Lagoon port: 30002
Deep Lake port: 30003
NodePort Service
Pine 端口:30001
Lagoon 端口:30002
Deep Lake 端口:30003
Service: Pine
Service: Lagoon
Service: Deep Lake
Service:Pine
Service:Lagoon
Service:Deep Lake
Node 2 节点 2
Node 3 节点 3

LoadBalancer

LoadBalancer service 能够接受外部流量,但需要使用外部负载均衡器作为该流量的接口。在外部负载均衡器经过正确调试和重新配置,可映射到正在运行的 pod的前提下,LoadBalancer service 支持七层路由(即路由流量到 pod 的 IP 地址)。LoadBalancer 是最受欢迎的对外暴露 service 的方式之一。它在云平台中的使用最为广泛,对于小型静态部署环境来说是不错的选择。

如果您使用的是托管 Kubernetes service,那么您会自动获得云提供商选择的负载均衡器。您暴露的每个 service 都有自己的公共 IP 地址来转发所有流量,但这些流量并没有经过任何过滤或路由,这意味着您可以发送几乎任何类型的流量(HTTP、TCP/UDP、WebSocket 等)。

如果您不想使用云提供商的工具(例如,如果您需要功能更强大或独立于平台的工具),那么您可以换成类似于 F5 BIG-IP(作为外部负载均衡器)和 F5 Container Ingress Services(作为执行 LoadBalancer 功能的 operator)这样的工具。有关此模式的进一步讨论,请参阅我们的博文《在同一架构中部署 BIG-IP 和 NGINX Ingress Controller》 

在动态多变的环境中,应用的 pod 需要通过扩展来满足不断变化的需求。在这种情况下使用 LoadBalancer 暴露应用就变得有挑战性了。由于每个 service 都有自己的 IP 地址,一个热门应用可能需要管理数百甚至数千个 IP 地址。在大多数情况下,外部负载均衡器可通过 NodePort 连接到 service(如下图所示)——虽然这可以保证流量均匀地分发到各个节点上,但仍然无法对 service 进行负载均衡,因此仍然会出现 service 过载和端口耗尽的问题。

Exposing Services with a Load Balancer and NodePort 使用负载均衡器和 NodePort 暴露 service
Client
Request to pine.color.com on port 80
客户端
 pine.color.com 的 80 端口发送请求
Load Balancer port 80 负载均衡器 80 端口
1 The client is programmed with the service IP address and the load balancer port. 1 客户端使用右侧图中 service 的 IP 地址和负载均衡器端口进行编程。
2 The load balancer guarantees traffic distributes across nodes. 2 负载均衡器保证流量分发到各个节点。
3 Load balancing within Kubemetes is not possible so traffic is distributed randomly, causing service overload and port exhaustion. 3 在 Kubernetes 内部进行负载均衡是无法实现的,因此流量会被随机分发,导致 service 过载和端口耗尽。
Kubernetes cluster Kubernetes 集群
Node 1 节点 1
NodePort Service
Pine port: 30001
Lagoon port: 30002
Deep Lake port: 30003
Service: Pine
Service: Lagoon
Service: Deep Lake
NodePort Service
Pine 端口:30001
Lagoon 端口:30002
Deep Lake 端口:30003
Service:Pine
Service:Lagoon
Service:Deep Lake
Node 2 节点 2
Node 3 节点 3

什么是 Kubernetes Ingress Controller?

根据 Kubernetes 文档,“控制器 (controller) 是监控集群状态的控制回路,能够在需要时做出更改或请求做出更改。每个控制器都会努力让当前集群状态接近所期望的状态。”控制器用于管理 Kubernetes 中许多种任务的状态,包括正确分配资源、指定持久化存储和管理 cron 作业。

在路由的上下文中,Ingress controller 能够消除 NodePort 和 LoadBalancer 的局限性。

针对特定 service 的 pod,Ingress controller 用于配置和管理其外部交互。Ingress controller 将动态七层路由视为“一等公民”。这意味着 Ingress controller 能够更轻松地提供更细粒度的控制和管理。借助 Ingress controller,您既可以轻松地控制入向流量,也可以提供 service 级的性能指标,并将其作为安全策略的一部分。Ingress controller 还具有传统外部负载均衡器的许多特性,例如 TLS 终止、处理多个域和命名空间,当然还有负载均衡流量。Ingress controller 可以按请求而不是按 service 对流量进行负载均衡,因此能够支持您更有效地监看七层流量并且更好地实施 SLA。

Ingress controller 还有一个优势!它还可以执行出向规则,这些规则可以做到只允许来自某些 pod 的流量传输到特定的外部 service,或者确保使用 mTLS 对流量进行相互加密。mTLS 加密对于在医疗、金融、电信和政府等行业提供受监管的服务至关重要,这也是端到端加密 (E2EE) 策略的关键组成部分。控制来自同一工具的出站流量还能够简化业务逻辑在 service的应用。当入向和出向可以在同一个控制平面中统一调配时,设置适当的资源规则就容易得多了。

下图展示了 Ingress controller 是如何降低客户端的复杂性的——客户端不再需要知道 service 的 IP 地址或端口。不同 service 之间的流量分发得到了保障。一些 Ingress controller 支持多个负载均衡算法,以获得更好的灵活性和控制性。

Exposing Services with an Ingress Controller 使用 Ingress Controller 暴露 service
Client
Request to pine.color.com on port 80
客户端
 pine.color.com 的 80 端口发送请求
Load Balancer port 80
-pine.color
-lagoon.color
-deeplake.color
负载均衡器 80 端口
-pine.color
-lagoon.color
-deeplake.color
1 The client is programmed with the service IP address and the load balancer port. 1 客户端使用 service IP 地址和负载均衡器端口进行编程。
2 The Ingress controller guarantees traffic distributes across nodes and services. 2 Ingress controller 保证流量分发到各个节点和 service。
Kubernetes cluster Kubernetes 集群
Node 1 节点 1
Service: Pine
Service: Lagoon
Service: Deep Lake
Service:Pine
Service:Lagoon
Service:Deep Lake
Node 2 节点 2
Node 3 节点 3

正如我们在《在同一架构中部署 BIG-IP 和 NGINX Ingress Controller》中所讨论的,许多企业的用例都会因部署带 Ingress controller(或在大多数情况下,多个 Ingress controller 实例)的外部负载均衡器而受益。当企业需要扩展 Kubernetes 或在高度合规环境中运营时,这种部署尤为常见。这些工具通常由不同的团队管理并用于不同的目的:

  • 负载均衡器(或称 ADC):
  1. 所有者:NetOps(也可能是 SecOps)团队
  2. 用例:位于 Kubernetes 外部,作为唯一面向公众的终端,为集群之外的用户提供服务和应用。作为一种更通用的应用,旨在提高安全性,并促进交付更高级别的网络管理。
  • Ingress controller:
  1. 所有者:Platform Ops 或 DevOps 团队
  2. 用例:位于 Kubernetes 内部,支持细粒度的南北流量(HTTP2、HTTP/HTTPS、SSL/TLS 终止、TCP/UDP、WebSocket、gRPC)负载均衡、API 网关功能以及集中式安全防护和身份验证。

下图展示了负载均衡器处理跨多个集群流量分发的过程,同时集群部署了 Ingress controllers 来确保对 service 的平均分发。

Deploying a Load Balancer in Front of Ingress Controllers 在 Ingress Controller 前面部署负载均衡器
Client
Request to pine.color.com on port 80
客户端
 pine.color.com 的 80 端口发送请求
Load Balancer port 80 负载均衡器 80 端口
Ingress Controller port 80
-pine.color
-lagoon.color
-deeplake.color
Ingress Controller 80 端口
-pine.color
-lagoon.color
-deeplake.color
1 The load balancer distributes traffic across Ingress pods. 1 负载均衡器将流量分发到各个 Ingress pod。
2 The Ingress controller guarantees traffic distributes across nodes and services. 2 Ingress controller 保证流量分发到各个节点和 service。
Kubernetes cluster Kubernetes 集群
Node 1 节点 1
Service: Pine
Service: Lagoon
Service: Deep Lake
Service:Pine
Service:Lagoon
Service:Deep Lake
Node 2 节点 2
Node 3 节点 3

后续步骤

如果本文没有完全解答您的疑问,请观看 Linux Foundation 网络研讨会“为什么需要 Ingress Controller”和“如何选择 Ingress Controller”,其中 NGINX 专家介绍了有关 Kubernetes 网络的入门知识,并就 Ingress controller 和市场现状做了深入探讨。

有关如何使用 Ingress controller 以及如何选择最能满足您需求的 Ingress controller 的更多信息,请阅读我们的博文《Ingress Controller 选购指南,第 1 部分:确定需求》


更多资源

想要更及时全面地获取 NGINX 相关的技术干货、互动问答、系列课程、活动资源?

请前往 NGINX 开源社区:

{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/5246775/blog/5553400