由于自己的个人站点规模较小,所以没有使用 k8s 管理集群,而是使用了 Docker 自带的 Swarm 容器编排服务。
本文记录了在配置 Docker Swarm 自动发现路由时遇到的一些问题,以及摸索出来的可用实践。
1 部署 Traefik Stack
将 Traefik 服务部署在 manager 节点上,配置文件如下:
version: "3.8"
services:
traefik:
image: traefik:2.5
command:
- "--api.dashboard=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=overnet"
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
- "--entrypoints.aria2.address=:1080"
- "--certificatesresolvers.le.acme.httpchallenge=true"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=http"
- "--certificatesresolvers.le.acme.email=i.inf@outlook.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--accesslog"
- "--log"
ports:
- 80:80
- 443:443
volumes:
- traefik-certificates:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- overnet
deploy:
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.http.routers.http2https.rule=HostRegexp(`{any:.+}`)"
- "traefik.http.routers.http2https.entrypoints=http"
- "traefik.http.routers.http2https.middlewares=https-redirect"
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true"
# dashboard 配置
- "traefik.http.routers.api.rule=Host(`gateway.don.red`)"
- "traefik.http.routers.api.entrypoints=https"
- "traefik.http.routers.api.tls.certresolver=le"
# 获取 dashboard 提供器
# @ 后面变量表示提供者, 像之前的 hello-world 实际上省略了 @docker
- "traefik.http.routers.api.service=api@internal"
# 基本验证中间件
- "traefik.http.routers.api.middlewares=api-auth"
# 配置用户名密码,密码使用 openssl passwd -apr1 $PASSWORD 生成
# 注意将 $ 变为 $$
- "traefik.http.middlewares.api-auth.basicauth.users=iinfinity:$$apr1$$0D6e5rhj$$7xOqEiRRQ8JdID9FQDR1O0"
# 最最关键的一步,创建一个 noop 虚服务的 loadbalancer,port 随便选,不然上面的 label 配置不会生效
- "traefik.http.services.noop.loadbalancer.server.port=9999"
volumes:
traefik-certificates:
networks:
overnet:
external: true
2 部署测试 Stack
标记了 labels 的容器可以被 Traefik 发现并路由。
version: "3.8"
services:
hello:
image: tutum/hello-world:latest
networks:
- overnet
deploy:
mode: replicated
replicas: 2
placement:
constraints:
- node.role != manager
- node.labels.database != true
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 3
window: 30s
labels:
- "traefik.enable=true"
- "traefik.http.routers.hello.rule=Host(`test.don.red`)"
- "traefik.http.routers.hello.entrypoints=https"
- "traefik.http.routers.hello.tls.certresolver=le"
- "traefik.http.services.hello.loadbalancer.server.port=80"
networks:
overnet:
external: true
中间件举例
该服务部署于 https://775.ink,是一个简单的短网址服务。
- 首先使用
traefik.http.routers.tinyurl-angular.middlewares=tinyurl-redirect
指定中间件 - 然后配置中间件
traefik.http.middlewares.tinyurl-redirect.redirectregex.regex=^https://775.ink/(.{12})
labels:
- "traefik.enable=true"
- "traefik.http.routers.tinyurl-angular.rule=Host(`775.ink`)"
- "traefik.http.routers.tinyurl-angular.entrypoints=https"
- "traefik.http.routers.tinyurl-angular.tls.certresolver=le"
- "traefik.http.services.tinyurl-angular.loadbalancer.server.port=80"
- "traefik.http.routers.tinyurl-angular.middlewares=tinyurl-redirect"
- "traefik.http.middlewares.tinyurl-redirect.redirectregex.regex=^https://775.ink/(.{12})"
- "traefik.http.middlewares.tinyurl-redirect.redirectregex.replacement=https://api.775.ink/link/$${1}"