nginx 刷新上游服务器IP

use*_*984 7 nginx docker

我有一个 Docker 设置,其中包含一个 Django 容器和一个 nginx 服务静态文件。我以标准方式配置了 nginx:

upstream main_web {
    server web:8000;
}
server {
    location / {
        proxy_pass http://main_web;
        #...
    }

}
Run Code Online (Sandbox Code Playgroud)

我使用该/etc/hosts条目来获取 Django 容器的 IP 地址。

当我重新启动 Django 容器时,它的 IP 地址会更新,这会反映到hosts文件中。但是nginx一直502 Bad Gateway报错。当我手动重新启动 nginx 时,一切正常。

如果无法访问,是否有办法告诉 nginx 再次解析 IP?

小智 7

当您在proxy_pass指令中使用变量指定域名时,NGINX 会在其TTL 到期时重新解析域名。您必须包含解析器指令以明确指定名称服务器(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
Run Code Online (Sandbox Code Playgroud)

关于上述配置的一些事情,注意我没有在后端服务中添加容器名称,因此我可以自由扩展它。还要注意服务名称,我们将在 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

要测试这个:

  • docker-compose up -d
  • docker-compose scale my-backend-service=5
  • docker-compose 日志 -f 我的后端服务

现在您可以开始向localhostNginx发出请求,Nginx 将使用您指定的 DNS 解析器来获取后端服务的 IP 地址,并在 TTL 到期时重新解析域名。

  • 这很好。问题:“10s”对于 TTL 来说是一个合适的持续时间吗?我想如果它太短,它会发生得太频繁并减慢*某些事情*(什么?),而如果它太长,则会延长停机时间。从我的日志来看,我仍然有 [0-10] 秒的时间间隔,其中一些请求丢失。没有办法**强制“解析器”自行刷新**吗?这完全有道理...... (2认同)

小智 1

请参阅: http: //tenzer.dk/nginx-with-dynamic-upstreams/,了解使用 proxy_pass 设置中的变量让 nginx 重新解析 IP 的方法。

ha_proxy 1.6 的“运行时使用 DNS 进行服务器 IP 解析”功能也可以实现这一点。