【问题标题】:Exposing a Docker database service only on the internal network with Traefik使用 Traefik 仅在内部网络上公开 Docker 数据库服务
【发布时间】:2019-02-15 08:17:41
【问题描述】:

假设我在 docker-compose.yml 中定义了两个服务“frontend”和“db”,它们部署到 Docker swarm,即它们也可以在不同的堆栈中运行。有了这个设置,Traefik 会自动为每个堆栈生成前端和后端,这很好。

现在我在 Jenkins 管道中临时运行了另一个 Docker 容器,它应该能够访问特定堆栈中的 db 服务。我的第一个想法是通过将db 服务添加到cluster-global-net 网络来公开db 服务,以便Traefik 可以生成到bakend 的前端路由。这基本上有效。

但我想对“公众”隐藏数据库服务,同时仍然能够使用内部“默认”网络通过其堆栈或服务名称将另一个 Docker 容器连接到它。

这可以通过某种方式完成吗?

version: '3.6'

networks:
  default: {}
  cluster-global-net:
    external: true

services:
  frontend:
    image: frontend_image
    ports:
    - 8080
    networks:
    - cluster-global-net
    - default
    deploy:
      labels:
        traefik.port: 8080
        traefik.docker.network: cluster-global-net
        traefik.backend.loadbalancer.swarm: 'true'
        traefik.backend.loadbalancer.stickiness: 'true'
      replicas: 1
      restart_policy:
        condition: any

  db:
    image: db_image
    environment:
    - MYSQL_ALLOW_EMPTY_PASSWORD=false
    - MYSQL_DATABASE=db_schema
    - MYSQL_USER=db_user
    - MYSQL_PASSWORD=db_pass
    ports:
    - 3306
    volumes:
    - db_volume:/var/lib/mysql
    networks: 
    - default
    restart: on-failure
    deploy:
      labels:
        traefik.port: 3306
        traefik.docker.network: default

【问题讨论】:

    标签: docker docker-compose docker-swarm traefik


    【解决方案1】:

    您需要的是一个部署了这两者的网络,但其他人看不到它。

    为此,请创建一个网络,将其添加到您的数据库服务和前端,以及您的临时服务中。事实上,删除 db 上的 traefik 标签,因为这里不再需要它们。

    EG:

    ...
    networks:
      default: {}
      cluster-global-net:
        external: true
      db-net:
        external: true
    
    services:
      frontend:
        image: frontend_image
        networks:
        - cluster-global-net
        - default
        - db-net
        deploy:
            ...
    
      db:
        image: db_image
        ...
        networks: 
        - default
        - db-net
        restart: on-failure
        #no labels
    


    docker network create db-net 
    docker stack deploy -c <mycompose.yml> <myfront>
    docker service create --network db-net <myTemporaryImage> <temporaryService>
    

    那么temporaryService和frontend就可以通过db:3306

    到达db

    顺便说一句:您不需要为前端打开端口,因为 traefik 将在内部访问它(trafik.port)。

    EDIT:从撰写文件创建网络的新示例。

    ...
    networks:
      default: {}
      cluster-global-net:
        external: true
      db-net: {}
    
    services:
      frontend:
        image: frontend_image
        networks:
        - cluster-global-net
        - default
        - db-net
        deploy:
            ...
    
      db:
        image: db_image
        ...
        networks: 
        - default
        - db-net
        restart: on-failure
        #no labels
    


    docker stack deploy -c <mycompose.yml> someStackName
    docker service create --network someStackName_db-net <myTemporaryImage> <temporaryService>
    

    【讨论】:

    • db-net定义为外部是必要的,以便临时服务可以连接,因为它没有在撰写文件中定义?
    • 不,不是。唯一的缺点是,如果您从 compose 中创建它,然后从 compose 外部使用它,则必须将其引用为 stackname_db-net。
    • 没关系,因为我可以控制堆栈名称。将尝试您的解决方案...
    • 否:如果您从 compose 中创建网络,则 external:true 不是强制性的。我将在我的答案中添加另一个示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2012-11-05
    相关资源
    最近更新 更多