基于服务器响应的kubernetes中的条件反向代理

问题描述 投票:1回答:2

TLDR:我正在寻找一种解决方案,该解决方案允许我根据它们的响应在两个不同的Kubernetes服务之间代理流量。

背景:我在Kubernetes上托管了一个退出的应用程序。最近,我开始重新编写我的微服务之一,以加快速度并添加一些新功能。我想让我的用户决定是要开始使用这项新服务还是坚持使用旧的服务(因为某些功能对其用例进行了重大更改)。由于用户通常使用诸如username.given-microservice.example.com之类的地址访问此微服务,因此我的最初计划是在这些服务之间建立一些代理,这可以使用以下查询来询问我的一个端点:http://my-new-service.example.com/enabled-for-client?=username

  • 如果返回代码200,则客户端将被转发到新服务
  • 如果响应代码是其他任何内容,那么客户端将被转发到旧服务。

当然,来自上面URI的响应将取决于用户设置。

这种情况与A / B测试非常相似,但是我不知道并且很难找到任何基于URL响应来设置代理的方法。

[非常感谢您提供的任何建议,博客文章或文档链接,这些信息可以帮助我解决自己的情况,此刻,我用尽了所有想法,感到有些困惑。

kubernetes reverse-proxy
2个回答
0
投票

[Envoy可以管理这种情况,首先查看HTTP routing。如果找不到所需的内容,则可以始终写filter/routing rules in Lua


0
投票

可以通过将NGINX Ingress与custom-http-errorsdefault-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
© www.soinside.com 2019 - 2024. All rights reserved.