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

标签 docker nginx docker-compose reverse-proxy

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

  • nginx 作为反向代理(主要用于处理虚拟主机和 SSL,尽管这不在 nginx.conf 中)。
  • 一个 golang 网络应用程序。
  • 用于缓存的 redis。
  • 用于存储的 postgresql。

这会生成类似于以下内容的 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服务。

我想要的是只允许从外部接口(interface)访问代理服务。

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

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

docker network create -d overlay --internal backend 

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

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

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

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

最佳答案

如果您不希望外部可以访问这些端口,则不需要发布这些端口。容器始终可以通过公共(public) 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:

关于docker - 如何禁用对 docker swarm 中覆盖网络的外部访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46787896/

相关文章:

r - ShinyProxy Euler App 未运行 - 无法启动容器

python - 带有 python docker 容器的 AWS Lambda 的无效入口点

python - Django+Gunicorn+nginx Internal Server Error,错误在哪里,如何解决?

rest - 如何在 Heroku 上使用 REST API 后端优化静态文件服务

docker - 在 Docker 容器内访问 Docker

angular - 在Docker中部署Spring Boot和Angular应用时出现CORS错误

asp.net - 无法使用 Docker 在 Azure 上的 VM 上部署 ASP .net vnext 应用程序

java - Spring Security 无法使用 Nginx 服务器创建 SESSION

docker - 如何为 1.6.2 安装正确的 docker-compose 版本

docker - 在 Dockerfile 和 docker-compose 中编写什么来传递本地包