Istio Gateway与Kubernetes Ingress Controller对比

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 在Kubernetes环境中,Kubernetes Ingress用于配置需要在集群外部公开的服务。但是在Istio服务网格中,更好的方法是使用新的配置模型,即Istio Gateway。Gateway允许将Istio流量管理的功能应用于进入集群的流量。

在Kubernetes环境中,Kubernetes Ingress用于配置需要在集群外部公开的服务。但是在Istio服务网格中,更好的方法是使用新的配置模型,即Istio Gateway。Gateway允许将Istio流量管理的功能应用于进入集群的流量。

二者在支持的功能上的对比,如下表所示

Istio Gateway 阿里云Ingress Controller NGINX Ingress Controller
根据HTTP Header选择路由规则 支持 仅支持单个Header,不支持多个Header组合 不支持
Header规则支持正则表达式 支持 支持 不支持
服务之间设置权重拆分流量 支持 支持 不支持
Header和权重规则组合使用 支持 支持 不支持
路由规则检查 支持 不支持 不支持
路由规则粒度 service下的不同pod service service
支持的协议 HTTP1.1/HTTP2/gRPC/TCP/Websockets/MongoDB HTTP1.1/HTTP2/gRPC/TCP/Websockets HTTP1.1/HTTP2/gRPC/TCP/Websockets

下面我们看下使用Istio Gateway实现灰度发布时,与Ingress在使用上的差异

Istio Gateway实现灰度发布

环境准备

创建Kubernetes集群

阿里云容器服务Kubernetes 1.10.4目前已经上线,可以通过容器服务管理控制台非常方便地快速创建 Kubernetes 集群。具体过程可以参考这里

部署istio

阿里云容器服务在应用目录目前支持istio快速部署,具体过程可以参考这里

部署用于灰度发布的两个服务

old service

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: old-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      run: old-nginx
  template:
    metadata:
      labels:
        run: old-nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx
        imagePullPolicy: Always
        name: old-nginx
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: old-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: old-nginx
  sessionAffinity: None
  type: NodePort

new service

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: new-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      run: new-nginx
  template:
    metadata:
      labels:
        run: new-nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx
        imagePullPolicy: Always
        name: new-nginx
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: new-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: new-nginx
  sessionAffinity: None
  type: NodePort

部署后效果如下图

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   172.19.0.1      <none>        443/TCP        9h
new-nginx    NodePort    172.19.8.168    <none>        80:31904/TCP   4h
old-nginx    NodePort    172.19.12.148   <none>        80:31545/TCP   4h

测试两个服务

$ kubectl run -it --rm bash --image=appropriate/curl --restart=Never curl 172.19.8.168
new
$ kubectl run -it --rm bash --image=appropriate/curl --restart=Never curl 172.19.12.148
old

创建Gateway对象

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: helloworld-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

确定Istio入口IP和port

$ kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   172.19.14.182   47.1x6.xx.41   80:31380/TCP,443:31390/TCP,31400:31400/...   10h

确认EXTERNAL-IP设置了值

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http")].port}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')

发布场景

满足特定规则的客户端才能访问new service

例如,我们希望请求头中带有user且值为new的客户端请求才能访问new service

我们可以创建一个对应的VirtualService为通过Gateway进入的流量配置路由

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  gateways:
  - helloworld-gateway
  hosts:
  - '*'
  http:
  - match:
    - headers:
        user:
          exact: new
    route:
    - destination:
        host: new-nginx
        port:
          number: 80
  - route:
    - destination:
        host: old-nginx
        port:
          number: 80

客户端测试

$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old

在满足特定规则的客户端请求中会有一定比例访问到new service

例如,我们希望请求头中带有user且值为new的客户端请求有50%的比例访问new service,那么我们可以创建一个这样的VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  gateways:
  - helloworld-gateway
  hosts:
  - '*'
  http:
  - match:
    - headers:
        user:
          exact: new
    route:
    - destination:
        host: new-nginx
        port:
          number: 80
      weight: 50
    - destination:
        host: old-nginx
        port:
          number: 80
      weight: 50
  - route:
    - destination:
        host: old-nginx
        port:
          number: 80

客户端测试

$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
new
$ curl -H "user: new" http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old

客户端请求中随机会有一定比例访问到new service

例如,我们仅仅希望20%的客户端请求访问new service,那么我们可以创建一个这样的VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  gateways:
  - helloworld-gateway
  hosts:
  - '*'
  http:
  - route:
    - destination:
        host: new-nginx
        port:
          number: 80
      weight: 20
    - destination:
        host: old-nginx
        port:
          number: 80
      weight: 80

