从概念、部署到优化,Kubernetes Ingress 网关的落地实践

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 随着容器和 Kubernetes 技术的兴起,集群入口流量管理方式逐渐通用化、标准化。Kubernetes 通过 Ingress 资源用来管理外部 HTTP/HTTPS 流量进入集群内部的方式。目前,Ingress 的实现者 - Provider 的发展呈现百花齐放的状态,用户可以根据自身业务场景进行产品选型。为了帮助用户从建好 Ingress 网关到用好 Ingress 网关,本文将分享 Kubernetes 集群内,Ingress 网关从概念到部署的落地实践以及 MSE 云原生网关如何更好地实现 Kubernetes Ingress。

Kubernetes Ingress 简介

通常情况下,K8s 集群内的网络环境与外部是隔离的,也就是说 K8s 集群外部的客户端无法直接访问到集群内部的服务,这属于不同网络域如何连接的问题。解决跨网络域访问的常规做法是为目标集群引入一个入口点,所有外部请求目标集群的流量必须访问这个入口点,然后由入口点将外部请求转发至目标节点。

同样,K8s 社区也是通过增设入口点的方案来解决集群内部服务如何对外暴露的问题。K8s 一贯的作风是通过定义标准来解决同一类问题,在解决集群对外流量管理的问题也不例外。K8s 对集群入口点进行了进一步的统一抽象,提出了3种解决方案:NodePort、LoadBalancer 和 Ingress。下图是这三种方案的对比:

1650856415636-2cdaba11-88a9-4c95-a55d-b993de9f806f.png

通过对比,可以看到 Ingress 是更适合业务使用的一种方式,可以基于其做更复杂的二次路由分发,这也是目前用户主流的选择。

Kubernetes Ingress 现状

虽然 K8s 对集群入口流量管理方式进行标准化的统一抽象,但仅仅覆盖了基本的 HTTP/HTTPS 流量转发功能,无法满足云原生分布式应用大规模复杂的流量治理问题。比如,标准的 Ingress 不支持流量分流、跨域、重写、重定向等较为常见的流量策略。针对这种问题,存在两种比较主流的解决方案。一种是在 Ingress 的 Annotation 中定义 Key-Value 的方式来拓展;另一种是利用 K8s CRD 来定义新的入口流量规则。如下图所示:

1650870864982-ac6eec8c-7100-471c-8d26-5eb6089a3491.png

Kubernetes Ingress 最佳实践

本节将从以下5个方面展开 K8s Ingress 最佳实践。

  • 流量隔离:部署多套 IngressProvider,缩小爆炸半径
  • 灰度发布:如何利 用IngressAnnotation 来进行灰度发布
  • 业务域拆分:如何按照业务域进行 API 设计
  • 零信任:什么是零信任,为什么需要零信任,怎么做
  • 性能调优:一些实用的性能调优方法

流量隔离

在实际业务场景中,集群中后端服务需要对外部用户或者内部其他集群提供服务。通常来说,我们将外部访问内部的流量称为南北向流量, 将内部服务之间的流量称为东西向流量。为了节省机器成本和运维压力,有些用户会选择将南北向流量和东西向流量共用一个Ingress Provider。这种做法会带来新的问题,无法针对外部流量或者内部流量做精细化的流量治理,同时扩大了故障影响面。最佳的做法是针对外网、内网的场景分别独立部署Ingress Provider,并且根据实际请求规模控制副本数以及硬件资源,在缩小爆炸半径的同时尽可能提供资源利用率。

1650880271119-b80004fd-e651-443b-b261-cb6cb77c0d26.png

灰度发布

在业务持续迭代发展过程中,业务的应用服务面临着版本频繁升级的问题。最原始最简单的方式,是停掉线上服务的旧版本,然后部署、启动服务的新版本。这种直接将服务的新版本提供给所有用户的方式会带来两个比较严重的问题。首先,在停掉服务旧版本与启动新版本这段时间内,该应用服务是不可用,流量请求的成功率跌零。其次,如果新版本中存在严重的程序BUG,那么新版本回滚到旧版本的操作又会导致服务出现短暂的不可用,不仅影响用户体验,而且也会对业务整体系统产生诸多不稳定因素。

