首页 > 解决方案 > Docker swarm 模式、搬运工、traefik

问题描述

我正在尝试将网络服务器设置为 Docker Swarm 模式。任何帮助表示赞赏。

我的想法是配置一台机器,暂时独立运行,但准备好扩展以实现负载平衡和容错目的。我希望 traefik 在我的所有节点上运行,而不仅仅是在主节点上运行,正如我在一些示例中看到的那样。

当前问题:

另一个问题是是否可以使用 docker swarm 集成键/值而不是 Consul

我的部署文件如下:

version: "3.7"
services:

  # swarm_socket
  #   Increase security in case of attack attempt
  swarm_socket:
    image: alpine/socat
    command: tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - net_mgmt
    deploy:
      placement:
        constraints:
          - node.role == manager
          - node.platform.os == linux

  # swarm_kv
  #   Key/Value store for traefik cluster
  swarm_kv:
    image: consul
    command: agent -server -client='{{ GetInterfaceIP "eth0" }}' -bind='{{ GetInterfaceIP "eth0" }}' -bootstrap
    volumes:
      - swarm_kv_data:/consul/data
    networks:
      - net_mgmt
    deploy:
      mode: global
      update_config:
        parallelism: 1
        failure_action: rollback
        delay: 30s
        monitor: 15s
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 10
        window: 60s
      placement:
        constraints:
          - node.role == manager
          - node.platform.os == linux

  # traefik_init
  #   Init traefik config
  traefik_init:
    image: traefik:1.7
    depends_on:
      - swarm_socket
    command:
      - "storeconfig"
      - "--logLevel=DEBUG"
      - "--api"
      - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entrypoints=Name:https Address::443 TLS"
      - "--defaultentrypoints=http,https"
      - "--acme"
      - "--acme.storage=traefik/acme/account"
      - "--acme.entryPoint=https"
      - "--acme.httpChallenge.entryPoint=http"
      - "--acme.onHostRule=true"
      - "--acme.onDemand=false"
      - "--acme.acmeLogging=true"
      - "--acme.email=mail@example.com" # Set your email
      - "--docker"
      - "--docker.swarmmode=true"
      - "--docker.endpoint=tcp://swarm_socket:2375"
      - "--docker.watch=true"
      - "--docker.exposedbydefault=false"
      - "--docker.domain=example.com" # Set your domain
      - "--consul"
      - "--consul.endpoint=swarm_kv:8500"
      - "--consul.prefix=traefik"
    networks:
      - net_mgmt
      - net_public
    deploy:
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.role == manager
          - node.platform.os == linux

  # traefik
  #   Traefik cluster
  traefik:
    image: traefik:1.7
    depends_on:
      - swarm_socket
      - traefik_init
    command:
      - "--docker"
      - "--docker.swarmmode=true"
      - "--docker.endpoint=tcp://swarm_socket:2375"
      - "--consul"
      - "--consul.endpoint=swarm_kv:8500"
      - "--consul.prefix=traefik"
    networks:
      - net_mgmt
      - net_public
    ports:
      - 80:80
      - 443:443
      - 8080:8080 # Remove after that config works
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.port=8080"
        - "traefik.docker.network=net_public"
        - "traefik.frontend.rule=Host:traefik.example.com" # Set you domain
        - "traefik.frontend.auth.basic.users=[sgobbit:$apr1$hpnuX1jh$IXu2P4aae0weviroUxP4S1]"
      mode: global
      placement:
        constraints:
          - node.platform.os == linux

  # catchall
  #   Catch all unmanaged domain and show a dedicated page
  catchall:
    image: mikesir87/cats # Replace with real static page
    networks:
      - net_public
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.port=5000"
        - "traefik.protocol=http"
        - "traefik.backend=catchall"
        - "traefik.docker.network=net_public"
        - "traefik.frontend.rule=HostRegexp:{catchall:.*}"
        - "traefik.frontend.priority=2"
        - "traefik.frontend.entryPoints=http,https"
        - "traefik.backend.loadbalancer.swarm=true"
        - "traefik.backend.loadbalancer.method=drr"
        - "traefik.backend.loadbalancer.stickiness=true"
      restart_policy:
        condition: on-failure
      update_config:
        parallelism: 1
        delay: 10s
      placement:
        constraints:
          - node.platform.os == linux

  # portainer_agent
  #   Agent that run on all nodes
  portainer_agent:
    image: portainer/agent
    environment:
      AGENT_CLUSTER_ADDR: tasks.portainer_agent
      AGENT_PORT: 9001
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - net_mgmt
    deploy:
      mode: global
      placement:
        constraints:
          - node.platform.os == linux

  # portainer
  #   Web UI to manage the cluster
  portainer:
    image: portainer/portainer
    depends_on:
      - portainer_agent
    command: -H tcp://tasks.portainer_agent:9001 --tlsskipverify
    volumes:
      - portainer_data:/data
    networks:
      - net_mgmt
      - net_public
    ports: # Remove after that config works
      - 9000:9000 # Remove after that config works
    labels:
      - "traefik.enable=true"
      - "traefik.port=9000"
      - "traefik.docker.network=net_public"
      - "traefik.backend=portainer"
      - "traefik.frontend.rule=Host:portainer.example.com" # Set you domain
      - "traefik.frontend.priority=1"
      - "traefik.backend.loadbalancer.swarm=true"
      - "traefik.backend.loadbalancer.method=drr"
      - "traefik.backend.loadbalancer.stickiness=true"
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.role == manager
          - node.platform.os == linux

volumes:
  swarm_kv_data: # Storage Key/Value
  portainer_data: # Storage portainer

networks:
  net_mgmt:
    driver: overlay
    external: true
  net_public:
    driver: overlay
    external: true

标签: traefikdocker-swarm-modesocatportainerconsul-kv

解决方案


  1. Traefik 文档说要为 Let's Encrypt 信息启用 acme 日志记录:acmeLogging = true
  2. 在http://dogvs.cat上查看我的 Portainer 和 Traefik 以及更多的 Swarm 示例
  3. 使用 Swarm raft log 而不是 consul 进行 traefik?不,作为最终用户是不可能的。

推荐阅读