Istio Gateway与Kubernetes Ingress Controller对比

简介: 在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,比较简单地集成到自己项目的微服务开发中。

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

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
缓存 Kubernetes Docker
容器服务ACK常见问题之容器服务ACK ingress websocket配置失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
11月前
|
编解码 运维 Kubernetes
政采云业务网关实践:使用 Higress 统一替代 APISIX/Kong/Istio Ingress
政采云基础架构团队技术专家朱海峰介绍了业务网关项目的背景和解决方案。
673 95
|
9月前
|
存储 人工智能 Kubernetes
ACK Gateway with AI Extension:面向Kubernetes大模型推理的智能路由实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with AI Extension组件,在Kubernetes环境中为大语言模型(LLM)推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
|
Kubernetes 应用服务中间件 nginx
Kubernetes上安装Metallb和Ingress并部署应用程序
Kubernetes上安装Metallb和Ingress并部署nginx应用程序,使用LoadBalancer类型的KubernetesService
968 104
|
Kubernetes 负载均衡 应用服务中间件
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
2401 1
|
Prometheus Kubernetes Cloud Native
云原生周刊:Argo Rollouts 支持 Kubernetes Gateway API 1.0 | 2024.7.1
探索开源世界:Kubetools的推荐系统[Krs](https://github.com/kubetoolsca/krs)助力K8s优化,追踪K8s组件清单,指引IAC集成。阅读建议: Prometheus与Thanos的进化故事,Adidas容器平台管理经验,K8s请求实现详解。关注云原生:Argo Rollouts支持Gateway API 1.0,Kubewarden v1.14强化策略与镜像安全。
204 0
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
453 2
|
API
Istio 使用ingress和gateway两种方式公开服务
本文档指导您完成Istio网关的部署与配置。首先安装`istiod`(步骤略过)。接着,创建`ingress.yaml`文件,定义Istio入口网关的服务、部署及权限设置,通过`kubectl apply -f ingress.yaml`命令应用。最后,创建Ingress资源,指定主机名、后端服务及TLS配置,实现对外部请求的路由管理。
1080 1
|
缓存 Kubernetes 负载均衡
在K8S中,ingress 有何作用?
在K8S中,ingress 有何作用?
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
2331 0

相关产品

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

    更多