AWS ECS jwilder/nginx-proxy 无法在上游内部生成服务器
AWS ECS jwilder/nginx-proxy fails to generate servers inside upstream
我正在尝试将 jwilder/nginx-proxy 设置为反向代理,以将请求代理到公开 VIRTUAL_HOST=example.com 环境变量的各种容器。
如果容器直接在 ec2 集群主机上启动但设置失败并出现以下错误:"error running notify command: nginx -s reload, exit status 1"如果它是从 ECS 生成的。
容器运行宁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
它现在 returns 默认的 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 套接字?
首先,最好避免在 Nginx 配置中使用域名,尤其是在定义上游服务器时。如果没有别的,那就令人困惑了。
您对 example.com
的所有值都相同吗?如果是这样,你有一个上游块,它定义了一个名称为 example.com
的上游服务器集群,那么你有一个服务器块,其服务器名称指令为 example.com
,然后你试图 proxy_pass至 example.com
.
如果您有多个服务器能够处理相同的请求,通常您指定一个上游块作为负载平衡的方法。编辑您的上游块并包括所有上游服务器 address:port,如果您愿意,您可以包括其他选项来配置 Nginx 如何在它们之间分配负载,请参阅 Nginx 文档以获取更多信息。你给上游块的名字只被 Nginx 使用,可以是任何东西,不要在这里使用你的域名。类似于:
upstream dockergroup {
然后在server块中的listen
指令中的端口前添加一个ip地址,并将proxy_pass
指令更改为http://dockergroup
我不确定具体细节,但根据您链接的页面上的文档:
you can To add settings on a per-VIRTUAL_HOST basis, add your
configuration file under /etc/nginx/vhost.d. Unlike in the proxy-wide
case, which allows multiple config files with any name ending in
.conf, the per-VIRTUAL_HOST file must be named exactly after the
VIRTUAL_HOST.
要解决的重要问题是您的上游块不能为空,并且上游块的名称不应与您网络上的任何域或主机名冲突。根据我的阅读,您应该能够使用各种配置选项来解决这个问题。
3 天前,我们的团队遇到了这个问题。我们为此花了很多时间。
问题原因应该在AWS ecs-agent(我们有2个环境,一个ecs-agent的版本是1.21,另一个是1.24)
昨天,我们解决了这个问题:使用AWS控制台将ecs-agent更新到最新版本:1.34并重启ecs-agent(docker contianer) 然后问题就解决了。
只需将此解决方案粘贴到此处即可。希望对其他人有所帮助!
我正在尝试将 jwilder/nginx-proxy 设置为反向代理,以将请求代理到公开 VIRTUAL_HOST=example.com 环境变量的各种容器。
如果容器直接在 ec2 集群主机上启动但设置失败并出现以下错误:"error running notify command: nginx -s reload, exit status 1"如果它是从 ECS 生成的。
容器运行宁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
它现在 returns 默认的 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 套接字?
首先,最好避免在 Nginx 配置中使用域名,尤其是在定义上游服务器时。如果没有别的,那就令人困惑了。
您对 example.com
的所有值都相同吗?如果是这样,你有一个上游块,它定义了一个名称为 example.com
的上游服务器集群,那么你有一个服务器块,其服务器名称指令为 example.com
,然后你试图 proxy_pass至 example.com
.
如果您有多个服务器能够处理相同的请求,通常您指定一个上游块作为负载平衡的方法。编辑您的上游块并包括所有上游服务器 address:port,如果您愿意,您可以包括其他选项来配置 Nginx 如何在它们之间分配负载,请参阅 Nginx 文档以获取更多信息。你给上游块的名字只被 Nginx 使用,可以是任何东西,不要在这里使用你的域名。类似于:
upstream dockergroup {
然后在server块中的listen
指令中的端口前添加一个ip地址,并将proxy_pass
指令更改为http://dockergroup
我不确定具体细节,但根据您链接的页面上的文档:
you can To add settings on a per-VIRTUAL_HOST basis, add your configuration file under /etc/nginx/vhost.d. Unlike in the proxy-wide case, which allows multiple config files with any name ending in .conf, the per-VIRTUAL_HOST file must be named exactly after the VIRTUAL_HOST.
要解决的重要问题是您的上游块不能为空,并且上游块的名称不应与您网络上的任何域或主机名冲突。根据我的阅读,您应该能够使用各种配置选项来解决这个问题。
3 天前,我们的团队遇到了这个问题。我们为此花了很多时间。
问题原因应该在AWS ecs-agent(我们有2个环境,一个ecs-agent的版本是1.21,另一个是1.24)
昨天,我们解决了这个问题:使用AWS控制台将ecs-agent更新到最新版本:1.34并重启ecs-agent(docker contianer) 然后问题就解决了。
只需将此解决方案粘贴到此处即可。希望对其他人有所帮助!