nginx 不会自动获取 swarm 中的 dns 变化
nginx does not automatically pick up dns changes in swarm
我是 运行 nginx 通过 lets-nginx 在 docker 群中的默认 nginx 配置(根据 lets-nginx 项目):
服务:
ssl:
image: smashwilson/lets-nginx
networks:
- backend
environment:
- EMAIL=sas@finestructure.co
- DOMAIN=api.finestructure.co
- UPSTREAM=api:5000
ports:
- "80:80"
- "443:443"
volumes:
- letsencrypt:/etc/letsencrypt
- dhparam_cache:/cache
api:
image: registry.gitlab.com/project_name/image_name:0.1
networks:
- backend
environment:
- APP_SETTINGS=/api.cfg
configs:
- source: api_config
target: /api.cfg
command:
- run
- -w
- tornado
- -p
- "5000"
api
是一个 flask 应用程序,它在 swarm 覆盖网络 backend
.
的端口 5000 上运行
最初启动服务时一切正常。但是,每当我以一种使 api
容器在三节点群中的节点之间移动的方式更新 api
时,nginx
无法将流量路由到新容器。
我可以在 nginx 日志中看到它坚持使用旧的内部 IP,例如 10.0.0.2,而新容器现在位于 10.0.0.4。
为了使 nginx 'see' 成为新的 IP,我需要重新启动 nginx 容器或 docker exec
进入它并 kill -HUP
nginx 进程。
有没有更好的自动方式让nginx容器刷新名字解析?
感谢@Moema 的指点,我想出了一个解决方案。 lets-nginx 的默认配置需要进行如下调整,以使 nginx 获取 IP 更改:
resolver 127.0.0.11 ipv6=off valid=10s;
set $upstream http://${UPSTREAM};
proxy_pass $upstream;
这使用 docker 带 TTL 的 swarm 解析器并设置一个变量,强制 nginx 刷新 swarm 中的名称查找。
请记住,当您使用 set
时,您需要自己生成整个 URL。
我在 compose 中使用 nginx 来代理 zuul 网关:
location /api/v1/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_pass http://rs-gateway:9030/api/v1/;
}
location /zuul/api/v1/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_pass http://rs-gateway:9030/zuul/api/v1/;
}
现在有了 Swarm,它看起来像这样:
location ~ ^(/zuul)?/api/v1/(.*)$ {
set $upstream http://rs-gateway:9030/api/v1/$is_args$args;
proxy_pass $upstream;
# Set headers
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
正则表达式很好,但不要忘记自己将 GET 参数插入到生成的 URL 中。
我是 运行 nginx 通过 lets-nginx 在 docker 群中的默认 nginx 配置(根据 lets-nginx 项目):
服务:
ssl:
image: smashwilson/lets-nginx
networks:
- backend
environment:
- EMAIL=sas@finestructure.co
- DOMAIN=api.finestructure.co
- UPSTREAM=api:5000
ports:
- "80:80"
- "443:443"
volumes:
- letsencrypt:/etc/letsencrypt
- dhparam_cache:/cache
api:
image: registry.gitlab.com/project_name/image_name:0.1
networks:
- backend
environment:
- APP_SETTINGS=/api.cfg
configs:
- source: api_config
target: /api.cfg
command:
- run
- -w
- tornado
- -p
- "5000"
api
是一个 flask 应用程序,它在 swarm 覆盖网络 backend
.
最初启动服务时一切正常。但是,每当我以一种使 api
容器在三节点群中的节点之间移动的方式更新 api
时,nginx
无法将流量路由到新容器。
我可以在 nginx 日志中看到它坚持使用旧的内部 IP,例如 10.0.0.2,而新容器现在位于 10.0.0.4。
为了使 nginx 'see' 成为新的 IP,我需要重新启动 nginx 容器或 docker exec
进入它并 kill -HUP
nginx 进程。
有没有更好的自动方式让nginx容器刷新名字解析?
感谢@Moema 的指点,我想出了一个解决方案。 lets-nginx 的默认配置需要进行如下调整,以使 nginx 获取 IP 更改:
resolver 127.0.0.11 ipv6=off valid=10s;
set $upstream http://${UPSTREAM};
proxy_pass $upstream;
这使用 docker 带 TTL 的 swarm 解析器并设置一个变量,强制 nginx 刷新 swarm 中的名称查找。
请记住,当您使用 set
时,您需要自己生成整个 URL。
我在 compose 中使用 nginx 来代理 zuul 网关:
location /api/v1/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_pass http://rs-gateway:9030/api/v1/;
}
location /zuul/api/v1/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_pass http://rs-gateway:9030/zuul/api/v1/;
}
现在有了 Swarm,它看起来像这样:
location ~ ^(/zuul)?/api/v1/(.*)$ {
set $upstream http://rs-gateway:9030/api/v1/$is_args$args;
proxy_pass $upstream;
# Set headers
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
正则表达式很好,但不要忘记自己将 GET 参数插入到生成的 URL 中。