使用Kubernetes Ingress来实现类似Istio条件路由

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 微服务 Istio / SpringCloud日益被越来越多的客户关注,Istio提供了各种酷炫的流量控制功能,但Istio距离生产部署可用仍然还有差距。条件路由是否可以在已有的Kubernetes Ingress架构中实现,以最小的代价实现应用的微服务化迁移。答案是肯定的,通过对ingress自定义location/server块的定义,以及upsteam自动生产的规则,可以实现复杂条件路由

微服务 Istio / SpringCloud日益被越来越多的客户关注,Istio提供了各种酷炫的流量控制功能,但Istio距离生产部署可用仍然还有差距。条件路由是否可以在已有的Kubernetes Ingress架构中实现,以最小的代价实现应用的微服务化迁移。答案是肯定的,通过对ingress自定义location/server块的定义,以及upsteam自动生产的规则,可以实现复杂条件路由的支持,类似istio, match。


[不满足] 1. 尝试一, 修改Ingress的server-snippet/location-snippet属性来重定向请求到后台服务, 不能按期望跳转

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/load-balance: ip_hash
    nginx.ingress.kubernetes.io/server-snippet: |
      set $agentflag 0;


      if ($http_user_agent ~* "(Mobile)" ){
        set $agentflag 1;
      }


     if ( $agentflag = 1 ) {
      .  return 301 http://default-cardinfo-homepage-80;
     }
    nginx.ingress.kubernetes.io/upstream-hash-by: ip_hash
    nginx.ingress.kubernetes.io//location-snippet: |
                  if ( $agentflag = 1 ) {
                     proxy_pass http://default-cardinfo-homepage-80;
                  }
  creationTimestamp: 2018-08-27T12:06:32Z
  generation: 2
  name: nginx-test
  namespace: default
  resourceVersion: "43290755"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/nginx-test
  uid: a310ca06-a9f1-11e8-a613-00163e0c87f1
spec:
  rules:
  - host: stickyingress.example.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /
  - host: mobile.example.com
    http:
      paths:
      - backend:
          serviceName: cardinfo-homepage
          servicePort: 80
        path: /
status:
  loadBalancer:
    ingress:
    - {}

检查ingressController自动生成的nginx server定义, 仅仅依靠server-snippet 以及location-snippet是不能完成请求的自动跳转。server-snippet at ingress level does not work for reverse proxy server-snippet spec

[不满足] 尝试二, 使用IngressController级别的定义 location-snippet, location-snippet会传播到所有的location-block, 不满足期望。

location-snippet of ingress controller is applied to all location block, it does not work as expected

location-snippet

apiVersion: v1
data:
  location-snippet: |
    if ( $agentflag = 1 ) {
                     proxy_pass http://default-cardinfo-homepage-80;
     }
  proxy-body-size: 20m
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"proxy-body-size":"20m"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"ingress-nginx"},"name":"nginx-configuration","namespace":"kube-system"}}
  creationTimestamp: 2018-02-07T09:06:33Z
  labels:
    app: ingress-nginx
  name: nginx-configuration
  namespace: kube-system
  resourceVersion: "43308775"
  selfLink: /api/v1/namespaces/kube-system/configmaps/nginx-configuration
  uid: 312dd92f-0be6-11e8-856b-00163e0c87f1

[解决] 尝试三, 使用configuration-snippet + server-snippet + upstream default name 来实现路由跳转到不同的kubernetes service服务。

configuration-snippet is alternative of location snippet, combination configuration-snippet and server-snippet to parse header, set global variable, then proxy specific backend service with upstream name created by IngressController. e.g. default-cardinfo-homepage-80

metadata:
  annotations:
     nginx.ingress.kubernetes.io/server-snippet: |
      set $agentflag 0;

      if ($http_user_agent ~* "(Mobile)" ){
        set $agentflag 1;
      }
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ( $agentflag = 1 ) {
         proxy_pass http://default-cardinfo-homepage-80;
      }

Put everything together

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/load-balance: ip_hash
    nginx.ingress.kubernetes.io/server-snippet: |
      set $agentflag 0;

      if ($http_user_agent ~* "(Mobile)" ){
        set $agentflag 1;
      }
    nginx.ingress.kubernetes.io/upstream-hash-by: ip_hash
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ( $agentflag = 1 ) {
         proxy_pass http://default-cardinfo-homepage-80;
      }
  name: nginx-condition
  namespace: default
spec:
  rules:
  - host: stickyingress.example.com
    http:
      paths:
      - backend:
          serviceName: cardinfo-recommendation
          servicePort: 80
        path: /
  - host: mobile.example.com
    http:
      paths:
      - backend:
          serviceName: cardinfo-homepage
          servicePort: 80
        path: /
status:
  loadBalancer:
    ingress:
    - {}

测试

使用不同的Header 模拟不同用户浏览器请求,用户请求根据浏览器的类型被重定向到不同的后台服务和入口。以stickyingress.example.com为入口的用户使用"user-agent: (Mobile)"的用户,自动跳转到后台服务cardinfo-homepage,其他用户仍然进入cardinfo-recommendation。

