Kubernetes Ingress 简介
通常情况下,Kubernetes 集群内的网络环境与外部是隔离的,也就是说 Kubernetes 集群外部的客户端无法直接访问到集群内部的服务,这属于不同网络域如何连接的问题。解决跨网络域访问的常规做法是为目标集群引入一个入口点,所有外部请求目标集群的流量必须访问这个入口点,然后由入口点将外部请求转发至目标节点。
同样,Kubernetes 社区也是通过增设入口点的方案来解决集群内部服务如何对外暴露的问题。Kubernetes 一贯的作风是通过定义标准来解决同一类问题,在解决集群对外流量管理的问题也不例外。Kubernetes 对集群入口点进行了进一步的统一抽象,提出了 3 种解决方案:NodePort、LoadBalancer 和 Ingress。下图是这三种方案的对比:
通过对比,可以看到 Ingress 是更适合业务使用的一种方式,可以基于其做更复杂的二次路由分发,这也是目前用户主流的选择。
Kubernetes Ingress 现状
虽然 Kubernetes 对集群入口流量管理方式进行标准化的统一抽象,但仅仅覆盖了基本的 HTTP/HTTPS 流量转发功能,无法满足云原生分布式应用大规模复杂的流量治理问题。比如,标准的 Ingress 不支持流量分流、跨域、重写、重定向等较为常见的流量策略。针对这种问题,存在两种比较主流的解决方案。一种是在 Ingress 的 Annotation 中定义 Key-Value 的方式来拓展;另一种是利用 Kubernetes CRD 来定义新的入口流量规则。如下图所示:
Kubernetes Ingress 最佳实践
本节将从以下 5 个方面展开 Kubernetes Ingress 最佳实践。
- 流量隔离:部署多套 IngressProvider,缩小爆炸半径
- 灰度发布:如何利 用 IngressAnnotation 来进行灰度发布
- 业务域拆分:如何按照业务域进行 API 设计
- 零信任:什么是零信任,为什么需要零信任,怎么做
- 性能调优:一些实用的性能调优方法
流量隔离
在实际业务场景中,集群中后端服务需要对外部用户或者内部其他集群提供服务。通常来说,我们将外部访问内部的流量称为南北向流量, 将内部服务之间的流量称为东西向流量。为了节省机器成本和运维压力,有些用户会选择将南北向流量和东西向流量共用一个 Ingress Provider。这种做法会带来新的问题,无法针对外部流量或者内部流量做精细化的流量治理,同时扩大了故障影响面。最佳的做法是针对外网、内网的场景分别独立部署 Ingress Provider,并且根据实际请求规模控制副本数以及硬件资源,在缩小爆炸半径的同时尽可能提供资源利用率。
灰度发布
在业务持续迭代发展过程中,业务的应用服务面临着版本频繁升级的问题。最原始最简单的方式,是停掉线上服务的旧版本,然后部署、启动服务的新版本。这种直接将服务的新版本提供给所有用户的方式会带来两个比较严重的问题。首先,在停掉服务旧版本与启动新版本这段时间内,该应用服务是不可用,流量请求的成功率跌零。其次,如果新版本中存在严重的程序 BUG,那么新版本回滚到旧版本的操作又会导致服务出现短暂的不可用,不仅影响用户体验,而且也会对业务整体系统产生诸多不稳定因素。
那么,如何既能满足业务快速迭代的诉求,又能保证升级过程中业务应用对外的高可用?
我认为需要解决以下几个核心问题:
- 如何减小升级的影响面?
- 新版本出现 Bug 时如何快速回滚到稳定版本?
- 如何解决标准 Ingress 不支持流量分流的缺陷?
针对前两个问题,业界共识比较通用的做法是采用灰度发布,俗称金丝雀发布。金丝雀发布的思想则是将少量的请求引流到新版本上,因此部署新版本服务只需极