我有一个 Docker 设置,其中包含一个 Django 容器和一个提供静态文件的 nginx。我以标准方式配置了 nginx:
upstream main_web {
server web:8000;
}
server {
location / {
proxy_pass http://main_web;
#...
}
}
我使用该/etc/hosts
条目来获取 Django 容器的 IP 地址。
当我重新启动 Django 容器时,其 IP 地址会更新,这会反映到文件中hosts
。但 nginx 一直出错502 Bad Gateway
。当我手动重新启动 nginx 时,一切正常。
如果无法访问 IP,有没有办法告诉 nginx 再次解析 IP?
答案1
当你在指令中使用变量指定域名时proxy_pass
,NGINX 会在域名TTL 过期。您必须包含 resolver 指令以明确指定名称服务器(NGINX 未引用 /etc/resolv.conf)。更多详情
使用 Docker,您可以检查当前的 DNS 解析器并将其添加到 nginx 配置中。检查/etc/resolv.conf
。
例如,使用 docker-compose 您可以在 nginx vhost 配置中设置服务的名称。假设我们有以下设置:
docker-compose.yml
version: "3"
services:
my-backend-service: # we will use this name in our nginx vhost conf
image: some-image
lb:
image: nginx
volumes:
- ".docker/etc/nginx/default.conf:/etc/nginx/conf.d/default.conf"
ports:
- 80:80
关于上述配置,请注意,我没有向后端服务添加容器名称,因此我可以自由扩展它。还要注意服务名称,我们将在 Nginx vhost conf 中使用它,以便它通过 DNS 解析到实例 ip。最后,Nginx 监听端口 80,后端服务监听端口 8080(作为示例,可以是任何名称)
默认配置文件
resolver 127.0.0.11 valid=10s; # 127.0.0.1 comes from /etc/resolv.conf on the nginx container
server {
location / {
set $backend_servers my-backend-service;
proxy_pass http://$backend_servers:8080;
}
}
测试一下:
- docker-compose up -d
- docker-compose scale my-backend-service=5
- docker-compose 日志-f my-backend-service
现在您可以开始发出请求localhost
,Nginx 将使用您指定的 DNS 解析器来获取后端服务的 IP 地址,并在 TTL 过期时重新解析域名。
答案2
看:http://tenzer.dk/nginx-with-dynamic-upstreams/寻找一种方法来让 nginx 使用 proxy_pass 设置中的变量重新解析 IP。
使用 ha_proxy 1.6 的‘运行时使用 DNS 解析服务器 IP’功能也可以实现。