共计 5811 个字符,预计需要花费 15 分钟才能阅读完成。
本文翻译自:[Life of a Packet in Kubernetes — Part 4 [1]](https://dramasamy.medium.com/…)
作者:Dinesh Kumar Ramasamy
本文在原文的根底上做了适当的批改,如有疑问请查阅原文。
本文是 Kubernetes 中数据包的生命周期系列文章的第 4 局部,咱们将会介绍 Kubernetes 中的 Ingress
资源对象和 Ingress Controller。Ingress Controller 是一个控制器,它监督 Kubernetes API Server 对 Ingress 资源的变更并相应地更新负载均衡器的配置。
## 1 Nginx Controller 和 LoadBalancer/Proxy
Ingress Controller 通常是以 Pod 的模式运行在 Kubernetes 集群中,它依据 Ingress 资源配置负载均衡器。负载均衡器能够是运行在集群中的软件负载均衡器,也能够是在内部运行的硬件或云负载均衡器。不同的负载均衡器须要应用不同的 Ingress Controller。
Ingress
实质上是 Kubernetes 对反向代理的一个高级形象,形容了一系列流量治理的办法,特地是针对 HTTP(S)。通过 Ingress
,咱们能够定义路由转发的规定,而无需创立一堆负载均衡器或在每个节点上裸露服务。能够为服务提供内部可拜访的 URLs,流量的负载平衡,SSL/TLS 终结,并提供基于名称的虚拟主机和基于内容的路由。
## 2 配置选项
在 Kubernetes 中应用 Ingress Class 标记 Ingress 资源对象所属的 Ingress Controller。这容许多个 Ingress Controller 在同一个 Kubernetes 集群中共存,每个 Ingress Controller 只会解决属于它的配置。
基于前缀的路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prefix-based
annotations:
kubernetes.io/ingress.class: "nginx-ingress-inst-1" # 标记所属的 Ingress Controller
spec:
rules:
- http:
paths:
- path: /video
pathType: Prefix
backend:
service:
name: video
port:
number: 80
- path: /store
pathType: Prefix
backend:
service:
name: store
port:
number: 80
在 Kubernetes 1.18 版本引入 IngressClass 资源和 ingressClassName
字段之前,Ingress Class 是通过 Ingress 中的一个 kubernetes.io/ingress.class
注解来指定的。这个注解从未被正式定义过,然而失去了 Ingress Controller 的广泛支持。
Ingress 中新的 ingressClassName
字段是该注解的替代品,但并非齐全等价。该注解通常用于援用实现该 Ingress 的控制器的名称,而这个新的字段则是对一个蕴含额定 Ingress 配置的 IngressClass 资源的援用,包含 Ingress Controller 的名称。
# IngressClass 资源
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx-ingress-inst-1 # IngressClass 名字
annotations:
ingressclass.kubernetes.io/is-default-class: "true" # 设置为默认的 IngressClass,当 Ingress 中没有设置 ingressClassName 字段或者 kubernetes.io/ingress.class 注解时将会应用这个 IngressClass
spec:
controller: k8s.io/ingress-nginx
---
# 在 Ingress 中指定 ingressClassName
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prefix-based
spec:
ingressClassName: "nginx-ingress-inst-1" # 标记所属的 Ingress,援用 IngressClass 资源
rules:
- http:
paths:
- path: /video
pathType: Prefix
backend:
service:
name: video
port:
number: 80
- path: /store
pathType: Prefix
backend:
service:
name: store
port:
number: 80
基于主机的路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-based
annotations:
kubernetes.io/ingress.class: "nginx-ingress-inst-1"
spec:
rules:
- host: "video.example.com" # 域名
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: video
port:
number: 80
- host: "store.example.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: store
port:
number: 80
基于主机 + 前缀的路由
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: host-prefix-based
annotations:
kubernetes.io/ingress.class: "nginx-ingress-inst-1"
spec:
rules:
- host: foo.com
http:
paths:
- backend:
serviceName: foovideo
servicePort: 80
path: /video
- backend:
serviceName: foostore
servicePort: 80
path: /store
- host: bar.com
http:
paths:
- backend:
serviceName: barvideo
servicePort: 80
path: /video
- backend:
serviceName: barstore
servicePort: 80
path: /store
Ingres 是 Kubernetes 的内置对象,为了让 Ingress 资源工作,集群中必须有一个正在运行的 Ingress Controller。Ingress Controller 须要实现 Ingress API 的相干接口。社区中有很多 Ingress Controller 的实现,本文将会介绍 Nginx 和 Contour。
前文提到,Kubernetes Ingress 是一个 API 对象,它形容了如何对外公布部署在 Kubernetes 集群中的服务。因而,要使 Ingress Controller 可能工作,你须要实现 Ingress API 来读取和解决 Ingress 资源的信息。
Ingress API 对象只是元数据信息,真正的工作是由 Ingress Controller 来实现的。有许多 [Ingress Controller [2]](https://kubernetes.io/docs/co…) 可供使用,重要是依据具体场景抉择适合的 Ingress Controller。
也能够在同一个集群中部署多个 Ingress Controller,并为每个 Ingress 设置所属的 Ingress Controller。通常,咱们会针对同一集群中的不同场景组合应用这些控制器。例如,咱们可能有一个控制器用于解决进入集群的内部流量,其中包含与 SSL 证书的绑定,而另一个没有 SSL 绑定的控制器用于解决集群内的流量。
## 3 部署选项
### 3.1 Contour + Envoy
Contour Ingress Controller 蕴含以下两局部:
- Envoy(数据立体),提供高性能反向代理。
- Contour(管制立体),读取 Ingress 资源信息并对 Envoy 进行配置。
Contour 和 Envoy 容器是离开部署的,Contour 以 Deployment 的形式运行,Envoy 以 Daemonset 的形式运行,当然其余形式部署也是能够的。Contour 是调用 Kubernetes API 的客户端。Contour 监督 Ingress,HTTPProxy, Secret, Service 和 Endpoint 对象,并转换为 Envoy 的相干配置:例如,Service 对应 CDS,Ingress 对应 RDS,Endpoint 对应 EDS 等等。
下图显示了启用主机网络(hostNetwork: true
)的 EnvoyProxy (0.0.0.0:80)。
3.2 Nginx
Nginx Ingress Controller 的指标是组装一个配置文件(nginx.conf)。当配置文件产生任何更改时须要从新加载 Nginx。须要留神的是,如果只有 upstream(应用程序的 Endpoint)变动的话,此时无需从新加载 Nginx。咱们能够应用 [lua-nginx-module [3]](https://github.com/openresty/…) 来实现这一点。
每当 Endpoint 更改时,控制器都会从 Service 中获取 Endpoint 并生成相应的后端对象。而后将这些对象发送到在 Nginx 中运行的 Lua 处理程序。Lua 代码将这些后端对象存储在共享内存区域中。对于在 [balancer_by_lua [4]](https://github.com/openresty/…) 上下文中的申请,Lua 代码会检测到有哪些上游 Enpdoint,并利用配置的负载平衡算法来抉择 Endpoint。其余的工作由 Nginx 负责。这样咱们能够防止在 Endpoint 更改时从新加载 Nginx。在频繁部署应用程序的绝对较大的集群中,此性能能够节俭 Nginx 大量的从新加载,从而防止影响响应提早、负载平衡品质(每次从新加载后 Nginx 都会重置负载平衡状态)等问题。
3.3 Nginx + Keepalived — 高可用部署
[keepalived [5]](https://keepalived.readthedoc…) 守护过程可用于监控服务或零碎,并在呈现问题时主动实现故障转移。咱们配置一个能够在工作节点之间漂移的[浮动 IP [6]](https://www.digitalocean.com/…)。当工作节点宕机时,浮动 IP 会主动漂移到另一个工作节点上,新的工作节点接管拜访流量。
3.4 MetalLB — 带有 LoadBalancer 服务的 Nginx(实用于含有大量公网地址的公有集群)
MetalLB 是裸机 Kubernetes 集群中负载均衡器的实现。简略来说,它容许你在非云提供商提供的 Kubernetes 集群中创立类型为 LoadBalancer 的 Kubernetes Service。在云提供商提供的 Kubernetes 集群中,由云提供商负责调配 LoadBalancer Service 的 IP 地址,并在云提供商的负载平衡设施上公布服务(例如 AWS 的 ELB,阿里云的 SLB 等)。在裸机 Kubernetes 集群中,MetalLB 负责调配 IP 地址。一旦 MetalLB 为服务调配了内部 IP 地址,它须要让集群内部的网络晓得这个 IP“存在“于集群中。MetalLB 应用规范的路由协定实现这一点:ARP,NDP 或者 BGP。
在 Layer 2 模式下,集群中的一台机器取得 IP 地址的所有权并应用规范地址发现协定(IPv4 应用 [ARP [7]](https://en.wikipedia.org/wiki…),IPv6 应用 [NDP [8]](https://en.wikipedia.org/wiki…))。在 Layer 2 模式下,所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上,存在单点网络瓶颈。
在 BGP 模式下,集群中的所有机器都与内部路由器建设 [BGP [9]](https://en.wikipedia.org/wiki…) 街坊关系,并通知路由器如何将流量转发到 Service IP。基于 BGP 的策略机制,应用 BGP 能够实现跨多个节点真正的负载平衡,以及细粒度的流量管制。
MetalLB 运行时有两种工作负载:
- Controler:以 Deployment 形式部署,是集群范畴的 MetalLB 控制器,用于监听 Service 的变更,调配 / 回收 IP 地址。
- Speaker:以 DaemonSet 形式部署,对外播送 Service 的 IP 地址。
4 参考资料
- [1] 原文链接: https://dramasamy.medium.com/…
- [2] Ingress Controller: https://kubernetes.io/docs/co…
- [3] lua-nginx-module: https://github.com/openresty/…
- [4] balancer_by_lua: https://github.com/openresty/…
- [5] keepalived: https://keepalived.readthedoc…
- [6] floating IP address: https://www.digitalocean.com/…
- [7] ARP: https://en.wikipedia.org/wiki…
-
[8] NDP: https://en.wikipedia.org/wiki…
- [9] BGP: https://en.wikipedia.org/wiki…
5 欢送关注