docker链接容器所有端口关闭

时间:2015-11-12 09:51:23

标签: linker docker containers derby

我尝试从一个docker容器连接到另一个。

  • Container A安装并启动了Derby DB,侦听端口3301
  • 容器B应连接到容器A

docker文件如下所示: 容器A

FROM java:8

# Install Derby
COPY db-derby-10.12.1.1-bin.tar.gz db-derby-10.12.1.1-bin.tar.gz

RUN mkdir /opt/Apache 
RUN cp db-derby-10.12.1.1-bin.tar.gz /opt/Apache 
RUN tar xzvf /opt/Apache/db-derby-10.12.1.1-bin.tar.gz

EXPOSE 3301
CMD ["/db-derby-10.12.1.1-bin/bin/startNetworkServer", "-p 3301"]

容器B

FROM java:8 

# Install nmap
RUN apt-get update
RUN apt-get install -y nmap
COPY db-derby-10.12.1.1-bin.tar.gz db-derby-10.12.1.1-bin.tar.gz

RUN mkdir /opt/Apache 
RUN cp db-derby-10.12.1.1-bin.tar.gz /opt/Apache 
RUN tar xzvf /opt/Apache/db-derby-10.12.1.1-bin.tar.gz
EXPOSE 9080

我启动两个容器并给它们命名 容器A

docker run -it --name derby <image>

容器B

docker run -it --link derby:derby <image> /bin/bash

然后我附上容器B和

ping derby or ping 172.17.0.2

这是成功的。但是当我尝试通过cli工具连接到derby数据库并给出像

这样的jdbc url时
connect 'jdbc:derby://172.17.0.2:3301/testdb;create=true';

我收到连接拒绝错误。

使用nmap扫描容器A的端口会导致“所有端口都关闭” 这是令人困惑的,因为Docker References声明:

  

那么连接容器实际上做了什么?你已经学会了   link允许源容器提供有关其自身的信息   收件人容器。在我们的示例中,收件人Web可以访问   有关源数据库的信息。为此, Docker创建了一个安全的   容器之间的隧道,不需要暴露任何端口   在容器外部;当我们启动数据库时你会注意到   容器我们没有使用-P或-p标志。那太大了   链接的好处:我们不需要在这里公开源容器   PostgreSQL数据库,到网络。

有人可能会给我一些提示或解决方案吗?

此致

2 个答案:

答案 0 :(得分:1)

The port is not open as you have not told docker to open it.

EXPOSE in the Dockerfile instructs docker that the container listens on the specified port, but it does NOT open that port or expose it to the host.

--link doesn't open ports either, that is the benefit of link, you can securely connect 2 containers without having to expose any ports to the host.

So, to connect to the derby BD with your command line tool you have 2 options.

1) Open the port - (possible security implications?)

When you run the container, you specificy the port to open.

docker run -it --name derby -p 3301:3301 <image>

The above will map the 3301 port on the container to the 3301 port on the host.

Then you can use the host IP and port 3301 to connect to that container.

2) Connect to the container directly

You can effectively ssh in to the container and run the command on the container itself...

$ sudo docker exec -it derby bash

And then you have a bash session on the derby container directly, and can run commands on it.

UPDATE

To connect from one container to another over the link you can use the ENV vars that docker exposes on the container about the link. http://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#environment-variables

So, on container B you will have ENV vars containing the link name DERBY.

So, DERBY_PORT will be a IP and PORT to connect to the derby container.

However, if the "derby" container is restarted, the IP in the ENV var will be out of date. So it is better to connect to it by its link name.

Docker also sets up host names about the links, so you can connect to the derby container with

http://derby:3301

from within container B

So you could try..

connect 'jdbc:derby://derby:3301/testdb;create=true';

答案 1 :(得分:1)

好吧,我解决了。对于可能被强制关注的所有其他人,您需要使用命令

启动Derby
startNetworkServer -h 0.0.0.0

通过这种方式告诉Derby接受来自外部的所有连接,如果需要则限制它,但必须存在参数,否则拒绝连接。

此致