curl stickyingress.example.com:32619 -v
* Rebuilt URL to: stickyingress.example.com:32619/
* Hostname was NOT found in DNS cache
*   Trying 192.168.33.239...
* Connected to stickyingress.example.com (192.168.33.239) port 32619 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.37.0
> Host: stickyingress.example.com:32619
> Accept: */*
>
< HTTP/1.1 200
* Server nginx/1.13.7 is not blacklisted
< Server: nginx/1.13.7
< Date: Wed, 14 Nov 2018 04:46:19 GMT
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 17
< Connection: keep-alive
<
* Connection #0 to host stickyingress.example.com left intact
recommendation v2

dns:~ # curl stickyingress.example.com:32619 -v -H "user-agent: (Mobile)"

* Rebuilt URL to: stickyingress.example.com:32619/
* Hostname was NOT found in DNS cache
*   Trying 192.168.33.239...
* Connected to stickyingress.example.com (192.168.33.239) port 32619 (#0)
> GET / HTTP/1.1
> Host: stickyingress.example.com:32619
> Accept: */*
> user-agent: (Mobile)
>
< HTTP/1.1 200
* Server nginx/1.13.7 is not blacklisted
< Server: nginx/1.13.7
< Date: Wed, 14 Nov 2018 04:46:31 GMT
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 26
< Connection: keep-alive
< Vary: Accept-Encoding
<
* Connection #0 to host stickyingress.example.com left intact
OK. Vist /cardinfo please.

Conclusion 总结

使用Ingress的自定义location/server block,以及upstream的隐含定义,依然可以实现类似Istio的自动流量路由功能,后台Pod出现更新升级并不会影响到条件跳转。 用户可以使用最小的代价通过Kubernetes Ingress实现ABTest,灰度,流量路由,并且享受到Kubernetes服务发现,和滚动更新带来的优势。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
Kubernetes 负载均衡 应用服务中间件
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
595 1
|
5天前
|
Kubernetes 应用服务中间件 nginx
Kubernetes上安装Metallb和Ingress并部署应用程序
Kubernetes上安装Metallb和Ingress并部署nginx应用程序,使用LoadBalancer类型的KubernetesService
32 2
|
23天前
|
Kubernetes 应用服务中间件 API
【Ingress 秘籍】集群进出流量的总管:揭秘 Kubernetes 中 Ingress 的终极奥秘!
【8月更文挑战第25天】Ingress是Kubernetes中用于管理HTTP与HTTPS流量进入集群的核心功能。作为集群内外通信的桥梁,Ingress通过定义规则将外部请求导向内部服务。本文详细介绍了Ingress的基本概念、配置方法及其实现方式。通过使用不同的Ingress控制器(如Nginx、Traefik等),用户可以根据需要选择最适合的方案。文中还提供了示例代码展示如何创建服务、部署应用及配置Ingress规则。
49 6
|
29天前
|
Kubernetes 负载均衡 应用服务中间件
在k8S中,ingress是什么?
在k8S中,ingress是什么?
|
17天前
|
API UED 开发者
超实用技巧大放送:彻底革新你的WinForms应用,从流畅动画到丝滑交互设计,全面解析如何在保证性能的同时大幅提升用户体验,让软件操作变得赏心悦目不再是梦!
【8月更文挑战第31天】在Windows平台上,使用WinForms框架开发应用程序时,如何在保持性能的同时提升用户界面的吸引力和响应性是一个常见挑战。本文探讨了在不牺牲性能的前提下实现流畅动画与交互设计的最佳实践,包括使用BackgroundWorker处理耗时任务、利用Timer控件创建简单动画,以及使用Graphics类绘制自定义图形。通过具体示例代码展示了这些技术的应用,帮助开发者显著改善用户体验,使应用程序更加吸引人和易于使用。
36 0
|
29天前
|
Kubernetes API 网络安全
在K8S中,ingress该如何使用?
在K8S中,ingress该如何使用?
|
23天前
|
存储 Kubernetes Go
【Azure K8S | AKS】在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例
【Azure K8S | AKS】在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例
|
14天前
|
存储 Kubernetes 负载均衡
CentOS 7.9二进制部署K8S 1.28.3+集群实战
本文详细介绍了在CentOS 7.9上通过二进制方式部署Kubernetes 1.28.3+集群的全过程,包括环境准备、组件安装、证书生成、高可用配置以及网络插件部署等关键步骤。
95 3
CentOS 7.9二进制部署K8S 1.28.3+集群实战
|
14天前
|
Kubernetes 负载均衡 前端开发
二进制部署Kubernetes 1.23.15版本高可用集群实战
使用二进制文件部署Kubernetes 1.23.15版本高可用集群的详细教程,涵盖了从环境准备到网络插件部署的完整流程。
29 2
二进制部署Kubernetes 1.23.15版本高可用集群实战
|
14天前
|
存储 Kubernetes 测试技术
k8s使用pvc,pv,sc关联ceph集群
文章介绍了如何在Kubernetes中使用PersistentVolumeClaim (PVC)、PersistentVolume (PV) 和StorageClass (SC) 来关联Ceph集群,包括创建Ceph镜像、配置访问密钥、删除默认存储类、编写和应用资源清单、创建资源以及进行访问测试的步骤。同时,还提供了如何使用RBD动态存储类来关联Ceph集群的指南。
29 7