使用Kubernetes Ingress资源(nginx)在不同路径上的两个Flask应用

时间:2019-10-29 09:42:00

标签: nginx flask kubernetes kubernetes-ingress nginx-ingress

我的目标如下:我在两个单独的Docker容器中有两个Flask应用程序,我想通过同一IP地址上的不同路径访问它们,例如:127.0.0.1/app1,127.0.0.1/app2(但带有真实IP地址)。

我想用Kubernetes做到这一点。

我有一个正在运行的Kubernetes集群(Azure Kubernetes服务),为两个Docker容器中的每一个都提供了Deployment and Service。每个应用程序的pod运行正常。 我还在集群中安装了一个Ingress控制器(Nginx),现在我正试图使其与单个Ingress资源一起使用。

如果我按以下方式进行操作,则它可以完美地适用于1个单个应用程序(其中一个都可以在IP地址/上运行):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: service1 (or service2)
          servicePort: 5000

但是当我尝试以下操作时,它不起作用:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /app1
        backend:
          serviceName: service1 
          servicePort: 5000
      - path: /app2
        backend:
          serviceName: service2 
          servicePort: 5000

对于这两个应用程序,我可以看到Flask应用程序呈现的html页面,但它们的功能都不起作用。

除了路径似乎并不总是可以正常工作(当我尝试连接到IP-address / app1或IP-address / app1 /时,有时我重定向到IP-address /)以外,问题是以下(我认为):

每个Flask应用程序都有一个“ / predict”路由,该路由仅接受POST请求,并在其中发出对应用程序的相应调用(每个应用程序都是对给定输入进行预测的AI应用程序)。

两个应用程序的调用均基于IP地址/预测,而不是IP地址/ app1 /预测或IP地址/ app2 /预测。同样,由于此路径问题,无法访问静态文件。

我不知道这是否是正确的方法?我也尝试过使用“重写目标”,但是还没有找到解决方案。

我希望有人可以向我解释我在做错什么。

2 个答案:

答案 0 :(得分:0)

在入口资源中检查您的重写注释。您提出的任何请求都将被重写为/。这意味着,如果您呼叫 IP:80 / app1 ,您的容器将收到 IP:80 /

nginx.ingress.kubernetes.io/rewrite-target: /

如果您不希望发生这种情况,请删除该重写注释。您的进入将最终像这样:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  namespace: my-namespace
spec:
  rules:
  - http:
      paths:
      - path: /app1
        backend:
          serviceName: service1 
          servicePort: 5000
      - path: /app2
        backend:
          serviceName: service2 
          servicePort: 5000

您的容器将收到基于 / app1 / app2 的完整路径。

更新 检查这个例子。我有两个后端,它们在/上侦听并用您通过环境变量配置的数字来响应html。

---
apiVersion: v1
kind: Service
metadata:
  name: backend1
  namespace: default
  labels:
    mojix.service: backend1
spec:
  ports:
  - name: "8000"
    port: 8000
    targetPort: 8000
  selector:
    mojix.service: backend1
status:
  loadBalancer: {}

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  labels:
    mojix.service: backend1
  name: backend1
spec:
  replicas: 1
  selector:
    matchLabels:
      mojix.service: backend1
  template:
    metadata:
      creationTimestamp: null
      labels:
        mojix.service: backend1
    spec:
      containers:
      - name: backend1
        image: lozuwa/number_backend:latest
        env:
          - name: BACKEND_NUMBER
            value: "1"
      hostname: backend1
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: backend2
  namespace: default
  labels:
    mojix.service: backend2
spec:
  ports:
  - name: "8000"
    port: 8000
    targetPort: 8000
  selector:
    mojix.service: backend2
status:
  loadBalancer: {}

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  labels:
    mojix.service: backend2
  name: backend2
spec:
  replicas: 1
  selector:
    matchLabels:
      mojix.service: backend2
  template:
    metadata:
      creationTimestamp: null
      labels:
        mojix.service: backend2
    spec:
      containers:
      - name: backend2
        image: lozuwa/number_backend:latest
        env:
          - name: BACKEND_NUMBER
            value: "2"
      hostname: backend2
      restartPolicy: Always

我有以下入口。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: vizix-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /app1
        backend:
          serviceName: backend1
          servicePort: 8000
      - path: /app2
        backend:
          serviceName: backend2
          servicePort: 8000

如果您击中IP/app1,您将得到Response from 1;如果您击中IP/app2,您将得到Response from 2。我的容器监听/,这就是为什么我需要重写的原因。您的应用程序期望什么路径?

答案 1 :(得分:0)

您可以考虑完全在Ingress清单中提供capture groups,并指定特定的正则表达式来定义源Nginx rewrite规则。

在对真实的Ingress清单进行一些调整之后,我希望它能够按预期运行:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - path: /app1(/|$)(.*)
        backend:
          serviceName: service1 
          servicePort: 5000
      - path: /app2(/|$)(.*)
        backend:
          serviceName: service2 
          servicePort: 5000

可能还需要在目标URL中添加Trailing slash,以指示Nginx引擎正确提供一些静态内容。