如何使用 nginx-ingress proxy_pass?

How to proxy_pass with nginx-ingress?

我想设置一个 k8s 集群,但我对 nginx-ingress 控制器和一些我需要设置的特殊设置感到绝望:尤其是 proxy_pass。

我已经尝试使用 "server-snippet"-snippet 实现这一点,但没有成功。

apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
kind: Ingress
metadata:
    name: ingress
    annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/affinity: "cookie"
        nginx.ingress.kubernetes.io/session-cookie-name: "route"
        nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
        nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
        nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/hsts: "false"
        nginx.ingress.kubernetes.io/server-snippet: |
            location / {
                internal;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_buffering off;

                proxy_pass http://localhost:30022/site/;
                proxy_redirect default;
                proxy_cookie_path /site/ /;
            }
spec:
    rules:
        - host: preview.test.de
          http:
              paths:
                  - path: /
                    backend:
                        serviceName: backend-service
                        servicePort: 8080

我想要实现的是这个nginx配置:

location / {
                internal;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_buffering off;

                proxy_pass http://localhost:30022/site/;
                proxy_redirect default;
                proxy_cookie_path /site/ /;
            }

在理想情况下,我希望 proxy_pass 指令中的主机和端口取决于我要连接的后端 pod,因此没有硬编码端口。

谁能帮我解决这个问题?

我相信你要找的是:

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

然而,这实际上意味着您只能将这个特定的入口实例用于这个应用程序或其他类似应用程序,因为此重写将适用于该入口实例的所有规则。

您也许可以使用基于正则表达式的规则来完成同样的事情,但这种方法肯定更简单。

关于您关于如何处理需要重写的两个不同路径的问题,这应该可以通过以下入口配置实现:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
    name: ingress
    annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/use-regex: true
spec:
    rules:
        - host: preview.test.de
          http:
              paths:
                  - path: /(site/.*)
                    backend:
                        serviceName: backend-service
                        servicePort: 8080
                  - path: /(cms/.*)
                    backend:
                        serviceName: cms-service
                        servicePort: 8080

然而,正如您可能猜到的那样,如果您最终拥有许多路径并在以后进行大量重写,这可能会变得更加困难。

至于配置此类设置的最佳实践,我通常建议采用子域。为每个 site/path 您希望可以访问的人设置一个,并让他们有自己独特的 nginx/ingress/etc 来根据需要处理他们的重写。然后,如果您想稍后将它们绑定到其他顶层 domain/site,这很容易完成,并且不必在一个位置管理许多重写规则,这可能会变得非常混乱。