如何在不同的主机上从外部访问docker container(overlay)中运行的服务

我有一个在覆盖networking上运行的docker容器。 我的要求是从不同的主机在外部到达在这个容器中运行的服务。 该服务绑定到容器的内部IP地址,在这种情况下做端口绑定到主机不是一个解决scheme。

实际情景

在容器内运行的服务是使用yarn-clientconfiguration的spark驱动程序 。 火花驱动程序绑定到容器内部IP(10.xxx)。 当火花驱动程序与在不同簇上运行的hadoop纱线进行通信时,纱线上的应用程序主设备试图通过驱动程序的容器内部ip进行通信,但是由于明显的原因它不能在内部IP上连接驱动程序。

请让我知道是否有办法实现从应用程序主(纱)到火花驱动(docker集装箱)的成功沟通。

Swarm版本:1.2.5

docker info: Containers: 3 Running: 2 Paused: 0 Stopped: 1 Images: 42 Server Version: swarm/1.2.5 Role: primary Strategy: spread Filters: health, port, containerslots, dependency, affinity, constraint Nodes: 1 ip-172-30-0-175: 172.30.0.175:2375 └ ID: YQ4O:WGSA:TGQL:3U5F:ONL6:YTJ2:TCZJ:UJBN:T5XA:LSGL:BNGA:UGZW └ Status: Healthy └ Containers: 3 (2 Running, 0 Paused, 1 Stopped) └ Reserved CPUs: 0 / 16 └ Reserved Memory: 0 B / 66.06 GiB └ Labels: kernelversion=3.13.0-91-generic, operatingsystem=Ubuntu 14.04.4 LTS, storagedriver=aufs └ UpdatedAt: 2016-09-10T05:01:32Z └ ServerVersion: 1.12.1 Plugins: Volume: Network: Swarm: NodeID: Is Manager: false Node Address: Security Options: Kernel Version: 3.13.0-91-generic Operating System: linux Architecture: amd64 CPUs: 16 Total Memory: 66.06 GiB Name: 945b4af662a4 Docker Root Dir: Debug Mode (client): false Debug Mode (server): false 

运行容器的命令:我正在使用docker-compose运行它:

 zeppelin: container_name: "${DATARPM_ZEPPELIN_CONTAINER_NAME}" image: "${DOCKER_REGISTRY}/zeppelin:${DATARPM_ZEPPELIN_TAG}" network_mode: "${CONTAINER_NETWORK}" mem_limit: "${DATARPM_ZEPPELIN_MEM_LIMIT}" env_file: datarpm-etc.env links: - "xyz" - "abc" environment: - "VOL1=${VOL1}" - "constraint:node==${DATARPM_ZEPPELIN_HOST}" volumes: - "${VOL1}:${VOL1}:rw" entrypoint: ["/bin/bash", "-c", '<some command here>'] 

看来纱线和火花需要能够直接在networking上看到对方 。 如果你可以把它们放在同一个覆盖networking上,所有东西都可以直接通信,如果没有的话…

覆盖

可以通过docker_gwbridge直接将数据路由到Docker节点上的覆盖networking,所有覆盖容器都连接到这个覆盖networking, 但是 ,这是一个很大的, 只有在容器正在运行的Docker节点上才有效。

所以在2节点非群模式覆盖10.0.9.0/24networking上运行2个容器…

我可以在demo0上ping本地容器,但不能在demo1上运行remote

 docker@mhs-demo0:~$ sudo ip ro add 10.0.9.0/24 dev docker_gwbridge docker@mhs-demo0:~$ ping -c 1 10.0.9.2 PING 10.0.9.2 (10.0.9.2): 56 data bytes 64 bytes from 10.0.9.2: seq=0 ttl=64 time=0.086 ms docker@mhs-demo0:~$ ping -c 1 10.0.9.3 PING 10.0.9.3 (10.0.9.3): 56 data bytes ^C --- 10.0.9.3 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss 

然后在另一个主机上,容器被倒过来,但它仍然是可访问的本地容器。

 docker@mhs-demo1:~$ sudo ip ro add 10.0.9.0/24 dev docker_gwbridge docker@mhs-demo1:~$ ping 10.0.9.2 PING 10.0.9.2 (10.0.9.2): 56 data bytes ^C --- 10.0.9.2 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss docker@mhs-demo1:~$ ping 10.0.9.3 PING 10.0.9.3 (10.0.9.3): 56 data bytes 64 bytes from 10.0.9.3: seq=0 ttl=64 time=0.094 ms 64 bytes from 10.0.9.3: seq=1 ttl=64 time=0.068 ms 

所以最大的问题是networking需要知道容器在哪里运行,并相应地路由数据包。 如果networking能够实现这样的路由,你可能不会首先需要覆盖networking。

桥梁networking

另一种可能性是在每个具有可路由IP的Docker节点上使用一个普通网桥。 因此,每个网桥都有一个IP范围,可以指定您的networking知道并可以从任何地方路由到。

 192.168.9.0/24 10.10.2.0/24 Yarn DockerC router 10.10.0.0/24 10.10.1.0/24 DockerA DockerB 

这将附加到每个节点的networking。

 DockerA:$ docker network create --subnet 10.10.0.0/24 sparknet DockerB:$ docker network create --subnet 10.10.1.0/24 sparknet DockerC:$ docker network create --subnet 192.168.2.0/24 sparknet 

然后路由器通过DockerA等configuration路由10.10.0.0/24

这与Kubernetes的联网方式类似。

织网

编织类似于重叠,因为它创build了一个通过UDP传输数据的虚拟networking。 这是一个更广泛的networking解决scheme,但可以与主机networking集成 。