Docker集群背后的Traefik 2.0无法正常工作

时间:2019-10-16 10:24:44

标签: docker-swarm traefik

因此,我正在尝试使用Traefik通过docker swarm平衡我的Web应用程序。

但是,我已经尝试了许多配置,但是不知为何。我已经阅读了文档并阅读了互联网上的一些文章。不幸的是,许多文章引用了traefik 1.x而不是traefik 2.0。

这是我的traefik的docker-stack.yml

version: '3.7'
services:
  traefik:
    image: traefik:2.0
    deploy:
      mode: global
      placement:
        constraints:
        - node.role == manager
      restart_policy:
        condition: on-failure
      labels:
      - traefik.docker.network=load_balancer
    configs:
    - source: traefik
      target: /etc/traefik/traefik.yml
    ports:
    - 80:80
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    networks:
    - load_balancer
configs:
  traefik:
    file: ./traefik.yml
networks:
  load_balancer:
    external: true
    name: load_balancer

whoami.yml(用于测试)

version: '3.7'
services:
  whoami:
    image: containous/whoami
    deploy:
      labels:
      - traefik.enable=true
      - traefik.docker.network=load_balancer
      - traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)
    networks:
    - load_balancer
networks:
  load_balancer:
    external: true
    name: load_balancer

我的traefik.yml

log:
  level: DEBUG

api:
  insecure: true

providers:
  docker:
    exposedByDefault: false
    swarmMode: true
    watch: true

docker network ls

hxjw9rytw3od        load_balancer       overlay             swarm

curl -H主机:whoami.docker.localhost http://127.0.0.1

404 page not found

5 个答案:

答案 0 :(得分:0)

也许您必须在配置中添加入口点声明:https://docs.traefik.io/routing/entrypoints/

答案 1 :(得分:0)

使用Docker的Traefik服务发现需要container labels instead of image labels(选中traefik's quickstart)。

以下最小工作示例适用于docker swarm:

version: '3.7'

services:
  traefik:
    image: traefik:2.0
    command: --providers.docker
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  whoami:
    image: containous/whoami
    labels:   # defining a container label instead of an image label
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"

答案 2 :(得分:0)

我建议您不要使用traefik.yml,而是使用cli args配置实例。

您可以这样:

version: "3.7"

services:
  ingress:
    image: traefik:v2.0
    networks:
      - ingress-net
    ports:
      - "80:80"
      - "443:443"
      # TCP Port if needed for any service you have
      - "60000:60000"
    command:
      ###                          ###
      # Traefik Global Configuration #
      ###                          ###
      # Enable DEBUG logs
      - "--log.level=DEBUG" # DEBUG, INFO, etc...
      - "--ping=true"
      # Enable api access without authentification (only GET route so it only possible to get IPs)
      - "--api.insecure=true" # You can insecure here, because It accessible only in the container if you didn't open the port.
      # Set the provider to Docker
      - "--providers.docker=true"
      # Set the docker network
      - "--providers.docker.network=ingress-net"
      # Set to docker swarm cluster
      - "--providers.docker.swarmMode=true"
      # If False : Do not expose containers to the web by default
      - "--providers.docker.exposedByDefault=false"
      # Default rule to service-name.example.com
      - "--providers.docker.defaultRule=Host(`{{ trimPrefix `/` .Name }}.example.com`)"
      # Default http port
      - "--entrypoints.http.address=:80"
      # Default https port
      - "--entrypoints.https.address=:443"
      # Enable let's encrypt
      - "--certificatesResolvers.certbot=true"
      - "--certificatesResolvers.certbot.acme.httpChallenge=true"
      - "--certificatesResolvers.certbot.acme.httpChallenge.entrypoint=http"
      - "--certificatesResolvers.certbot.acme.email=admin@example.com"
      - "--certificatesResolvers.certbot.acme.storage=/letsencrypt/acme.json"
      # TCP Entrypoint if needed
      - "--entrypoints.tcpendpointname.address=:60000"

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./acme.json:/letsencrypt/acme.json

    deploy:
      replicas: 1
      labels:
        ###               ###
        # Traefik Dashboard #
        ###               ###
        # Enable this endpoint
        - traefik.enable=true
        ##
        # Http
        #
        # Set the service route
        - traefik.http.routers.ingress_http.rule=Host(`ingress.example.com`)
        # Set the entrypoint (http or https)
        - traefik.http.routers.ingress_http.entrypoints=http
        # Rule to redirect to http to https
        - traefik.http.middlewares.ingress-https-redirect.redirectscheme.scheme=https
        # Enable Https redirection
        - traefik.http.routers.ingress_http.middlewares=ingress-https-redirect@docker
        #
        ##

        ##
        # Https
        #
        - traefik.http.routers.ingress_https.rule=Host(`ingress.example.com`)
        # Set the entrypoint (http or https)
        - traefik.http.routers.ingress_https.entrypoints=https
        # Enable Let's encrypt auto certificat creation
        - traefik.http.routers.ingress_https.tls.certresolver=certbot
        # Enable authentification
        - traefik.http.routers.ingress_https.middlewares=ingress-auth@
        # Uncommant this to enable basic authentification
        # - traefik.http.middlewares.ingress-auth.basicauth.users=admin:$$this$$is$$encrypted$$password
        #
        ##

        ##
        # TCP Endpoint
        #
        # Set the service route
        - "traefik.tcp.routers.tcpendpointname.rule=HostSNI(`*`)"
        # Here you can set the host uri if you use tls only.
        # - "traefik.tcp.routers.tcpendpointname.rule=HostSNI(`tcp.example.com`)"
        # - "traefik.tcp.routers.tcpendpointname.tls=true"
        # Set the entrypoin
        - "traefik.tcp.routers.tcpendpointname.entrypoints=tcpendpointname"
        #
        ##

        ##
        # Service
        #
        # Set the service port
        - traefik.http.services.ingress.loadbalancer.server.port=8080
        #
        ##
      placement:
        constraints:
          - node.role == manager

networks:
  ingress-net:
    external: true

希望这会对您有所帮助。

您可以对使用相同逻辑的任何其他容器使用相同的标签。

答案 3 :(得分:0)

由于您拥有404 page not found Traefik,因此似乎可以使用。

但是,当使用 curl 来获取http://127.0.0.1时,此IP地址将成为请求的Host标头字段的内容。依次由Traefik用于路由请求。由于您的whoami服务旨在匹配对主机whoami.docker.localhost的请求,因此Traefik的给定响应就可以了。

您是否尝试过获取http://whoami.docker.localhost?在使用 curl 进行测试之前,您可能需要将此主机名注入主机 / etc / hosts 文件中。

127.0.0.1 whoami.docker.localhost

(可选)您可以尝试使用 netcat 之类的工具(有时以 nc 使用)进行手动HTTP请求:

# netcat 127.0.0.1 80
GET / HTTP/1.0
Host: whoami.docker.localhost

根据HTTP要求输入第二行请求后,您需要按Enter键两次。

答案 4 :(得分:0)

端口检测

Docker Swarm不向Traefik提供任何port detection信息。

因此,您必须使用标签traefik.http.services。 .loadbalancer.server.port指定用于通信的端口(请检查routing section for Docker中此标签的引用)。