nginx proxy_pass 到链接的 docker 容器

Posted

技术标签:

【中文标题】nginx proxy_pass 到链接的 docker 容器【英文标题】:nginx proxy_pass to a linked docker container 【发布时间】:2015-03-17 16:53:52 【问题描述】:

我有两个带有 nginx 的 docker 容器。 container1 链接到 container2。 Docker 然后向 /etc/hosts 添加一个条目,我将其输入到 nginx 配置中,如下所示:

server 
    location ~ ^/some_url/(.*)$ 
        proxy_pass http://container1/$1;
    

我可以从 container2 ping container1,但 nginx 无法解析:

*1 没有定义解析器来解析容器1

如何代理_将请求传递给另一个 docker 容器?

【问题讨论】:

你能分享你的主机文件吗?你是如何链接这两个容器的? (链接的名称是什么?)还有问题:如果您rmd 其中一个容器并稍后重新启动它,IP 将会改变(主机未更新) 我刚刚尝试了与您类似的配置,nginx:1.7.9 对我来说效果很好。你可以在 container2 和 curl container1 开始 bash 吗?您使用的不是容器 1 和 2 相同的配置,是吗? @MykolaGurov 我可以 ping 和 curl 以及来自 container2 的不是 container1。我的问题是,nginx 似乎无法解决它。我没有使用相同的配置,不(如果您指的是 nginx 配置)。 【参考方案1】:

直接使用上游块而不是容器名称

upstream backend 
    server container1;

server 
    location ~ ^/some_url/(.*)$ 
        proxy_pass http://backend/$1;
    

这应该允许正常的名称解析发生,提供一种轻松使用 nginx 的 docker 链接的方法。

【讨论】:

当您不想弄乱任何外部依赖项时的最佳答案。 这个解决方案的问题是container1必须先启动并运行才能启动你的nginx容器,否则它不会启动 编写一个等待后端启动的脚本。像这样的东西应该可以工作:bash -c "while ! curl -s container1:8080 > /dev/null; do echo waiting for container1; sleep 3; done; start_nginx.sh" start_nginx.sh 实际上启动了 nginx 服务。 @Marc-AlexandreBérubé 不过应该不是问题 - 如果您使用的是--link,无论如何这是一个要求。 只有真正干净和安全的解决方案。赞!【参考方案2】:

我相信,Nginx 正在使用自己的 DNS 解析器实现,

您可以使用嵌入式 Docker DNS 服务,如果启用,请检查您的容器解析器:

cat /etc/resolv.conf

应该是:

nameserver 127.0.0.11

使用此 IP 作为解析器:

server 
    location ~ ^/some_url/(.*)$ 
        resolver 127.0.0.11;
        proxy_pass http://container1/$1;
     

入口点中有大量​​带有此类 hack 的 Docker 映像:

https://github.com/jetbrains-infra/docker-nginx-resolver

entrypoint.sh:

...
echo resolver $(awk 'BEGINORS=" " $1=="nameserver" print $2' /etc/resolv.conf) ";" > /etc/nginx/includes/resolver.conf
...

nginx.conf:

http 
    include       /etc/nginx/includes/resolver.conf;
....

【讨论】:

嗯,也许硬编码的 IP 127.0.0.11 会带来一些问题 我认为是的。理想的方法是解析 etc/resolv.conf 以获得名称服务器 IP。 我刚遇到这个:***.com/questions/35744650/…。在用户定义的网络中硬编码 IP 地址不会有问题。 为什么 Nginx 不解析 resolv.conf 顺便说一句? 看起来确实如此,但不确定为什么它在 docker 的情况下特别失败。【参考方案3】:

你应该看看这个关于使用 /etc/hosts 作为你的解析器的答案:Using /etc/hosts as resolver for url rewriting

基本上,您的 dns 或解析器在查找期间不使用 /etc/hosts 来解析名称,但您可以通过安装 dnsmasq 并使用 127.0.0.1 作为解析器来解决此问题。您可以直接在您的 nginx 配置中添加 127.0.0.1 作为解析器:

server 
    location ~ ^/some_url/(.*)$ 
        resolver 127.0.0.1;
        proxy_pass http://container1/$1;
    

【讨论】:

那是我实际上已经尝试过的东西,但是由于 dnsmasq 没有启动没有错误,我放弃了。也许太快了。会再试一次并通知您。 我又试了一次,只是将 dnsmasq 添加到我的入口点。如果您在 VM 中运行容器,请确保以 root 身份运行 dnsmasq,否则它将无法工作。

以上是关于nginx proxy_pass 到链接的 docker 容器的主要内容,如果未能解决你的问题,请参考以下文章

Nginx Proxy_pass简述

nginx 之 proxy_pass详解

nginx proxy_pass 到 phpmyadmin docker 容器

nginx 中的 proxy_pass 到 EC2 实例的私有 IP

nginx 位置 /sub/$VAR/ 到 proxy_pass /sub/$VAR/

Nginx中uwsgi_pass和proxy_pass的区别?