那么,如何既能满足业务快速迭代的诉求,又能保证升级过程中业务应用对外的高可用?

1650881695816-4dd76efa-28a4-4754-97cf-fa9860ba7975.png

我认为需要解决以下几个核心问题:

  1. 如何减小升级的影响面?
  2. 新版本出现Bug时如何快速回滚到稳定版本?
  3. 如何解决标准Ingress不支持流量分流的缺陷?

针对前两个问题,业界共识比较通用的做法是采用灰度发布,俗称金丝雀发布。金丝雀发布的思想则是将少量的请求引流到新版本上,因此部署新版本服务只需极小数的机器。验证新版本符合预期后,逐步调整流量,使得流量慢慢从老版本迁移至新版本,期间可以根据当前流量在新老版本上的分布,对新版本服务进行扩容,同时对老版本服务进行缩容,使得底层资源得到最大化利用。

在Ingress现状小节里,我们提到了目前比较流行的两种扩展Ingress的方案,其中通过为Annotation新增Key-Value的方式可以解决第三个问题。我们可以在Annotation中定义灰度发布需要的策略配置,比如配置灰度流量的Header、Cookie以及对应值的匹配方式 (精确匹配或者正则匹配)。之后由Ingress Provider识别新定义的Annotation并解析为自身的路由规则,也就是关键在于用户选择的Ingress Provider要支持丰富的路由方式。

灰度发布——按照Header灰度

在进行小流量验证服务新版本是否符合预期的环节中,我们可以有选择的将线上具有一部分特征的流量认为是小流量。请求内容中Header、Cookie都可以认为是请求特征,因此针对同一个API,我们可以按照Header或者Cookie对线上流量进行切分。如果真实流量中Header无差别,我们可以基于线上环境手动制造一些带有灰度Header的流量进行验证。此外,我们也可以按照客户端的重要性来分批进行新版本验证,比如对于普通用户的访问请求优先访问新版本,待验证完毕后,再逐步引流VIP用户。一般这些用户信息、客户端信息都会存在Cookie中。

以Nginx-Ingress为例,通过Annotation支持Ingress的流量分流,按照Header灰度的示意图如下:

1650888122357-03ef69d4-dd46-465b-bd22-e5ab8b714b72.png

灰度发布——按照权重灰度

按照Header灰度的方式可以对特定的请求或者用户提供服务新版本,但是无法很好评估访问新版本的请求规模,因此在为新版本分配机器时可能无法做到资源最大化利用。而按照权重进行灰度的方式可以精确控制流量比例,在机器资源分配上游刃有余。通过前期小流量验证后,后期通过调整流量权重,逐步完成版本升级,这种方式操作简单,易于管理。然而线上流量会无差别地导向新版本,可能会影响重要用户的体验。按照权重灰度的示意图如下:

1650888707034-71f1a4ba-b89f-49fa-8b81-d2451533fced.png

业务域拆分

随着云原生应用规模不断扩大,开发者开始对原来的单体架构进行细粒度的拆分,将单体应用中的服务模块拆分成一个个独立部署运行的微服务,并且这些微服务的生命周期由对应的业务团队独自负责,有效的解决了单体架构中存在的敏捷性不足、灵活性不强的问题。但任何架构都不是银弹,在解决旧问题同时势必会引入一些新的问题。单体应用通过一个四层SLB即可完成对外暴露服务,而分布式应用依赖Ingress提供七层流量分发能力,这时如何更好的设计路由规则尤为重要。

通常我们会根据业务域或者功能域进行服务拆分,那么我们在通过Ingress对外暴露服务时同样可以遵循该原则。为微服务设计对外API时可以在原有的Path上添加具有代表性意义的业务前缀,在请求完成路由匹配之后和转发请求到后端服务之前时,由Ingress Provider通过重写Path完成业务前缀消除的工作,工作流程图如下:

1650941272227-144386a6-0a2c-4ea9-98fc-37dc6f035126.png

该API设计原则易于管理对外暴露的服务集合,基于业务前缀做更细粒度的认证鉴权,同时方便对各个业务域服务进行统一的可观测建设。

零信任

