Docker nginx-proxy:容器之间的代理 [英] Docker nginx-proxy : proxy between containers

查看:400
本文介绍了Docker nginx-proxy:容器之间的代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在公司使用Docker-Compose运行一个开发栈,向开发人员提供编写我们的应用程序所需的所有东西。



它特别包括:





为了通过HTTPS保护服务并将其暴露给外界,我安装了优秀的nginx-proxy容器( jwilder / nginx-proxy ),允许自动化的nginx代理配置离子使用容器上的环境变量,以及自动化HTTP到HTTPS重定向。



DNS配置为将停靠服务的每个公共URL映射到主机的IP。 >

最后,使用Docker-Compose,我的docker-compose.yml文件如下所示:

  version:'2'
services:
nginx-proxy:
image:jwilder / nginx-proxy
ports:
- 80:80
- 443:443
卷:
- /var/run/docker.sock:/tmp/docker.sock:ro
- / var / config / nginx-代理/证书:/ etc / nginx / certs:ro
postgresql:
#配置postgresql容器...
gitlab:
image:sameersbn / gitlab
ports :
- 10022:22
卷:
- / var / data / gitlab:/ home / git / data
环境:
# ...
- VIRTUAL_HOST = gitlab.my-domain.com
- VIRTUAL_PORT = 80
- CERT_NAME = star.my-domain.com
arch iva:
image:ninjaben / archiva-docker
卷:
- / var / data / archiva:/ var / archiva
环境:
- VIRTUAL_HOST = archiva。 my-domain.com
- VIRTUAL_PORT = 8080
- CERT_NAME = star.my-domain.com
jenkins:
image:jenkins
卷:
- / var / data / jenkins:/ var / jenkins_home
环境:
- VIRTUAL_HOST = jenkins.my-domain.com
- VIRTUAL_PORT = 8080
- CERT_NAME = star.my -domain.com

对于开发人员工作站,一切都按预期工作。可以通过 https://gitlab.my-domain.com https://repo.my-domain.com https://jenkins.my-domain.com



发生问题当其中一个dockerized服务访问另一个dockerized服务。例如,如果我尝试从jenkins docker访问 https://archiva.my-domain.com ,我将从代理获取超时错误。



似乎即使 c> archiva.my-domain.com 被解析为Docker容器中的公共主机IP,来自dockerized服务的请求不由nginx-proxy代理。



据我所知,docker-nginx正在处理来自主机网络的请求,但不关心来自内部容器网络(_dockerconfig_default_ for Docker-Compose堆栈)的那些。



你可以说,为什么我需要使用代理从容器?当然,我可以使用Jenkins容器的URL http:// archiva:8080 ,这样就可以了。但是这种配置是不可扩展的。



例如,使用Gradle构建来编译一个应用程序,build.gradle需要通过 https://archiva.my-domain.com 。如果构建是从开发人员工作站启动的,而不是通过jenkins容器启动,那么它将工作。



另一个例子是由OAuth GitLab服务在Jenkins中的身份验证,相同的URL GitLab身份验证需要从外部和Jenkins容器内部获得



我的问题是:如何配置nginx-proxy来代理从容器到另一个容器的请求?



我没有看到任何话题讨论这个问题,我不了解足够的问题来构建一个nginx配置的解决方案。



任何帮助将非常感谢。

解决方案

BMitch,可能性很好,这确实是一个iptables规则问题,而不是nginx-proxy的配置错误。



过滤器的链INPUT的默认策略为 DROP ,并且没有规定来自容器IP(127.20.XX)的 ACCEPT 请求。



所以为了纪录,如果其他人面临同样的问题,我会给出一些细节。



要从外部访问容器,Docker将规则放在PREROUTING和FORWARD规则上,以允许外部IP从主机IP到容器IP的DNATed。这些默认规则允许任何外部IP,这就是为什么限制对容器的访问需要一些高级iptables自定义。



查看此链接的示例: http://rudijs.github.io/2015-07/docker-restricting- container-access-with-iptables /



但是,如果您的容器需要访问主机资源(在主机上运行的服务,或在我的情况下,nginx -proxy容器监听HTTP / HTTPS主机端口并代理容器),您需要注意INPUT链的iptables规则。



实际上,请求来自容器并寻址到主机的Docker守护程序将被路由到主机网络堆栈,则需要传递INPUT链(如请求 src IP是主机)。所以如果你想保护主机资源并让容器访问它们,不要记得添加这样的东西:

  iptables -A INPUT -s 127.20.XX / 24 -j ACCEPT 

