路径上的应用程序而不是root不适用于Kubernetes Ingress [英] app on path instead of root not working for Kubernetes Ingress

查看:111
本文介绍了路径上的应用程序而不是root不适用于Kubernetes Ingress的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用K8s Ingress时遇到问题,在这里我将使用伪造的示例来说明我的观点. 假设我有一个名为Tweeta的应用程序,而我的公司名为ABC.我的应用程序当前位于tweeta.abc.com. 但是我们想将我们的应用程序迁移到app.abc.com/tweeta.

I have an issue at work with K8s Ingress and I will use fake examples here to illustrate my point. Assume I have an app called Tweeta and my company is called ABC. My app currently sits on tweeta.abc.com. But we want to migrate our app to app.abc.com/tweeta.

我目前在K8s中的进入情况如下:

My current ingress in K8s is as belows:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress
spec:
  rules:
  - host: tweeta.abc.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /api
        backend:
          serviceName: tweeta-backend
          servicePort: 80

对于迁移,我添加了第二个入口:

For migration, I added a second ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress-v2
spec:
  rules:
  - host: app.abc.com
    http:
      paths:
      - path: /tweeta
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /tweeta/api
        backend:
          serviceName: tweeta-backend
          servicePort: 80

为了连续性,我想同时有2个入口指向我的服务.当新域准备就绪并可以正常工作时,我只需要拆除旧的入口即可.

For sake of continuity, I would like to have 2 ingresses pointing to my services at the same time. When the new domain is ready and working, I would just need to tear down the old ingress.

但是,在这次入侵中,我对新域并没有任何运气.是因为它托管在路径上,而k8s入口需要托管在根目录上吗?还是我需要在Nginx端进行配置?

However, I am not getting any luck with the new domain with this ingress. Is it because it is hosted on a path and the k8s ingress needs to host on root? Or is it a configuration I would need to do on the nginx side?

推荐答案

我假设您的前端Pod期望路径/,而后端Pod期望路径/api

I assume your frontend Pod expects the path / and backend Pod expects the path /api

第一个入口配置不会转换请求,它会按原样转到前端(Fpod)/后端(Bpod)Pod:

The first ingress config doesn't transform the request and it goes to the frontend(Fpod)/backend(Bpod) Pods as is:

http://tweeta.abc.com/     -> ingress -> svc -> Fpod: [ http://tweeta.abc.com/    ] 
http://tweeta.abc.com/api  -> ingress -> svc -> Bpod: [ http://tweeta.abc.com/api ] 

但第二次进入后无法正常工作:

but with second ingress it doesn't work as expected:

http://app.abc.com/tweeta      -> ingress -> svc -> Fpod: [ http://app.abc.com/tweeta    ] 
http://app.abc.com/tweeta/api  -> ingress -> svc -> Bpod: [ http://app.abc.com/tweeta/api    ] 

Pod请求路径从/更改为/tweeta,从/api更改为/tweeta/api.我想这不是预期的行为.通常,Pods中的应用程序不关心Host标头,但Path必须正确.如果您的Pod并非旨在响应其他tweeta\路径,则在使用第二个入口时,它们可能会以404 (Not Found)响应.

The Pod request path is changed from / to /tweeta and from /api to /tweeta/api. I guess it's not the expected behavior. Usually application in Pods doesn't care about Host header but Path must be correct. If your Pods aren't designed to respond to additional tweeta\ path, they likely respond with 404 (Not Found) when the second ingress is used.

要修复此问题,您必须添加重写注释从Pod的请求中删除tweeta路径:

To fix it you have to add rewrite annotation to remove tweeta path from the Pods' request:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress-v2
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: app.abc.com
    http:
      paths:
      - path: /tweeta(/|$)(.*)
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /tweeta(/)(api$|api/.*)
        backend:
          serviceName: tweeta-backend
          servicePort: 80

结果将如下所示,这正是它应该工作的方式:

The result will be as follows, which is exactly how it suppose to work:

http://app.abc.com/tweeta            -> ingress -> svc -> Fpod: [ http://app.abc.com/    ] 
http://app.abc.com/tweeta/blabla     -> ingress -> svc -> Fpod: [ http://app.abc.com/blabla    ] 

http://app.abc.com/tweeta/api        -> ingress -> svc -> Bpod: [ http://app.abc.com/api    ] 
http://app.abc.com/tweeta/api/blabla -> ingress -> svc -> Bpod: [ http://app.abc.com/api/blabla    ] 

要检查入口控制器日志和配置,请相应地使用:

To check ingress-controller logs and configuration use accordingly:

$ kubectl logs -n ingress-controller-namespace ingress-controller-pods-name

$ kubectl exec -it -n ingress-controller-namespace ingress-controller-pods-name -- cat /etc/nginx/nginx.conf > local-file-name.txt && less local-file-name.txt

这篇关于路径上的应用程序而不是root不适用于Kubernetes Ingress的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