安全问题始终是业务应用的头号公敌,伴随着业务发展的整个生命周期。此外,外部互联网的环境越来越复杂,内部业务架构日益庞大,部署结构涉及公有云、私有云以及混合云多种形态,安全问题愈演愈烈。零信任作为安全领域的一种新型设计模型应用而生,认为应用网络内外的所有用户、服务都不可信,在发起请求、处理请求之前都要经过身份认证,所有授权操作遵循最小权限原则。简单来说就是trust no-one, verify everything.

下图是关于外部用户->Ingress Provider->后端服务整个端到端落地零信任思想的架构图:

1650942822546-19a4664b-a890-47f7-8d0c-9c0fd29c2dbb.png

  • 外部用户与Ingress Provider。外部用户通过向权威证书机构验证Ingress Provider提供的证书完成身份认证;Ingress Provider通过外部用户提供JWT凭证完成认证鉴权。
  • Ingress Provider与后端服务。Ingress Provider通过向内部私有证书机构验证后端服务提供的证书完成身份认证,后端服务通过向内部私有证书验证Ingress Provider提供的证书完成身份认证,同时后端服务可以基于调用方身份向授权服务进行鉴权操作。

性能调优

所有的外部访问流量都需要先经过Ingress Provider,因此主要性能瓶颈体现在Ingress Provider,在高并发、高性能上有了更高的要求。抛开各个Ingress Provider之间的性能差异,我们可以通过调整内核参数来进一步释放性能。经过阿里巴巴多年在集群接入层的实践经验,我们可以适当调整以下内核参数:


  1. 调大TCP连接队列的容量:net.core.somaxconn
  2. 调大可用端口范围:net.ipv4.ip_local_port_range
  3. 复用TCP连接:net.ipv4.tcp_tw_reuse

另一个优化角度是从硬件着手,充分释放底层硬件算力来进一步提高应用层的性能。当下HTTPS已经成为公网请求的主要使用方式,全部使用HTTPS后由于其要做TLS握手,相比HTTP势必性能上会有很大损耗。目前随着CPU性能的大幅提升,利用CPU的SIMD机制可以很好的加速TLS的性能。该优化方案依赖机器硬件的支持以及Ingresss Provider内部实现的支持。

目前,依托Istio-Envoy架构的MSE云原生网关结合阿里云第七代ECS率先完成了TLS硬件加速,在不增加用户资源成本的同时大幅度提升HTTPS的性能。

1642598010888-9e2f1400-f54f-4665-aa20-e8de85e60b59.png

Ingress Provider新选择——MSE 云原生网关

随着云原生技术持续演进,云原生应用微服务化不断深入,Nginx Ingress在面对复杂路由规则配置、支持多种应用层协议(Dubbo和QUIC等)、服务访问的安全性以及流量的可观测性等问题上略显疲惫。另外,Nignx Ingress在处理配置更新问题上是通过Reload方式来生效配置,在面对大规模长连接的情况下是会出现闪断情况,频繁变更配置可能会造成业务流量有损。

为了解决用户对大规模流量治理的强烈诉求,MSE云原生网关应运而生,这是阿里云推出的兼容标准Ingress规范的下一代网关,具备低成本、安全、高集成和高可用的产品优势。将传统的WAF网关、流量网关和微服务网关合并,在降低50%资源成本的同时为用户提供了精细化的流量治理能力,支持ACK容器服务、Nacos、Eureka、固定地址、FaaS等多种服务发现方式,支持多种认证登录方式快速构建安全防线,提供全方面、多视角的监控体系,如指标监控、日志分析以及链路追踪,并且支持解析单、多K8s集群模式下的标准Ingress资源,帮助用户在云原生应用场景下以声明式进行统一流量治理,此外我们引入了WASM插件市场满足用户定制化的需求。

1650957451074-75048b37-7fe3-44c6-a1e6-046a4b73c164.png

Nginx Ingress VS MSE 云原生网关

以下是Nginx Ingress与MSE云原生网关的对比总结:

1650957597957-c45c26e7-6569-4f44-a437-b9f4c6d513f8.png

平滑迁移

MSE云原生网关由阿里云托管,免运维,降成本,功能丰富,且与阿里云周边产品深度集成,下图是从Nginx Ingress如何无缝迁移至MSE云原生网关,其他Ingress Provider也可以参考该方法。

