我已经在集群上安装了nginx入口。这里是yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-client
annotations:
kubernetes.io/ingress.class: nginx
namespace: dev
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: client-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
当我点击/前缀时,它是好的。curl http://example.com (All Good)
问题:
但是当我点击/api前缀时,它返回服务的/api而不是服务的/
curl http://example.com/api(它应该链接到api-service(但它链接到api-service/api)
任何帮助将不胜感激!
这是因为类型为Prefix
的路径/
将匹配/
及其之后的所有内容,包括/api
。所以你的第一条规则在某种意义上掩盖了第二条规则。
我不知道这是否适合您,但是为两个服务使用不同的主机名可能是最优雅和最习惯的。如果您部署了cert-manager,这应该不是问题。
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: client-service
port:
number: 80
# use a different hostname for the api
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
另一个选择是在前端路径规则中使用regex。当斜杠后面跟api时,让它不匹配。为此,您需要设置一个注释。
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
那么你可以为你的前端服务做如下的事情。使用反向向前看
- path: /(?!api).*
或者,但不太漂亮,你可以添加一个路径前缀到你的前端服务,并通过路径重写注释删除它。但是,您可能需要编写两个单独的入口清单,因为这是对两者的注释计数,或者您需要使用更复杂的路径重写规则。
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
- path: /ui(/|$)(.*)
也许将更具体的路由/api
移动到通用的/
路由之前也足够了。在这种情况下,切换列表中的路径。如果它们在nginx配置中以这个顺序结束,nginx应该能够按需要处理它。
你可以使用nginx.ingress.kubernetes.io/rewrite-target:
在某些场景中,后端服务中公开的URL与Ingress规则中指定的路径不同。如果不重写,任何请求都将返回404。设置注释nginx.ingress.kubernetes。Io/rewrite-target到服务期望的路径
那么,这里你可以把你的入口改为next:
metadata:
name: ingress-client
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
namespace: dev
上面的入口定义将导致以下重写:
api-service/api
重写为api-service/