Traefik: http, https, ws, wss в том же домене (docker swarm)

Я пытаюсь настроить traefik для обслуживания http, https, ws, wss в том же домене. Вот мой traefik init (docker-compose.yml):

    command:
      - "storeconfig"
      - "--api"
      - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entrypoints=Name:https Address::443 TLS"
      - "--entrypoints=Name:ws Address::8081 Redirect.EntryPoint:wss"
      - "--entrypoints=Name:wss Address::8083 TLS"
      - "--defaultentrypoints=http,https"
      - "--acme"
      - "--acme.entryPoint=https"
      - "--acme.httpChallenge.entryPoint=http"
      - "--acme.onHostRule=true"
      - "--acme.onDemand=false"
      - "--acme.email=${EMAIL}"
      - "--acme.storage=etc/traefik/acme/acme.json"
      - "--docker"
      - "--docker.swarmMode"
      - "--docker.watch"

И разверните метки для службы ws / wss:

    deploy:
      labels:
        - traefik.enable=true
        - traefik.backend=ws-container-name
        - traefik.frontend.rule=Host:myhost
        - traefik.frontend.entryPoints=ws,wss
        - traefik.docker.network=traefik
        - traefik.port=9001

Результат: ws работает, wss - нет.

 % wscat -c ws://myhost:8081 
connected (press CTRL+C to quit)
 % wscat -c wss://myhost:8083
error: unable to verify the first certificate

http, https (другой контейнер) работает хорошо

Почему traefik не выдает сертификаты для wss?


person Eddie    schedule 05.10.2019    source источник
comment
Чтобы помочь другим вам помочь, было бы предпочтительнее, если бы вы предоставили минимальный рабочий пример. В этом случае вы можете собрать docker-compose.yml, который запускает traefik, вместе с парой эхо-сервисов, которые вы хотите протестировать.   -  person RAM    schedule 26.10.2019
comment
Я решил проблему с обновлением traefik до v2, так как в v1.7 это казалось невозможным. Я разместил ответ ниже.   -  person Eddie    schedule 27.10.2019


Ответы (1)


Решение - обновить traefik до версии 2

Пример конфигурации:

services:
  traefik:
    image: traefik:v2.0
    command:
      - "--accesslog=true"
      - "--log.level=ERROR"
      - "--api.insecure=true"
      - "--providers.docker"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.exposedByDefault=false"
      - "--providers.docker.network=traefik"
      - "--providers.docker.watch=true"
      - "--entryPoints.http.address=:80"
      - "--entryPoints.https.address=:443"
      - "--entryPoints.ws.address=:8081"
      - "--entryPoints.wss.address=:8083"
      - "[email protected]"
      - "--certificatesResolvers.dns.acme.storage=/letsencrypt/acme.json"
      # Using DNS challenge is important to support a service without http protocol
      - "--certificatesResolvers.dns.acme.dnsChallenge=true"
      - "--certificatesResolvers.dns.acme.dnsChallenge.provider=godaddy"
      # ...
  http-service:
    # ...
    deploy:
      labels:
        - traefik.enable=true
        # important to tell traefik that swarm is load balancer
        - traefik.docker.lbswarm=true
        # redirect http
        - traefik.http.middlewares.http-redirect.redirectregex.regex=^http://(.*)
        - traefik.http.middlewares.http-redirect.redirectregex.replacement=https://$${1}
        # backend port
        - traefik.http.services.http.loadbalancer.server.port=80
        # http
        - traefik.http.routers.http.middlewares=http-redirect
        - traefik.http.routers.http.rule=Host(`example.com`)
        - traefik.http.routers.http.entrypoints=http
        # https
        - traefik.http.routers.https.rule=Host(`example.com`)
        - traefik.http.routers.https.entrypoints=https
        - traefik.http.routers.https.tls=true
        - traefik.http.routers.https.tls.certresolver=dns
  ws-service:
    # ...
    deploy:
      labels:
        - traefik.enable=true
        - traefik.docker.lbswarm=true
        # backend port
        - traefik.http.services.ws-service.loadbalancer.server.port=9001
        # ws
        - traefik.http.routers.ws-service-ws.rule=Host(`example.com`)
        - traefik.http.routers.ws-service-ws.entrypoints=ws
        # wss
        - traefik.http.routers.ws-service-wss.rule=Host(`example.com`)
        - traefik.http.routers.ws-service-wss.entrypoints=wss
        - traefik.http.routers.ws-service-wss.tls=true
        - traefik.http.routers.ws-service-wss.tls.certresolver=dns
person Eddie    schedule 27.10.2019
comment
Спасибо за пример. Однако кажется, что конфигурация http-service относится к службе nginx вместо http-service. Это намеренно? - person RAM; 28.10.2019
comment
Спасибо за уведомление. Нет, это не намеренно, так как я забыл заменить его при копировании кода из моего проекта. Исправлено =) - person Eddie; 29.10.2019