我们在 docker swarm 中使用 NGINX 作为反向代理。 NGINX 位于覆盖网络中,并将外部请求中继到相关的群服务。
但是我们有一个问题,每次我们重新启动/更新或以其他方式关闭集群服务时,NGINX 都会返回
502 Bad Gateway
。然后 NGINX 继续服务 502
即使在服务重新启动后,这也没有得到纠正,直到我们重新启动 NGINX 服务,这显然违背了在多个地方运行负载均衡器和服务的全部要点。
这是我们的 NGINX CONF:
events {}
http {
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
client_max_body_size 20M;
large_client_header_buffers 8 256k;
client_header_buffer_size 256k;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
map $host $client {
default clientname;
}
#Healthcheck
server {
listen 443;
listen 444;
location /is-healthy {
access_log off;
return 200;
}
}
#Example service:
server {
listen 443;
server_name scheduler.clientname.com;
location / {
resolver 127.0.0.11 ipv6=off;
proxy_pass http://$client-scheduler:60911;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
#catchll
server {
listen 443;
listen 444;
server_name _;
location / {
return 404 'Page not found';
}
}
}
我们使用 $client 占位符,否则当其中一项服务关闭时我们甚至无法启动 nginx。
另一种选择是使用具有健康检查的上游指令,这可以很好地工作。问题在于,如果任何服务不可用,NGINX 甚至都不会启动!
我们做错了什么?
更新 看来我们在这里想要的是不可能的(尽管请证明我错了!)。在 docker 和微服务的世界中错过这样的功能似乎很疯狂!
我们目前正在寻找 HAPROXY 作为替代方案,因为它可以通过
default-server init-addr none
设置来阻止启动失败。
我是这样做的,创建一个 max_fails=0 的上游
upstream docker-api {
server docker.api:80 max_fails=0;
}
# load configs
server {
listen 80;
listen [::]:80;
server_name localhost;
location /api {
proxy_pass http://docker-api;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
# Others config...
}
}
我在使用 docker-compose 时遇到了同样的问题。
docker-compose restart
后Nginx容器无法连接web服务。
最后我弄清楚了导致这个故障的两种情况。首先,
docker-compose restart
不遵循 depends_on 应该在 web 重启后重启 nginx。第二,docker-compose restart
重新分配一个新的内部IP地址给容器,nginx启动后不刷新Web IP地址。
我的解决方案是定义一个变量来强制 nginx 每次解析 IP:
location /api {
set $web_service "http://web_container_name:13579";
proxy_pass $web_service;
}