【问题标题】:nginx proxy_pass to a linked docker containernginx proxy_pass 到链接的 docker 容器
【发布时间】: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 配置)。

标签: nginx docker reverse-proxy


【解决方案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 'BEGIN{ORS=" "} $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。
  • 我刚遇到这个:stackoverflow.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,否则它将无法工作。
猜你喜欢
  • 2018-07-08
  • 2022-01-22
  • 2023-02-26
  • 1970-01-01
  • 2017-01-22
  • 2015-05-03
  • 2017-02-13
  • 2019-03-20
  • 1970-01-01
相关资源
最近更新 更多