客户端测试

$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
old
$ curl http://$INGRESS_HOST:$INGRESS_PORT
new

与阿里云容器服务Kubernetes Ingress Controller使用上的对比

阿里云容器服务Kubernetes Ingress Controller提供的灰度发布功能参考这里

因为受限于Kubernetes对Ingress资源的描述,Ingress Controller只能通过各种annotation表达式来支持http路由特性

但是Istio Gateway是通过Custom Resource Definition(CRD)的方式定义一种新的资源,相比之下具有更多优势:

  • 语义规则清晰,更有约束,与Ingress的annotation纯文本定义相比更容易检查错误
  • 各种规则可以自由组合,比如,第一种灰度场景,如果我们希望客户端请求header中同时有user=new和foo=bar才可以访问new service时,我们可以将VirtualService修改如下:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  gateways:
  - helloworld-gateway
  hosts:
  - '*'
  http:
  - match:
    - headers:
        user:
          exact: new
        foo:
          exact: bar
    route:
    - destination:
        host: new-nginx
        port:
          number: 80
      weight: 50
    - destination:
        host: old-nginx
        port:
          number: 80
      weight: 50
  - route:
    - destination:
        host: old-nginx
        port:
          number: 80

这种场景,目前Ingress就无法支持

总结

我们可以利用阿里云Kubernetes容器服务,快速搭建一套用于连接、管理以及安全化微服务的开放平台Istio,为应用引入和配置多个相关服务。本文通过几个灰度发布的场景来体验Istio Gateway带来的Ingress功能,并同Kubernetes Ingress做了功能上的对比。
欢迎大家使用阿里云上的容器服务,快速搭建微服务的开放治理平台Istio,比较简单地集成到自己项目的微服务开发中。

感谢师兄在本文写作过程中给予的指导:)

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
104 0
|
2月前
|
Kubernetes 应用服务中间件 nginx
Kubernetes上安装Metallb和Ingress并部署应用程序
Kubernetes上安装Metallb和Ingress并部署nginx应用程序,使用LoadBalancer类型的KubernetesService
139 4
|
28天前
|
缓存 Kubernetes 负载均衡
在K8S中,ingress 有何作用?
在K8S中,ingress 有何作用?
|
3月前
|
Kubernetes 应用服务中间件 API
【Ingress 秘籍】集群进出流量的总管:揭秘 Kubernetes 中 Ingress 的终极奥秘!
【8月更文挑战第25天】Ingress是Kubernetes中用于管理HTTP与HTTPS流量进入集群的核心功能。作为集群内外通信的桥梁,Ingress通过定义规则将外部请求导向内部服务。本文详细介绍了Ingress的基本概念、配置方法及其实现方式。通过使用不同的Ingress控制器(如Nginx、Traefik等),用户可以根据需要选择最适合的方案。文中还提供了示例代码展示如何创建服务、部署应用及配置Ingress规则。
114 6
|
3月前
|
API UED 开发者
超实用技巧大放送:彻底革新你的WinForms应用,从流畅动画到丝滑交互设计,全面解析如何在保证性能的同时大幅提升用户体验,让软件操作变得赏心悦目不再是梦!
【8月更文挑战第31天】在Windows平台上,使用WinForms框架开发应用程序时,如何在保持性能的同时提升用户界面的吸引力和响应性是一个常见挑战。本文探讨了在不牺牲性能的前提下实现流畅动画与交互设计的最佳实践,包括使用BackgroundWorker处理耗时任务、利用Timer控件创建简单动画,以及使用Graphics类绘制自定义图形。通过具体示例代码展示了这些技术的应用,帮助开发者显著改善用户体验,使应用程序更加吸引人和易于使用。
71 0
|
3月前
|
Kubernetes API 网络安全
在K8S中,ingress该如何使用?
在K8S中,ingress该如何使用?
|
9天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
10天前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
1月前
|
Kubernetes Cloud Native 云计算
云原生之旅:Kubernetes 集群的搭建与实践
【8月更文挑战第67天】在云原生技术日益成为IT行业焦点的今天,掌握Kubernetes已成为每个软件工程师必备的技能。本文将通过浅显易懂的语言和实际代码示例,引导你从零开始搭建一个Kubernetes集群,并探索其核心概念。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
100 17
|
25天前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
281 1

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多