带有Nginx代理的Docker Compose拒绝环境中容器的连接

时间:2020-01-23 06:17:44

标签: docker nginx proxy docker-compose

我有一个docker-compose文件,该文件使用jwilder/nginx-proxy为我正在运行的Artifactory图像提供ssl。

通过撰写环境的容器外部的连接,一切都可以正常工作。这样,我的浏览器就可以很好地加载Artifactory网络应用程序并对其进行ssl加密,并且所有API的命令行工具都可以正常工作。

问题是,如果我位于环境中的一个容器中,则可以ping环境中的其他容器,但是如果尝试从Artifactory容器中加载页面,则会收到错误消息,指出连接为拒绝。

这是我的撰写文件:

version: '3'
services:

  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./assets/certs:/etc/nginx/certs
    depends_on:
      - artifactory

  artifactory:
    image: docker.bintray.io/jfrog/artifactory-pro:latest
    volumes:
      - artifactory5_data:/var/opt/jfrog/artifactory
    environment:
      - VIRTUAL_HOST=artifactory.test
      - VIRTUAL_PORT=8081
    depends_on:
      - node

  node:
    build:
      context: ./nodes
      dockerfile: Dockerfile

volumes:
  artifactory5_data:

构建node的Dockerfile只是puppet/puppet-agent-ubuntu的一个实例,其入口点脚本会循环运行木偶以保持容器打开。

我用来启动环境的命令是:

docker-compose --project-name preso up -d --scale node=3                                                                                                      
Creating network "preso_default" with the default driver
Creating preso_node_1 ... done
Creating preso_node_2 ... done
Creating preso_node_3 ... done
Creating preso_artifactory_1 ... done
Creating nginx-proxy         ... done

docker ps --all --no-trunc
CONTAINER ID                                                       IMAGE                                            COMMAND                                       CREATED             STATUS                  PORTS                                      NAMES
d390506f4149b6f386376f94dad1c2d34cce11d869b2033e72646856c5f9a47b   jwilder/nginx-proxy                              "/app/docker-entrypoint.sh forego start -r"   45 seconds ago      Up 43 seconds           0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx-proxy
1695bc05d4bd1ea0c08ec82b636ce5847649f9aa8b48814d44d5986c8577f29d   docker.bintray.io/jfrog/artifactory-pro:latest   "/entrypoint-artifactory.sh"                  46 seconds ago      Up 43 seconds           8081/tcp                                   preso_artifactory_1
291965e80148f4670b32ef0bded891c79ef361161d3860fd33707f4805d004f0   preso_node                                       "/bin/bash /entrypoint.sh"                    47 seconds ago      Up 44 seconds                                                      preso_node_3
d81f4e2a22b5d8e56e8764029f5ae0b0666e353937a70c825cce1a2c5d2d1f3a   preso_node                                       "/bin/bash /entrypoint.sh"                    47 seconds ago      Up 44 seconds                                                      preso_node_2
b64038d2c3ca32939686eb2cc9324cc5e935df5445570a8746d80c527b3fe95d   preso_node                                       "/bin/bash /entrypoint.sh"                    47 seconds ago      Up 44 seconds                                                      preso_node_1

Artifactory可以从本地计算机和浏览器中的命令行正常加载,但可以从node容器之一中的bash中获得:

curl --insecure https://artifactory.test/artifactory
curl: (7) Failed to connect to artifactory.test port 443: Connection refused

ping可以识别我

Pinging artifactory.test [127.0.0.1] with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time=0ms TTL=128
Reply from 127.0.0.1: bytes=32 time=0ms TTL=128
Reply from 127.0.0.1: bytes=32 time=0ms TTL=128
Reply from 127.0.0.1: bytes=32 time=0ms TTL=128

更新: 我尝试将nginx-proxy主机名添加到容器的hosts文件中:

echo 'nginx-proxy artifactory.test' >> /etc/hosts

这没有奏效。 ping artifactory.test现在仍然将连接发送到本地主机:

Pinging artifactory.test [127.0.0.1] with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time=0ms TTL=128

ping nginx-proxy返回时:

Pinging nginx-proxy [172.21.0.6] with 32 bytes of data:
Reply from 172.21.0.6: bytes=32 time=0ms TTL=128

注意:我现在看到尝试通过主机将一个主机名重定向到另一个主机名永远都行不通。

如果我将IP地址作为hostsfile条目添加到artifactory.test,那么一切都会按预期进行。

这种方法的问题是我不知道该地址在环境中分配给nginx-proxy容器的可靠性如何。如果我将托管条目构建为node容器,那么它是否始终可以正常工作?

2 个答案:

答案 0 :(得分:0)

尽管我承认由于它是内部网络,所以实际上可能实际上并不需要它,但是这里的目的是向观众演示如何在企业中安装和使用Artifactory,因此使用某些演示脚本的docker主机名可能会使某些查看者感到困惑。事物看起来应该尽可能正常且易于理解,这意味着在容器中运行的命令行命令中使用与在我的机器浏览器中使用的主机名相同的主机名。

也就是说,我确实做到了这一点。诀窍是定义一个自定义内部网络,在该网络上我可以控制将要分配的IP地址。知道将要分配的IP地址之后,我还可以确保我的所有节点容器都具有一个自定义主机条目,该条目将知道如何正确路由请求。下面是最终的撰写文件。

注意:如果您没有如图所示将默认网络明确添加回nginx-proxy服务,则对artifactory.test的请求将返回一个502 Bad Gateway响应而不是按预期转发请求。

version: '3'
services:

  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./assets/certs:/etc/nginx/certs
    depends_on:
      - artifactory
    networks:
      demo:
        ipv4_address: 10.5.0.100
      default:

  artifactory:
    container_name: artifactory
    image: docker.bintray.io/jfrog/artifactory-pro:latest
    volumes:
      - artifactory5_data:/var/opt/jfrog/artifactory
    environment:
      - VIRTUAL_HOST=artifactory.test
      - VIRTUAL_PORT=8081
    depends_on:
      - node

  node:
    build:
      context: ./nodes
      dockerfile: Dockerfile
    extra_hosts:
      - "artifactory.test:10.5.0.100"
    networks:
      demo:

volumes:
  artifactory5_data:

networks:
  demo:
    ipam:
     config:
       - subnet: 10.5.0.0/16

到位后,对artifactory.test主机名的卷曲请求将按预期通过SSL终止通过代理进行路由。

curl --insecure https://artifactory.test/artifactory/api/nuget/nuget-local
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~
  ~ Copyright 2016 JFrog Ltd. All rights reserved.
  ~ JFROG PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  -->

<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xml:base="https://artifactory.test/artifactory/api/nuget/nuget-local">
    <workspace>
        <atom:title>Default</atom:title>
        <collection href="Packages">
            <atom:title>Packages</atom:title>
        </collection>
    </workspace>
</service>

答案 1 :(得分:0)

我将jwilder用作我在生产环境中所有服务的反向代理,这没有问题。您必须检查以下步骤:

1-首先检查证书和密钥文件名,在您的情况下,应为artifactory.test.crt和artifactory.test.key

2-通过“ docker exec -itartistory SHELL”将第二个exec进入人为因素容器,然后寻找监听端口并确保您的应用程序侦听8081,然后使用docker检查容器,然后检查articleoryContainerName并寻找暴露的端口

如果上述方法还可以,请提供jwilder容器日志