其中127.20.XX / 24是虚拟网络您的集装箱正在运行。



非常感谢您的帮助。


I am currently running a development stack using Docker-Compose in my company, to provide to developers everything they need to code our applications.

It includes in particular:

In order to secure the services through HTTPS, and exposing them to the outside world, I installed the excellent nginx-proxy container (jwilder/nginx-proxy) which allows automated nginx proxy configuration using environment variables on containers, and automated HTTP to HTTPS redirection.

DNS are configured to map each public URL of dockerized services to the IP of the host.

Finally, using Docker-Compose, my docker-compose.yml file looks like this :

version: '2'
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - /var/config/nginx-proxy/certs:/etc/nginx/certs:ro
  postgresql:
    # Configuration of postgresql container ...
  gitlab:
    image: sameersbn/gitlab
    ports:
    - "10022:22"
    volumes:
    - /var/data/gitlab:/home/git/data
    environment:
    # Bunch of environment variables ...
    - VIRTUAL_HOST=gitlab.my-domain.com
    - VIRTUAL_PORT=80
    - CERT_NAME=star.my-domain.com
  archiva:
    image: ninjaben/archiva-docker
    volumes:
    - /var/data/archiva:/var/archiva
    environment:
    - VIRTUAL_HOST=archiva.my-domain.com
    - VIRTUAL_PORT=8080
    - CERT_NAME=star.my-domain.com
  jenkins:
    image: jenkins
    volumes:
    - /var/data/jenkins:/var/jenkins_home
    environment:
    - VIRTUAL_HOST=jenkins.my-domain.com
    - VIRTUAL_PORT=8080
    - CERT_NAME=star.my-domain.com

For a developer workstation, everything works as expected. One can access the difference services through https://gitlab.my-domain.com, https://repo.my-domain.com and https://jenkins.my-domain.com.

The problem occurs when one of the dockerized service access another dockerized service. For instance, If I try to access https://archiva.my-domain.com from jenkins docker, I will get a timeout error from the proxy.

It seems that even if archiva.my-domain.com is resolved as the public host IP from the docker container, requests coming from dockerized services are not proxied by nginx-proxy.

As far as I understood, docker-nginx is handling requests coming from the host network, but does not care about the ones coming from the internal container network (_dockerconfig_default_ for a Docker-Compose stack).

You could say, why would I need to use the proxy from a container ? Of course, I could use URL http://archiva:8080 from Jenkins container, and it would work. But this kind of configuration is not scalable.

For example, using a Gradle build to compile one application, the build.gradle needs to declare my private repository through https://archiva.my-domain.com. It will work if build is launched from a developer workstation, but not through the jenkins container ...

Another example is an authentication in Jenkins by OAuth GitLab service, where the same URL GitLab authentication needs to be both available from the outside, and inside the Jenkins container.

My question here is then : How to configure nginx-proxy to proxy a request from a container to another container ?

I did not see any topic discussing this problem, and I do not understand enough the problem to build a solution on nginx configuration.

Any help would be really appreciated.

解决方案

BMitch, the odds were good, it was indeed a iptables rules problem, and not a misconfiguration of nginx-proxy.

The default policy of chain INPUT for the table filter was DROP, and no rules was made to ACCEPT requests from the container IPs (127.20.X.X).

So for the record, I give some details of the situation if other people face the same problem.

To access containers from the outside world, Docker put rules on PREROUTING and FORWARD rules to allow external IPs to be DNATed from the host IP to the container IPs. Theses default rules allow any external IPs, and that is why limiting access to containers requires some advanced iptables customizations.

See this link for an example : http://rudijs.github.io/2015-07/docker-restricting-container-access-with-iptables/

But if your containers need to access host resources (services runing on the host, or in my case, a nginx-proxy container listening to HTTP/HTTPS host port and proxying to containers), you need to take care about the iptables rules of the INPUT chain.

In fact, a request coming from the container and addressed to the host will be routed to the host network stack by the Docker daemon, but will then need to pass the INPUT chain (as the request src IP is the host one). So if you want to protect host resources and let containers access them, do not remember to add something like this :

iptables -A INPUT -s 127.20.X.X/24 -j ACCEPT

Where 127.20.X.X/24 is the virtual network on which your containers are running.

Thank you a lot for your help.

这篇关于Docker nginx-proxy:容器之间的代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