我目前在公司中使用Docker-Compose运行开发堆栈,以向开发人员提供他们编写我们的应用程序所需的一切。
它尤其包括:
为了通过HTTPS保护服务并将其暴露给外界,我安装了出色的nginx-proxy容器(jwilder / nginx- proxy),该容器允许使用容器上的环境变量自动进行nginx代理配置,以及自动进行HTTP到HTTPS重定向。
DNS配置为将dockerized服务的每个公共URL映射到主机的IP。
最后,使用Docker-Compose,我的docker-compose.yml文件如下所示:
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
对于开发人员工作站,一切正常。人们可以通过访问差别服务https://gitlab.my-domain.com,https://repo.my- domain.com和https://jenkins.my-domain.com。
https://gitlab.my-domain.com
https://repo.my- domain.com
https://jenkins.my-domain.com
当其中一个dockerized服务访问另一个dockerized服务时,就会发生此问题。例如,如果尝试https://archiva.my- domain.com从jenkins docker 访问,则会从代理收到超时错误。
https://archiva.my- domain.com
似乎即使将archiva.my-domain.com其解析为 来自Docker 容器的公共主机IP, 来自dockerized服务的请求也不会被nginx-proxy代理。
archiva.my-domain.com
据我了解,docker-nginx正在处理来自主机网络的请求,但并不关心来自内部容器网络(对于Docker- Compose堆栈为_dockerconfig_default_)的请求。
您可能会说,为什么我需要使用容器中的代理?当然,我可以使用http://archiva:8080Jenkins容器中的URL ,它可以工作。但是这种配置是不可扩展的。
http://archiva:8080
例如,使用Gradle构建来编译一个应用程序,build.gradle需要通过声明我的私有存储库https://archiva.my- domain.com。如果从开发人员工作站启动构建,但不能通过jenkins容器启动构建,它将起作用。
另一个示例是通过OAuth GitLab服务在Jenkins中进行身份验证,其中需要在Jenkins容器的外部和内部 都 可以使用相同的URL GitLab身份验证。
那么我的问题是: 如何配置nginx-proxy以将请求从一个容器代理到另一个容器?
我没有看到任何讨论此问题的主题,并且我对问题的理解还不足以在nginx配置上构建解决方案。
任何帮助将非常感激。
BMitch,赔率很好,这的确是iptables规则的问题,而不是nginx-proxy的错误配置。
该表的默认链INPUT策略filter为DROP,并且未对ACCEPT来自容器IP(127.20.XX)的请求制定任何规则。
filter
DROP
ACCEPT
因此,为了记录在案,我提供了一些其他人遇到相同问题时的情况的详细信息。
为了从外部访问容器,Docker在PREROUTING和FORWARD规则上设置了规则,以允许将外部IP从主机IP映射到容器IP。这些默认规则允许任何外部IP,这就是为什么限制对容器的访问需要一些高级iptables自定义的原因。
请参阅此链接以获取示例:http : //rudijs.github.io/2015-07/docker- restricting-container-access-with- iptables/
但是,如果您的容器需要访问主机资源(在主机上运行的服务,或者在我的情况下是侦听HTTP / HTTPS主机端口并代理到容器的nginx代理容器),则需要注意容器中的iptables规则输入链。
实际上,来自容器并发给主机的请求将由Docker守护程序路由到主机网络堆栈, 但 随后需要传递INPUT链(因为请求srcIP是主机的IP)。因此,如果您想保护主机资源并允许容器访问它们,请不要记得添加以下内容:
src
iptables -A INPUT -s 127.20.X.X/24 -j ACCEPT
其中127.20.XX / 24是运行容器的虚拟网络。
非常感谢您的帮助。