更新 2。我想添加并转发所有流量到localhost/admin/
而不是localhost/
。
- 应用程序监听这些路径:
localhost/
(然后应用程序获取 302localhost/login
),localhost/overview
,localhost/books/details
, ETC。
- 我希望管理员用户使用这些 URL:
localhost/admin/
(通过应用程序获取 302localhost/admin/login
)localhost/admin/overview
localhost/admin/books/details
- 使用我的反向代理(见下文):
localhost/admin/
(我localhost/login
通过应用程序获得 302)
,
我也可以用来ingrees-nginx-controller
代替安装文件。
在docker nginx.conf中(或类似于k8s)
server {
listen 80 default_server;
listen [::]:80 default_server;
...
location /admin {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host/admin;
proxy_pass http://<conteiner2>.docker-network;
}
...
}
更新1
对于 kubernetes,我正在尝试设置ingress-nginx
为此,我安装了ingress-nginx-controller
并使用以下 YAML 设置ingress-nginx
:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Host $host";
more_set_headers "X-Real-IP $remote_addr";
more_set_headers "X-Forwarded-For $proxy_add_x_forwarded_for";
more_set_headers "X-Forwarded-Proto $scheme";
more_set_headers "X-Forwarded-Host $host/admin";
name: test-ingress
namespace: <namespace>
spec:
rules:
- http:
paths:
- path: /admin
backend:
serviceName: <app1>-admin
servicePort: 8002
答案1
因此,这里有几件事要发生;最重要的是:
proxy_set_header X-Forwarded-Host $host/admin;
proxy_pass http://<conteiner2>.docker-network;
是不正确的,因为x-forwarded-HOST
不应该包含乌里,正如您所看到的/admin
:它应该只是$host
;您真正想要的是更新proxy_pass
以包含,$request_uri
正如您可以观察到的那样,在使用 nginx Ingress 控制器时生成的 nginx.conf 会这样做。等待位置的 URI/admin
以及位置中匹配的任何其他内容将按预期向上游传递:
proxy_set_header X-Forwarded-Host $host;
proxy_pass http://<conteiner2>.docker-network$request_uri;
# or you're free to hard-code /admin if you prefer:
proxy_pass http://<conteiner2>.docker-network/admin;
其次,如果您遇到想要将一些configuration-snippet:
应用于一个 URI 但不想同时应用于它们的情况,则将两个路由分成两个单独的 Ingress 资源,以便可以独立管理它们:
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
# this one just applies to /api
name: test-ingress-api
spec:
rules:
- http:
paths:
- path: /api
backend:
serviceName: <app2>-api
servicePort: 8000
---
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
# this one just applies for /admin
name: test-ingress-admin
spec:
rules:
- http:
paths:
- path: /admin
backend:
serviceName: <app1>-admin
servicePort: 8002
关于如何调试 nginx 代理,有什么想法吗?
有两种很好的方法:首先,获取生成的 nginx.conf 并通读它以查看您期望发生的情况以及实际发生的情况:
kubectl cp ${the_nginx_controller_pod}:/etc/nginx/nginx.conf ingress-nginx.conf
另一种方法是转动nginx 日志级别(debug
如果您尝试在生产环境中进行调试,这可能会有问题,因为它会生成大量的文本,但它几乎肯定会对您要调试的内容提供实际答案):
# the ConfigMap may be named differently in your setup:
$ kubectl edit configmap nginx-ingress-controller
# and add:
data:
error-log-level: debug
# then wait a few seconds for nginx to notice the configmap change
# and if it doesn't, kill the controller pods to force the reload