作 者 | 魁予
来 源 | 腾讯云原生植物项目组
时至今日有愈来愈多的企业开始接纳云原生植物经营理念进行应用领域构架结构调整。而 K8s 和微服务项目是云原生植物的三大支撑点,随着云原生植物大潮而被应用领域。
对绝大多数应用领域来说,提供更多对内服务项目的历史使命并不会发生改变,较之于原本的乙烯应用领域,微服务项目构架下的应用领域的服务项目出口产品更多,管理工作更繁杂,微服务项目交换机也不断涌现;而 K8s 也提供更多了多种不同形式来曝露应用领域的服务项目,各种 Ingress 同时实现百家争鸣。直面为数众多控制技术计划,我们怎样作出科学合理的优先选择,避免出现潜在性信用风险,责任编辑将得出一些THF1提议,供我们参照。
云原生植物交换机基本上简述
K8s 中服务项目对内出访的形式
对于布署在云服务项目器上的应用领域,一般来说采用阻抗平衡应用软件或服务项目(如 SLB)来提供更多高需用的服务项目。K8s 提供更多了如前所述 Service 的服务项目发现监督机制,使用者通过将一大批完全相同优点的 Pod 存取到两个 Service,能提供更多平衡的 VIP(交互式IP)或搜索引擎供应用软件产业内出访,并由 kube-proxy 模块如前所述 ipvs 或 iptables 同时实现 Pod 出访的阻抗平衡。当须要提供更多服务项目对内出访时,须要采用 NodePort 或 LoadBalancer 类别的 Service。
预设情况下,NodePort 会为服务项目在每一 K8s 应用软件产业的结点上重新分配两个结点路由器,采用结点的 IP 门牌号和选定的结点路由器能从应用软件产业内部出访到服务项目后端 Pod。用 NodePort 的形式曝露服务项目时,由于客户端实用性的是结点的 IP 门牌号和路由器,即便 Service 提供更多了阻抗平衡的潜能,其灵活性也会受相关联结点的影响。在应用程序出访服务项目时,设置多个 K8s 应用软件产业结点的 IP 和服务项目 nodePort 路由器,并实用性合适的阻抗平衡和重试策略,才能够避免单点故障。
K8s 同时提供更多了 LoadBalancer 的 Service,应用程序采用 LoadBalancer 的服务项目端点,能有效避免出现掉结点单点故障信用风险。LoadBalancer 类别 Service 如前所述 NodePort 同时实现,云厂商 CCM 模块将根据 Service 创建阻抗平衡监听路由器,并将 K8s 应用软件产业中各结点和 nodePort 路由器添加到阻抗平衡器后端,由云上阻抗平衡器同时实现服务项目阻抗平衡潜能。
对于须要 TCP 或 UDP 协议的四层转发时,采用 LoadBalancer 是两个简单有效的形式。但是当 K8s 应用软件产业中有大量 HTTP 或 HTTPS 类别的 web 服务项目须要进行七层转发时,如果仅采用 LoadBalancer 形式来曝露服务项目,当存在多个服务项目须要采用完全相同的路由器时,须要为每一服务项目创建两个阻抗平衡器,重新分配不同的 IP 门牌号,会造成大量的资源成本和维护成本。
应用领域交换机的要求
如前文所述,K8s Service 解决的是服务项目发现和阻抗平衡的问题,但并没有服务项目治理潜能,无法被当成交换机采用,而对于两个典型的应用领域交换机,基本上都包含以下能力:
为了避免为各个微服务项目做重复冗余的认证鉴权实用性,交换机能够支持提供更多安全认证、出访限制、支持 SSL 卸载等。
出于交换机灵活性考虑,我们希望交换机能够提供更多一定的限流潜能。
须要有可观测潜能查看交换机后端各服务项目响应时间趋势、请求状态码统计等。
为了保证能够快速定位排查问题,交换机也须要记录各请求的详细出访日志。
K8s 提出了 Ingress 以支持从应用软件产业内部到应用软件产业内服务项目的 HTTP 和 HTTPS 服务项目路由,并提供了对内出访的统一端点,Nginx Ingress 是社区提供更多的如前所述 Nginx 同时实现的预设 Ingress 控制器。
Nginx Ingress 简述
交换机云原生植物化是两个普遍的趋势,采用不同底层交换机同时实现的 Ingress Provider,其提供更多的交换机优点潜能各不完全相同。Nginx 作为被普遍采用的反向代理工具,如前所述 Nginx 同时实现的 Nginx Ingress 也成为了 K8s 应用软件产业中最广泛采用的Ingress交换机。
工作原理
一般来说 Nginx Ingress 以 Deployment 结合 LoadBalancer Service 的形式布署在 K8s 应用软件产业中,Nginx Ingress Controller 由 manager 和 Nginx 进程组成,manager 负责监听 Ingress 资源变更并如前所述 Nginx 实用性模版将 Ingress 资源的 Spec 定义和注解转换为Nginx可识别参数,生成新的 nginx.conf 实用性文件,并由 manager 发起 Nginx 进程 reload,新的路由实用性就通过 Ingress 在交换机生效了。内部流量经过 LoadBalancer 转发到 Nginx,由 Nginx 根据路由实用性转发到后端服务项目中。
Nginx Ingress Controller 还监听了 Service 的后端变化,并将变更后的后端列表发送到 Nginx 中进行缓存,在应用领域 Pod 变更或扩缩容时,无需考虑 Pod IP 变化即可同时实现 Nginx 服务项目后端动态变更。此外,Nginx Ingress 官方提供更多了 prometheus 监控对接计划,并提供更多了基础指标的监控大盘,便于观察交换机后端服务项目响应状态。
Ingress 资源定义了主机名和路径来设置服务项目在 Nginx 上的七层转发规则,同时 Nginx Ingress 还支持实用性扩展,扩展监督机制包括:
通用注解:对于一些通用的 Nginx 潜能,比如重写、重定向、连接数设置、超时时间等,Nginx Ingress 定义了通用的注解以便于 Controller 识别解析为 nginx.conf 配置文件内容。
实用性片段:直面须要定制化 Nginx 实用性的场景,Nginx Ingress 也提供更多了注解 main-snippet、server-snippet、configuration-snippet 来插入定制化的 nginx.conf 实用性片段。
lua 插件:Nginx Ingress 还支持插件化挂载自定义 lua 脚本便于从自建 Nginx 迁移到K8s Nginx Ingress 中。
两个采用 Ingress 的注解来自定义 location 片段,同时实现根据请求头重定向的例子如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_user = “gray”) {
rewrite ^/(.*)$ /traffic;
}
…
spec:
rules:
– host: test.domain.com
http:
paths:
– backend:
service:
name: test-svc
port:
number: 80
path: /test
…
查看 Nginx Ingress Controller 中的实用性,能看到插入的实用性片段:
server {
server_name test.domain.com
…
location /test {
…
if ($http_user = “gray”) {
rewrite ^/(.*)$ /traffic;
}
}
}
Nginx Ingress 交换机不足
不难看出,Nginx 反向代理交换机仍然是布署在 K8s 应用软件产业中的,交换机的性能直接受 Pod 资源重新分配和宿主机性能影响。且如果 Nginx Ingress Controller Pod 所在的结点仍然存在其他业务 Pod,还会出现资源抢占问题。由于 Nginx Ingress 承担了应用软件产业的大量入口流量,灵活性要求很高,一般来说情况下,我们会将其 Pod 独立调度来保证灵活性,比如在结点上设置污点,并在 Ingress Controller 的 Pod 中设置污点容忍让其独占结点资源;为增强 Ingress 交换机可靠性,须要结合业务实际压力设置 Ingress 的副本数和资源重新分配;出于交换机高峰期弹性考虑,还须要结合 HPA 以支持交换机 Pod 水平扩容;此外,Nginx Ingress 实际是由阻抗平衡器提供更多的对内出访潜能,还须要结合业务考虑阻抗平衡带宽是否满足高峰期需求。
K8s 为 Pod 提供更多了 livenessProbe 和 readinessProbe 的存活检查和健康检查监督机制,官方 Nginx Ingress Controller 的 Deployment 布署模版中也采用了该机制进行交换机健康检查,相关实用性如下:
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
其健康检查和存活检查采用的是由控制面 manager 监听的 10254 路由器提供更多的 /healthz 健康检查入口,而 Nginx Ingress 数据面和控制面在同两个容器中,在业务高峰期交换机阻抗较高时很有可能导致控制面的健康检查接口响应超时。根据 livenessProbe 监督机制,很有可能出现 Nginx Ingress 交换机不断重启导致网关不平衡,流量有损。此外,控制面 manager 还负责采集prometheus监控指标,在业务高峰期控制面还可能抢占不到足够的 CPU,出现 OOM,导致容器被 Kill 的情况。
另外须要注意的是,通过 Nginx Ingress 更新 Nginx 交换机路由规则直接将搜索引擎和路径订正到 nginx.conf 实用性文件,须要更新 Nginx 实用性并重新加载才能生效。当应用领域存在长连接,如 websocket 的情况下,reload 操作会导致业务连接在一段时间后出现明显掉线。
在操作 Ingress 资源时,如新建 Ingress、删除 Ingress、更新 Ingress 后端、更新 Ingress 证书实用性等操作,都会触发 Nginx 进程的 reload。虽然 Nginx 的 reload 过程存在优雅停止监督机制,在接收到 reload 信号后会创建新的 workerq 子进程并保持旧 worker 进程处理已有请求,如下图所示:
但是当应用程序存在 TCP 长连接超过了 worker_shutdown_timeout 时间没有断开时,会强制终止原有的 worker 进程,断开 worker 上的连接,nginx reload 原理示意图如下:
除此之外,由于 Nginx Ingress Controller 是通过 List 和 Watch 监督机制监听 K8s 中的资源,多个结点的控制器行为一致,reload 操作的时间虽然存时间差异,但大致能看作是同时进行,同时 reload 无疑会让信用风险最大化。为降低 reload 的影响,我们能考虑优化 Nginx Ingress,比如通过将 Nginx Ingress Controller 的实用性文件变更与自动reload 行为分开,保留动态修改实用性逻辑,增加 reload 触发逻辑,reload 操作只有满足了特定条件才能进行。比如,为 Pod 新增 reload 信号注解,控制器识别到结点存在该注解再触发 reload,降低 reload 操作的影响面。
但是 Nginx Ingress 通过实用性文件来更新 Nginx 路由实用性的操作,无法避免 reload。直面该问题,业界也提出了采用 Nginx 结合 Lua 插件动态读取交换机上游实用性的计划,路由规则存储在数据库中,由 Lua 实用性读取到 Nginx 的共享内存中,示意图如下。
自建交换机容易忽略的细节
综上可见,Nginx Ingress 交换机在 K8s 应用软件产业中存在进程 reload 长连接有损、数据面和控制面未分离、运维难度高等短板。当我们须要自建 Nginx Controller 时,设想一下,在 K8s 中还须要考虑哪些细节:
不平衡的后端 IP:Pod 的 IP 门牌号会随应用领域的重启、迁移、新版本发布频繁的变更。不平衡的后端 IP 让实用性难以下手。
频繁更新的实用性文件:每次后端应用领域的变更都须要人工维护 Nginx 实用性,当构建多结点的高需用 Nginx 服务项目时,须要人工保证多结点实用性的准确性一致性。
实用性持久化:由于 Pod 的不灵活性,当以 Pod 形式布署 Nginx 服务项目时,每次 Pod 的销毁和新建,在 Pod 中的变更都会丢失,须要持久化保存实用性并挂载到多个 Nginx Pod 中。
监控面板对接:须要运维人员自行安装 Nginx 监控模块,并对接到内部监控系统。
出访日志持久化:须要为 Nginx 服务项目额外挂载持久化数据盘以保存出访日志。
庆幸的是,随着云原生植物化趋势,愈来愈多的交换机兼容了 Ingress 同时实现成为了 Ingress Provider,不少交换机已经同时实现了实用性热加载,数据面和控制面分离的潜能,并且根据交换机优点潜能的不同存在各自的优缺点。在 EDAS 中,除了接入了 Nginx Ingress 路由外,还接入了 ALB Ingress、MSE Ingress。下面以这两种 Ingress Provider 为例介绍多种不同Ingress Provider 的通用同时实现及其优缺点。
其他 Ingress 交换机同时实现
Ingress 支持设置 “kubernetes.io/ingress.class” 注解或者实用性 ingressClassName 属性来为 Ingress 关联不同的 Ingress Controller。并由 Ingress Controller 来作为 Ingress 资源的监听模块,将 Ingress 的实用性解析为后端交换机的实用性中,如 Nginx 交换机的 nginx.conf 实用性,ALB 交换机的监听后端转发规则,云原生交换机的路由规则。Ingress、Ingress Class、Ingress Controller 关联关系如下图所示:
ALB Ingress
由上图可见,ALB Ingress 工作时业务面与数据面分离,支持热加载,底层的交换机同时实现为托管在阿里云上的 ALB 实例。如前所述 ALB 的高弹性、高并发数优点,能够得到完全免运维、自动弹性伸缩的高性能交换机,阿里云的 ALB Ingress 解决了 Nginx Ingress 维护的难点。ALB Ingress 兼容了部分 Nginx Ingress 的通用注解,但对于实用性片段和插件监督机制,由于底层同时实现的不同,并不能做到完全兼容。
MSE Ingress(云原生交换机)
MSE Ingress 是如前所述 MSE 云原生植物交换机同时实现的,业务面与数据面分离、支持热加载,云原生植物交换机不仅能够作为 Ingress Provider 为 K8s 应用软件产业中的 Service 提供更多对外南北向流量管理工作,还能够作为微服务项目交换机对接 EDAS 注册中心、MSE 注册中心、自建 Nacos、Eureka 注册中心提供更多东西向流量管理工作潜能。同时支持完备的微服务项目交换机功能,如限流、流量防护、熔断等,能够节省布署和维护应用领域型微服务项目交换机的成本,如 springCloud gateway、zuul。此外,在扩展性上,MSE Ingress 支持了 Wasm 插件,对于 Lua 插件的支持也在进行中。
场景总结
交换机云原生植物化是两个普遍的趋势,采用不同底层交换机同时实现的 Ingress Provider,其提供更多的交换机优点潜能各不完全相同。除责任编辑介绍 EDAS 支持的实用性的三种 Ingress Provider 外,还有其他多种不同热门 Provider,如 APISIX Ingress、Haproxy Ingress、Istio Ingress,他们在 K8s 应用软件产业中的工作模型均可参照上述的 Ingress-IngressClass-Ingress Controller 模式。
直面多样化的应用领域路由交换机,我们须要了解交换机优点潜能并结合实际业务场景来做优先选择,对于责任编辑提到的三种 Ingress Provider,能总结其分别适用的场景:
Nginx Ingress:官方提供更多的开源 Nginx Ingress 解决计划,与平台无关最易接入,适用于对交换机有定制化需求场景,适用于从自建 Nginx 交换机迁移到 K8s Ingress 交换机的场景。但须要额外对交换机进行运维,存在灵活性信用风险。
ALB Ingress:如前所述 ALB,全托管于阿里云上,免运维。适用于业务高峰期超大 QPS、超高并发连接的场景。如果应用领域运行在阿里云上,且没有复杂的扩展需求,ALB 是省时省力的优先选择。
MSE Ingress:如前所述云原生植物交换机,作为流量交换机和微服务项目 API 交换机,适用于对 K8s Ingress 交换机和微服务项目交换机同时需求的场景,支持多语言编写 Wasm 插件扩展交换机潜能。此外,该交换机同时实现已开源,详细可见:https://github.com/alibaba/higress
此外,Ingress API 仅支持根据搜索引擎和路径配置转发规则,交换机供应商须要通过自定义注解来同时实现更丰富的路由转发和流量治理潜能,致使交换机路由资源实用性愈来愈复杂。K8s 社区推出了开源项目 Gateway API,用以提供更多规范化、可扩展、更丰富的交换机路由模型,已有多种不同 Ingress 交换机供应商在其控制器中同时实现了 Gateway API 标准,保证了其路由实用性向 Gateway API 标准平滑迁移。
EDAS 应用领域路由管理工作
K8s Ingress为应用交换机提供更多了很多灵活的优先选择,但每种交换机潜能各有差异,而且大多通过注解形式来提供更多扩展潜能,对很多使用者来说复杂度是比较高的。为此,EDAS 提供更多了应用领域路由管理工作功能,使用者只须要编写路由规则并优先选择交换机类别,就能将应用领域的服务项目曝露到内部,方便快捷。同时 EDAS 也提供更多了应用领域路由的监控大盘,日志检索等必备的运维功能,能帮助使用者快速发现和定位问题,保证业务灵活性。参见下图:
Nginx Ingress
MSE Ingress
ALB Ingress
概览大盘
出访日志查询
调用链路追踪
↓进入代码江湖 领取限量云小宝数字藏品