我的目标如下:我在两个单独的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 /预测。同样,由于此路径问题,无法访问静态文件。
我不知道这是否是正确的方法?我也尝试过使用“重写目标”,但是还没有找到解决方案。
我希望有人可以向我解释我在做错什么。
答案 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引擎正确提供一些静态内容。