1650957762335-6112070b-781f-41d1-bdb7-121f440fe6e8.png

动手实践

接下来,我们会基于阿里云容器服务 ACK 进行 Ingress Provider——MSE云原生网关相关的实践操作,您可以了解到如何通过 MSE Ingress Controller 来管理集群入口流量。

操作文档地址:https://help.aliyun.com/document_detail/426544.html

前提条件

安装MSE Ingress Controller

我们可以在阿里云容器服务的应用市场中找到ack-mse-ingress-controller,并且按照组件下方的操作文档完成安装。

1651042349667-b3528071-55ea-47f9-9afb-a2dd01e897ff.png

通过CRD的方式创建MSE云原生网关

MseIngressConfig是由MSE Ingress Controller提供的CRD资源,MSE Ingress Controller使用MseIngressConfig来管理MSE 云原生网关实例的生命周期。一个MseIngressConfig对应一个Mse 云原生网关实例,如果您需要使用多个Mse 云原生网关实例,需要创建多个MseIngressConfig配置。为了简单展示,我们以一个最小化配置的方式来创建网关。

apiVersion: mse.alibabacloud.com/v1alpha1
kind: MseIngressConfig
metadata:
  name: test
spec:
  name: mse-ingress
  common:
    network:
      vSwitches:
        - "vsw-bp1d5hjttmsazp0ueor5b"

配置K8s标准的IngressClass来关联MseIngressConfig,关联完毕后云原生网关就会开始监听集群中与该IngressClass有关的Ingress资源。

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  annotations:
    ingressclass.kubernetes.io/is-default-class: 'true'
  name: mse
spec:
  controller: mse.alibabacloud.com/ingress
  parameters:
    apiGroup: mse.alibabacloud.com
    kind: MseIngressConfig
    name: test

我们可以通过查看MseIngressConfig的status来查看当前状态。MseIngressConfig会按照Pending > Running > Listening的状态依次变化。各状态说明如下:

  • Pending:表示云原生网关正在创建中,需等待3min左右。
  • Running:表示云原生网关创建成功,并处于运行状态。
  • Listening:表示云原生处于运行状态,并监听集群中Ingress资源。
  • Failed:表示云原生网关处于非法状态,可以查看Status字段中Message来进一步明确原因。

灰度发布实践

假设集群有一个后端服务httpbin,我们希望在版本升级时可以按照header进行灰度验证,如图所示:

1651043289224-f42b3dfa-24c0-43eb-af4f-61957a377518.png

首先部署httpbin v1和v2版本,通过apply以下资源到ACK集群中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin-v1
  template:
    metadata:
      labels:
        app: go-httpbin-v1
        version: v1
    spec:
      containers:
        - image: specialyang/go-httpbin:v3
          args:
            - "--port=8090"
            - "--version=v1"
          imagePullPolicy: Always
          name: go-httpbin
          ports:
            - containerPort: 8090
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-httpbin-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-httpbin-v2
  template:
    metadata:
      labels:
        app: go-httpbin-v2
        version: v2
    spec:
      containers:
        - image: specialyang/go-httpbin:v3
          args:
            - "--port=8090"
            - "--version=v2"
          imagePullPolicy: Always
          name: go-httpbin
          ports:
            - containerPort: 8090
---
apiVersion: v1
kind: Service
metadata:
  name: go-httpbin-v1
spec:
  ports:
    - port: 80
      targetPort: 8090
      protocol: TCP
  selector:
    app: go-httpbin-v1
---
apiVersion: v1
kind: Service
metadata:
  name: go-httpbin-v2
spec:
  ports:
    - port: 80
      targetPort: 8090
      protocol: TCP
  selector:
    app: go-httpbin-v2  

发布稳定版本v1的Ingress资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin
spec:
  ingressClassName: mse
  rules:
  - host: test.com
    http:
      paths:
      - path: /version
        pathType: Exact
        backend:
          service:
            name: go-httpbin-v1
            port: 
              number: 80

发布灰度版本v2的Ingress资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    "nginx.ingress.kubernetes.io/canary": "true"
    "nginx.ingress.kubernetes.io/canary-by-header": "stage"
    "nginx.ingress.kubernetes.io/canary-by-header-value": "gray"
  name: httpbin-canary-header
