如何在docker swarm中禁用对覆盖网络的外部访问

时间:2017-10-17 10:23:11

标签: docker nginx docker-compose reverse-proxy

我正在尝试设置一个具有以下服务的群:

  • nginx作为反向代理(主要用于处理虚拟主机和SSL,但不在nginx.conf中)。
  • 一个golang网络应用。
  • redis for caching。
  • postgresql for storage。

这导致docker-compose文件类似于:

version: '3'
services:
  proxy:
    image: nginx:1.13.5-alpine
    ports:
      - "80:80"
    deploy:
      placement:
        constraints: [node.role == manager]
    depends_on:
      - api
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - webnet

  api:
    image: user/webapp:latest
    deploy:
      replicas: 4
    ports:
      - "8000:8000"
    depends_on:
      - postgres
      - redis
    networks:
      - webnet

  postgres:
    image: postgres:9.6.5-alpine
    ports:
      - "5432:5432"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet

  redis:
    image: redis:4.0.2-alpine
    ports:
      - "6379:6379"
    deploy:
      placement:
        constraints: [node.role == manager]
    command: redis-server --appendonly yes
    networks:
      - webnet

networks:
  webnet:

我使用的nginx配置文件是:

upstream api {
    server api:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://api;
    }
}

这一切都有效。我可以使用curl和nginx服务代理从另一台机器连接到相应的webapp服务。

问题是,我还可以从外部机器连接到redis,api和postgres服务。

我想要的是只从外部接口访问代理服务。

我想确保redis,api和postgres服务只能通过swarm访问。 (或者,只能在主机节点的本地网络上访问。在这种情况下,主机是CentOS 7设置为群集管理器。)

我尝试创建一个名为后端的覆盖网络,而不是使用网络,将internal设置为true。像这样:

docker network create -d overlay --internal backend 

然后在docker-compose.yml文件中使用backend网络而不是用于redis,postgres和api服务的webnet。这似乎不起作用。所有服务仍可在外部IP上使用。

我可以通过以下方式解决此问题:

  • 阻止我不想公开的服务的端口。
  • 执行上述操作并在主机上运行nginx作为代理(而不是容器)。

虽然上述方法确实有效,但我真的更喜欢所有这些逻辑都在docker-compose级别强制执行,而不是依赖防火墙或外部进程。

1 个答案:

答案 0 :(得分:2)

如果您不希望外部访问端口,则无需发布这些端口。容器总是可以通过公共docker网络将容器与容器通信,而不会发布端口。

version: '3'
services:
  proxy:
    image: nginx:1.13.5-alpine
    ports:
      - "80:80"
    deploy:
      placement:
        constraints: [node.role == manager]
    depends_on:
      - api
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - webnet

  api:
    image: user/webapp:latest
    deploy:
      replicas: 4
    depends_on:
      - postgres
      - redis
    networks:
      - webnet

  postgres:
    image: postgres:9.6.5-alpine
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet

  redis:
    image: redis:4.0.2-alpine
    deploy:
      placement:
        constraints: [node.role == manager]
    command: redis-server --appendonly yes
    networks:
      - webnet

networks:
  webnet: