0

我正在尝试将jwilder/nginx-proxy设置为反向代理,以将请求代理到公开 VIRTUAL_HOST=example.com 环境变量的各种容器。

如果容器直接在 ec2 集群主机上启动,则设置有效,但如果它是从 ECS 生成的,则会失败并显示以下错误:“error running notify command: nginx -s reload, exit status 1”。

运行 jwilder/nginx-proxy 容器的容器的 docker 日志: WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. forego | starting dockergen.1 on port 5000 forego | starting nginx.1 on port 5100 dockergen.1 | 2018/08/19 10:43:37 Generated '/etc/nginx/conf.d/default.conf' from 4 containers dockergen.1 | 2018/08/19 10:43:37 Running 'nginx -s reload' dockergen.1 | 2018/08/19 10:43:37 **Error running notify command: nginx -s reload, exit status 1** dockergen.1 | 2018/08/19 10:43:37 Watching docker events dockergen.1 | 2018/08/19 10:43:37 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload' 2018/08/19 10:48:23 [emerg] 38#38: no servers are inside upstream in /etc/nginx/conf.d/default.conf:55 nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/default.conf:55 Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time dhparam generation complete, reloading nginx

环境配置如下:

services: 
- name: proxy
  *volumes*:
  Name: docker-socket
  Source Path: /var/run/docker.sock
  *containers*: 
    - name: proxy
      image: jwilder/nginx-proxy
      port: 80:80
      Mount Points:
        Container Path: /tmp/docker.sock
        Source Volume: docker-socket
        Read only: true 
- name: site
  *containers*:
    - name: site
      image: nginx
      port: 0:80
      environment:
      - VIRTUAL_HOST=example.com

测试命令:

curl -H "Host: example.com" localhost:80   

它现在返回默认的 nginx 页面,因为 nginx 配置文件无法生成有效配置,因为缺少上游主机。

生成的无效 nginx 配置

proxy_set_header Proxy "";
server {
  server_name _; # This is just an invalid value which will never trigger on a real hostname.
  listen 80;
  access_log /var/log/nginx/access.log vhost;
  return 503;
}
# example.com
upstream example.com {
}
server {
  server_name example.com;
  listen 80 ;
  access_log /var/log/nginx/access.log vhost;
  location / {
    proxy_pass http://example.com
  }
}

如果使用以下命令,代理将按预期工作:

docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

如果运行上面的命令,它会给出以下输出: WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. forego | starting dockergen.1 on port 5000 forego | starting nginx.1 on port 5100 dockergen.1 | 2018/08/19 10:18:48 Generated '/etc/nginx/conf.d/default.conf' from 10 containers dockergen.1 | 2018/08/19 10:18:48 Running 'nginx -s reload' dockergen.1 | 2018/08/19 10:18:48 Watching docker events dockergen.1 | 2018/08/19 10:18:48 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload' 2018/08/19 10:19:09 [notice] 40#40: signal process started Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time dhparam generation complete, reloading nginx 生成的有效 nginx 配置:

proxy_set_header Proxy "";
server {
  server_name _; # This is just an invalid value which will never trigger on a real hostname.
  listen 80;
  access_log /var/log/nginx/access.log vhost;
  return 503;
}
# example.com
upstream example.com {
        ## Can be connected with "bridge" network
      # ecs-site-site-add8hjasd
      server 172.17.0.3:80;
}
server {
  server_name example.com;
  listen 80 ;
  access_log /var/log/nginx/access.log vhost;
  location / {
    proxy_pass http://example.com;
  }
}

我的问题是:为什么这不起作用,是因为权限还是挂载到 docker 套接字?

4

2 回答 2

2

3天前,我们的团队遇到了这个问题。我们为此花了很多时间。

问题原因应该在 AWS ecs-agent 中(我们有 2 个环境,一个 ecs-agent 的版本是 1.21,另一个是 1.24)

昨天,我们解决了这个问题: 使用 AWS 控制台将 ecs-agent 更新到最新版本:1.34 并重启 ecs-agent(docker contianer) 然后问题就解决了。

只需在此处粘贴此解决方案。希望对其他人有帮助!

于 2019-11-30T06:56:52.460 回答
0

首先,最好避免在 Nginx 配置中使用域名,尤其是在定义上游服务器时。如果没有别的,那就令人困惑了。

你所有的价值观都example.com一样吗?如果是这样,您有一个上游块,它定义了一个名为 的上游服务器集群example.com,那么您有一个服务器块,其服务器名称指令为example.com,然后您尝试将 proxy_pass 传递给example.com

通常,如果您有多个能够处理相同请求的服务器,您可以指定上游块作为负载平衡的方法。编辑您的上游块并包括所有上游服务器地址:端口,如果您愿意,您可以包括其他选项来配置 Nginx 如何在它们之间分配负载,请参阅 Nginx 文档以获取更多信息。您给上游块的名称仅供 Nginx 使用,可以是任何名称,请勿在此处使用您的域名。就像是:

upstream dockergroup {

listen然后在 server 块中的指令中的端口前添加一个 ip 地址并将指令更改proxy_passhttp://dockergroup

我不确定具体细节,但根据您链接的页面上的文档:

您可以在每个 VIRTUAL_HOST 的基础上添加设置,在 /etc/nginx/vhost.d 下添加您的配置文件。与代理范围的情况不同,它允许多个配置文件的名称以 .conf 结尾,每个 VIRTUAL_HOST 文件必须完全在 VIRTUAL_HOST 之后命名。

要解决的重要问题是您的上游块不能为空,并且上游块的名称不应与网络上的任何域或主机名冲突。根据我读到的内容,您应该能够使用各种配置选项来解决这个问题。

于 2018-08-19T15:57:16.490 回答