TLDR:我正在寻找一种解决方案,该解决方案允许我根据它们的响应在两个不同的Kubernetes服务之间代理流量。
背景:我在Kubernetes上托管了一个退出的应用程序。最近,我开始重新编写我的微服务之一,以加快速度并添加一些新功能。我想让我的用户决定是要开始使用这项新服务还是坚持使用旧的服务(因为某些功能对其用例进行了重大更改)。由于用户通常使用诸如username.given-microservice.example.com之类的地址访问此微服务,因此我的最初计划是在这些服务之间建立一些代理,这可以使用以下查询来询问我的一个端点:http://my-new-service.example.com/enabled-for-client?=username
当然,来自上面URI的响应将取决于用户设置。
这种情况与A / B测试非常相似,但是我不知道并且很难找到任何基于URL响应来设置代理的方法。
[非常感谢您提供的任何建议,博客文章或文档链接,这些信息可以帮助我解决自己的情况,此刻,我用尽了所有想法,感到有些困惑。
[Envoy可以管理这种情况,首先查看HTTP routing。如果找不到所需的内容,则可以始终写filter/routing rules in Lua。
可以通过将NGINX Ingress与custom-http-errors
和default-backend
批注一起使用来实现。
我创建了一个实验室来证明这一概念。让我们一起探讨它。
首先,您必须在集群中安装NGINX Ingress。如果没有,请遵循installation guide。
在此POC上,我们将部署2个不同的应用程序。一个叫做old-http-backend,它提供默认的nginx登陆页面。第二个称为new-http-backend,它提供echo-server
登陆页面。
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-http-backend
spec:
selector:
matchLabels:
app: old-http-backend
template:
metadata:
labels:
app: old-http-backend
spec:
containers:
- name: old-http-backend
image: nginx
ports:
- name: http
containerPort: 80
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: old-http-backend
spec:
selector:
app: old-http-backend
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-http-backend
spec:
selector:
matchLabels:
app: new-http-backend
template:
metadata:
labels:
app: new-http-backend
spec:
containers:
- name: new-http-backend
image: inanimate/echo-server
ports:
- name: http
containerPort: 8080
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: new-http-backend
spec:
selector:
app: new-http-backend
ports:
- protocol: TCP
port: 80
targetPort: 8080
应用此清单后,我们将提供以下部署和服务:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
new-http-backend 1/1 1 1 2s
old-http-backend 1/1 1 1 43m
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.31.240.1 <none> 443/TCP 152m
new-http-backend ClusterIP 10.31.240.168 <none> 80/TCP 44m
old-http-backend ClusterIP 10.31.242.175 <none> 80/TCP 44m
现在我们可以应用Ingress来为我们做所有的魔术:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-app-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: "/"
nginx.ingress.kubernetes.io/custom-http-errors: '403,404,500,502,503,504'
nginx.ingress.kubernetes.io/default-backend: old-http-backend
spec:
rules:
- host: app.company.com
http:
paths:
- path: "/"
backend:
serviceName: new-http-backend
servicePort: 80
此入口在做什么?
在“自定义HTTP错误documentation中,我们无法读取,如果在入口处指定了default backend annotation,则错误将被路由到该注释的默认后端服务(而不是全局默认后端)。
因此,通过在我们的入口规则中插入这些注释,我们说所有请求都应发送到new-http-backend
,除非它收到custom-http-errors
上列出的返回码。如果发生这种情况,用户将被重定向到old-http-backend
注释上指定的default-backend
。
nginx.ingress.kubernetes.io/custom-http-errors: '403,404,500,502,503,504'
nginx.ingress.kubernetes.io/default-backend: old-http-backend