spec:
  ingressClassName: mse
  rules:
  - host: test.com
    http:
      paths:
      - path: /version
        pathType: Exact
        backend:
          service:
            name: go-httpbin-v2
            port: 
              number: 80

测试验证

# 测试稳定版本
curl -H "host: test.com" <your ingress ip>/version
# 测试结果
version: v1
# 测试灰度版本
curl -H "host: test.com" -H "stage: gray" <your ingress ip>/version
# 测试结果
version: v2

以上就是我们利用Ingress Annotation的方式扩展标准Ingress支持灰度发布的高阶流量治理能力。



写在最后

MSE - 云原生网关,旨在为用户提供更可靠的、成本更低、效率更高的,符合 K8s Ingress 标准的企业级网关产品,更多发布详情移步直播间观看:https://yqh.aliyun.com/live/detail/28477

MSE - 云原生网关提供后付费和包年包月两类付费模式,支持杭州、上海、北京、深圳 、张家口、香港、新加坡、美国(弗吉尼亚)、美国(硅谷)、德国(法兰克福)10个 region,并会逐步开放其他 region,云原生网关购买链接在这里

现在购买MSE云原生网关预付费全规格,立享7折优惠,新老同享。


也可钉钉搜索群号 34754806 可加入用户群交流、答疑。

1642599892533-9caa4835-ccb6-4144-8c20-ac88c345f815.png

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
25天前
|
网络协议 网络安全 数据安全/隐私保护
计算机网络概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等
计算机网络概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等
44 4
|
1月前
|
监控 安全 应用服务中间件
微服务架构下的API网关设计策略与实践####
本文深入探讨了在微服务架构下,API网关作为系统统一入口点的设计策略、实现细节及其在实际应用中的最佳实践。不同于传统的摘要概述,本部分将直接以一段精简的代码示例作为引子,展示一个基于NGINX的简单API网关配置片段,随后引出文章的核心内容,旨在通过具体实例激发读者兴趣,快速理解API网关在微服务架构中的关键作用及实现方式。 ```nginx server { listen 80; server_name api.example.com; location / { proxy_pass http://backend_service:5000;
|
1月前
|
网络协议 网络安全 数据安全/隐私保护
计算机网络概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等
【10月更文挑战第27天】计算机主机网关的作用类似于小区传达室的李大爷,负责将内部网络的请求转发到外部网络。当小区内的小不点想与外面的小明通话时,必须通过李大爷(网关)进行联系。网关不仅帮助内部设备与外部通信,还负责路由选择,确保数据包高效传输。此外,网关还参与路由表的维护和更新,确保网络路径的准确性。
48 2
|
2月前
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
131 0
|
3月前
|
监控 负载均衡 应用服务中间件
探索微服务架构下的API网关设计与实践
在数字化浪潮中,微服务架构以其灵活性和可扩展性成为企业IT架构的宠儿。本文将深入浅出地介绍微服务架构下API网关的关键作用,探讨其设计原则与实践要点,旨在帮助读者更好地理解和应用API网关,优化微服务间的通信效率和安全性,实现服务的高可用性和伸缩性。
59 3
|
4月前
|
Kubernetes 监控 开发者
|
4月前
|
Kubernetes Cloud Native 应用服务中间件
Kubernetes 自动伸缩策略:优化资源利用率
【8月更文第29天】在现代云原生环境中,应用的流量往往具有不可预测性。为了应对这种变化,Kubernetes 提供了多种自动伸缩机制来动态调整应用实例的数量和每个实例分配的资源。本文将深入探讨两种主要的自动伸缩工具:水平 Pod 自动伸缩器 (HPA) 和垂直 Pod 伸缩器 (VPA),并提供实际的应用示例。
123 0
|
4月前
|
应用服务中间件 API nginx
微服务从代码到k8s部署应有尽有系列(二、网关)
微服务从代码到k8s部署应有尽有系列(二、网关)
|
4月前
|
存储 Kubernetes 监控
在K8S中,集群可以做哪些优化?
在K8S中,集群可以做哪些优化?
|
4月前
|
存储 Kubernetes 监控
在K8S中,ELK是如何实现及如何优化的ES?
在K8S中,ELK是如何实现及如何优化的ES?