了解Docker网络隔离

时间:2019-03-01 15:22:17

标签: docker docker-compose

我已经创建了以下docker-compose文件...

version: '3'

services:
  db-service:
    image: postgres:11
    volumes:
      - ./db:/var/lib/postgresql/data
    expose: 
      - 5432
    environment:
      - POSTGRES_PASSWORD=mypgpassword
    networks:
      - net1
  pgadmin:
    image: dpage/pgadmin4
    volumes:
      - ./pgadmin:/var/lib/pgadmin
    ports:
      - 5000:80
    environment:
      - PGADMIN_DEFAULT_EMAIL=me@gmail.com
      - PGADMIN_DEFAULT_PASSWORD=mypass
    networks:
      - net1
networks:
  net1:
    external: false

通过阅读docker站点上的各种文档,我期望pgadmin容器将能够通过端口5432访问postgres容器,但我不应该能够直接从主机访问postgres。但是,我可以使用psql从主机访问数据库。

实际上,如果我注释了暴露行和端口行,我仍然可以从主机访问这两个容器。

我对此有什么想念?

编辑-我正在通过首先运行docker container inspect...来获取IP地址来访问容器。对于我正在使用的postgres容器

psql -h xxx.xxx.xxx.xxx -U postgres

它提示我输入密码,然后让我执行您期望的所有正常操作。

对于pgadmin容器,我将浏览器指向IP地址并获得pgadmin界面。

请注意,这两个都是从主机上的终端执行的,而不是从任何一个容器中执行的。我也注释掉了暴露命令,并且仍然可以访问postgres数据库。

3 个答案:

答案 0 :(得分:1)

docker-compose创建了一个网络,供这两个容器在运行时通过DNS服务相互通信,该DNS服务将按名称包含指向每个服务的指针。

因此,从pgadmin容器的角度来看,可以在主机名db-service下访问dbserver(因为这就是您在docker-compose.yml文件中命名的服务的名称)。

因此,流量不会像您想象的那样通过主机,而是通过上述网络。

要进行验证,请docker exec -it [name-of-pg-admin-container] /bin/sh并输入: ping db-service。您将看到docker提供了DNS解析,您甚至可以在其中打开与普通postgres端口的连接。

答案 1 :(得分:0)

Docker为每个容器分配一个内部IP地址。如果您碰巧有这个地址,而且碰巧可以访问,那么Doc​​ker不会做任何专门的事情来屏蔽它。特别是在Linux主机上,如果特定的Docker网络位于172.17.0.0/24上,则该主机可能具有172.17.0.1地址,并且特定的容器可能是172.17.0.2,并且他们可以通过这种方式相互通信。

使用Docker内部IP地址不是最佳实践。如果您删除并重新创建容器,其IP地址将会更改;在某些主机平台上,您甚至不能从同一主机直接访问专用IP地址;专用IP地址永远无法从其他主机访问。在日常使用中,您永远不要需要docker inspect一个容器。

您获得的重要隔离级别是,除非您明确发布端口(docker run -p选项,Docker Compose ports:选项),否则其他主机无法访问该容器。与标准应用程序相比,这里的设置更加统一:在容器内设置应用程序以侦听0.0.0.0(“所有主机接口”,通常是默认值),然后根据需要发布或不发布端口。如果主机有多个接口,则您只能在其中一个接口上发布端口(即使应用程序本身不支持该端口)。

答案 2 :(得分:-1)

这些容器通过网桥网络net1相互连接。

公开端口时,会在IPTABLES中创建端口转发以连接主机网络和net1。

停止在db-service中暴露5432端口,您会发现无法从主机连接到db-service。