带有动态容器的 Nginx 反向代理

Posted

技术标签:

【中文标题】带有动态容器的 Nginx 反向代理【英文标题】:Nginx Reverse Proxy with Dynamic Containers 【发布时间】:2019-01-12 22:31:52 【问题描述】:

我有一个使用 docker compose 设置的带有 nginx 的反向代理。当我与docker-compose up 一起运行所有服务时,它可以正常工作。但是,我希望能够运行单个容器,并独立于代理容器启动 (docker-compose up service1) 和停止它们。这是我当前 nginx 配置中的一个 sn-p:

server 
  listen 80;

  location /service1/ 
    proxy_pass http://service1/;
  

  location /service2/ 
    proxy_pass http://service2/;
  

现在,如果我同时运行 service1、service2 和代理,一切都很好。但是,如果我运行代理并且只运行 service2,例如,我会收到以下错误:host not found in upstream "service1" in /etc/nginx/conf.d/default.conf:13。我在这里想要的行为是抛出一些 HTTP 错误,然后当该服务出现时适当地路由到它。

有没有办法得到这种行为?

【问题讨论】:

标准指令无法做到这一点。也许如果你添加 Lua 模块,你可以编写一个脚本,但不确定那个。 【参考方案1】:

您的问题与 nginx 有关。如果无法解析上游主机名之一,它将无法启动。

在您的情况下,如果服务未启动,则 docker 服务名称将无法解析。

尝试here 的解决方案之一,例如在位置级别解决。


(编辑)以下示例适用于我:

events 
  worker_connections  4096;


http 
  server 
    location /service1 
        resolver 127.0.0.11;
        set $upstream http://service1:80;
        proxy_pass    $upstream;
    

    location /service2 
        resolver 127.0.0.11;
        set $upstream2 http://service2:80;
        proxy_pass    $upstream2;
    
  

【讨论】:

我试过这个。我最初遇到错误no resolver defined to resolve ...。将解析器设置为 127.0.0.11 可以解决此问题。但是,它不能正常工作。使用配置:set $upstream service; proxy_pass http://$upstream/; 无论我去什么网址,我都只能请求索引(/)。但是,如果我只使用proxy_pass http://service/;,它就可以正常工作(只要服务在代理之前启动,这是我想要避免的)。 @JohnHoward 我已经更新了配置——这个版本似乎对我有用。即使 service1 或 service2 没有启动,nginx 也会启动。 您还可以通过在 location 指令中包含 rewrite url 规则来请求您喜欢的任何上游 url(不仅仅是 /)。【参考方案2】:

听起来您需要使用负载平衡。我相信通过负载平衡,它将尝试在服务器/服务之间共享负载。如果一个发生故障,它应该自动使用其他的。

例子

http 
    upstream myapp1 
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    

    server 
        listen 80;
        location / 
            proxy_pass http://myapp1;
        
    

文档:http://nginx.org/en/docs/http/load_balancing.html

【讨论】:

我不认为这正是我想要的。当 nginx 找不到服务 1 时,不是因为它意外宕机,而是因为我故意不运行它,所以我希望 /service1 路由返回 404(或其他错误)。 然而,在现实世界中可能就是这种情况 - 当有人因为某种原因关闭服务时,他们不希望他们的网站出现故障,他们希望能够做任何他们想做的事情希望在自己的空闲时间恢复服务,无需停机 - 这是负载均衡器的一个目的 我确信我想要的是我描述的行为,而不是负载均衡器

以上是关于带有动态容器的 Nginx 反向代理的主要内容,如果未能解决你的问题,请参考以下文章

为Docker创建自动化nginx反向代理

如何使用多个节点应用程序设置 nginx 反向代理

NGINX动态反向代理

仅使用 Nginx 反向代理启用 Docker 端口访问

nginx 反向代理可以访问多个 docker 容器

对 docker 容器使用 nginx 反向代理