介绍 traefik 是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持 Docker, Swarm, Mesos/Marathon, Mesos, Kubernetes, Consul, Etcd, Zookeeper, BoltDB, Rest API 等等后端模型。
为什么选择 traefik?
Golang 编写,单文件部署,与系统无关,同时也提供小尺寸 Docker 镜像。
支持 Docker/Etcd 后端,天然连接我们的微服务集群。
内置 Web UI,管理相对方便。
自动配置 ACME (Let’s Encrypt) 证书功能。
性能尚可,我们也没有到压榨 LB 性能的阶段,易用性更重要。
Restful API 支持。
支持后端健康状态检查,根据状态自动配置。
支持动态加载配置文件和 graceful 重启。
支持 WebSocket 和 HTTP/2。
借用官网的图,一图以蔽之
需求 使用场景作为一个基于 Angular 的单页 App,与后端 Server 通过 RESTful 接口通信,前后端都需要提供 https 支持。使用场景很简单,暂时也没有负载均衡。
准备 根据 traefik 的官方文档中关于 ACME 的说明,Cloudflare 是支持宽域名自动发证书的。
把域名的 DNS 改成 Cloudflare 的
需要的是账户的邮箱地址和 Globel API key
配置 traefik 的配置文件。可以挂载到 docker 容器上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 logLevel = "ERROR" InsecureSkipVerify = true defaultEntryPoints = ["https" , "http" ][web] address = ":8080" [web.auth.basic] usersFile = "/shared/.htpasswd" [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [entryPoints.ws] [entryPoints.wss] [file] watch = true filename = "/etc/traefik/rules.toml" [acme] email = "yong.gu@qlink.mobi" storage ="/etc/traefik/acme/acme.json" entryPoint = "https" acmeLogging =true onDemand = false [acme.dnsChallenge] provider = "cloudflare" delayBeforeCheck = 0 [[acme.domains]] main = "example.com" [[acme.domains]] main = "*.example.com" [docker] endpoint = "unix:///var/run/docker.sock" domain = "example.com" watch = true exposedbydefault = false
注:需要发证书的域名在 acme.domains
中配置,这里以 example.com
为例。
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 version: "3.5" services: qlc_wallet_server: image: qlcwallet-server:latest container_name: qlc_wallet_server ports: - "127.0.0.1:8888:8888" networks: - qlcwallet - traefik environment: - DB_PASS=/run/secrets/db_root_password volumes: - type: bind source: ./wallet-server/.env target: /app/config/.env - type: bind source: ./wallet-server/logs target: /var/log/wallet-server secrets: - db_root_password restart: always labels: - "traefik.enable=true" - "traefik.backend=qlc_wallet_server" - "traefik.api.port=8888" - "traefik.api.frontend.rule=Host:api.example.com" - "traefik.docker.network=traefik" qlc_wallet: image: qlcwallet:latest container_name: qlcwallet ports: - "127.0.0.1:4200:80" networks: - qlcwallet - traefik depends_on: - qlc_wallet_server restart: always labels: - "traefik.enable=true" - "traefik.backend=qlc_wallet" - "traefik.port=80" - "traefik.frontend.rule=Host:wallet.example.com" - "traefik.docker.network=traefik" traefik: hostname: traefik image: traefik:latest container_name: traefik restart: always domainname: example.com networks: - qlcwallet - traefik ports: - "80:80" - "443:443" - "8080:8080" environment: - CLOUDFLARE_EMAIL=/run/secrets/traefik_user - CLOUDFLARE_API_KEY=/run/secrets/traefik_api labels: - "traefik.enable=true" - "traefik.backend=traefik" - "traefik.frontend.rule=Host:traefik.example.com" - "traefik.port=8080" - "traefik.docker.network=traefik" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik:/etc/traefik - ./shared:/shared secrets: - traefik_api - traefik_user networks: qlcwallet: name: qlcwallet traefik: name: traefik secrets: db_root_password: file: ./secrets/db_password.txt traefik_api: file: ./secrets/api.txt traefik_user: file: ./secrets/user.txt
这部分包含三部分
qlc_wallet_server RESTful 服务器
qlc_wallet Angular 应用
traefik traefik 本身自带一个简单的 Web 后台,绑定在 8080 端口,可以选择性开启。
这里以 labels 的形式配置,生产环境建议通过 toml
文件的方式配置,这样修改配置不要重启容器。traefik 默认是不会把容器对外发布的,需要手动设置。traefik.port
需要设置成容器内部端口,而不是绑定的外部端口。
总结 总的来说,traefik 配置简单,可以非常快速的搭建测试环境,很方便地支持宽域名证书。另外官方说是支持单容器多端口绑定到不同的 url 上的,但是我一直没试成功。