如何解决带有位置正则表达式的代理传递到 docker 容器
在我的应用程序中,我在同一个 docker 网络中使用了 N 个节点(在下面的示例中为 3 个)。
项目的 docker-compose 如下所示:
version: "3.7"
networks:
my-network:
name: my-network
services:
my-node0:
container_name: node0
image: myimage
build:
context: $PWD/
dockerfile: Dockerfile
ports:
- "8080:8080"
- "9090:9090"
networks:
my-network:
aliases:
- my-node-0
my-node1:
container_name: node1
image: myimage
build:
context: $PWD/
dockerfile: Dockerfile
ports:
- "8081:8080"
- "9091:9090"
networks:
my-network:
aliases:
- my-node-1
my-node2:
container_name: node2
image: myimage
build:
context: $PWD/
dockerfile: Dockerfile
ports:
- "8082:8080"
- "9092:9090"
networks:
my-network:
aliases:
- my-node-2
nginx:
image: nginx:latest
networks:
my-network:
aliases:
- nginx
container_name: my-nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- 3080:80
frontend:
container_name: my-frontend
image: node
build:
context: $PWD/frontend
dockerfile: Dockerfile
ports:
- "3002:3000"
stdin_open: true
environment:
- CHOKIDAR_USEPOLLING=true
external_links:
- my-node-0
networks:
my-network:
aliases:
- my-frontend
command: npm start
我使用 nginx 来帮助我的浏览器通过 docker 网络别名进行导航。 每个节点运行 2 个不同的应用程序,一个在端口 8080 上,一个在端口 9090 上,从现在开始我将它们称为“第一”和“第二”。 以前我使用过这样的 nginx 配置,它的作用就像一个魅力:
events {}
http {
server {
listen 80;
server_name localhost;
location /node0-first {
proxy_pass http://my-node-0:8080/;
proxy_pass_request_headers on;
}
location /node0-second{
proxy_pass http://my-node-0:9090/;
proxy_pass_request_headers on;
}
location /node1-first {
proxy_pass http://my-node-1:8080/;
proxy_pass_request_headers on;
}
location /node1-second{
proxy_pass http://my-node-1:9090/;
proxy_pass_request_headers on;
}
location /node2-first{
proxy_pass http://my-node-2:8080/;
proxy_pass_request_headers on;
}
location /node2-second{
proxy_pass http://my-node-2:9090/;
proxy_pass_request_headers on;
}
}
}
显然,如果有一天我想添加,假设有 1000 个节点,我不想在配置中再添加 2000 个位置块。这是当我遇到在这些位置使用正则表达式的可能性时 我有以下不工作的 nginx 配置:
events {}
http {
server {
listen 80;
server_name localhost;
##first application
location ~ ^/node(?<node_number>\d+)-first {
proxy_pass http://my-node-$node_number:8080/;
proxy_pass_request_headers on;
}
##second application
location ~ ^/node(?<node_number>\d+)-second {
proxy_pass http://my-node-$node_number:9090/
proxy_pass_request_headers on;
}
##testing dynamic rooting
location ~ ^/test(?<test_number>\d+)$ {
return 200 "/test$test_number";
}
}
}
测试路线告诉我,我并没有完全走错路,因为它有效。输入 http://localhost:3080/test12 会返回一个带有 docker 日志的“/test12”:
<IP ADDR> - - [<TIME>] "GET /test12 HTTP/1.1" 200 7 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/90.0.4430.93 Safari/537.36"
但是,向我的节点之一上的现有端点发送请求会导致:
<DATE> <TIME> [error] 31#31: *3 no resolver defined to resolve my-node-1,client: <IP ADDR>,server: localhost,request: "GET /<MY WORKING ENDPOINT> HTTP/1.1",host: "localhost:3080"
<IP ADDR> - - [<TIME>] "GET /<MY WORKING ENDPOINT> HTTP/1.1" 502 560 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/90.0.4430.93 Safari/537.36"
试图寻找一个答案,这使我找到了一个可能的解决方案,在该解决方案中我定义了上游块中的每个节点,但我可以只做位置块,这不是我想要的。
比我尝试在末尾添加位置正则表达式和额外的“$”(我认为正则表达式的结尾,正则表达式相当新),这导致了以下糟糕的结果:
<DATE> <TIME> [error] 31#31: *1 open() "/etc/nginx/html/node1-second/<MY WORKING ENDPOINT>" failed (2: No such file or directory),request: "GET /node1-second/<MY WORKING ENDPOINT> HTTP/1.1",host: "localhost:3080"
<IP ADDR> - - [<TIME>] "GET /node1-second/<MY WORKING ENDPOINT> HTTP/1.1" 404 556 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/90.0.4430.93 Safari/537.36"
我在这里假设,由于 nginx 找不到端点(出于某种原因),它试图提供静态内容,而这显然不存在。
现在的问题是:是否可以通过这种方式动态使用代理传递,如果可以,我做错了什么?
编辑
如果有人遇到同样的问题,我设法这样做了:
events {}
http {
server {
listen 80;
server_name localhost;
resolver 127.0.0.11 ipv6=off;
#first application
location ~ ^/node(?<node_number>\d+)-first/(.*)$ {
proxy_pass http://my-node-$node_number:8080/$2;
proxy_pass_request_headers on;
}
#second applicaton
location ~ ^/node(?<node_number>\d+)-second/(.*)$ {
proxy_pass http://my-node-$node_number:9090/$2;
proxy_pass_request_headers on;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。