Traefik 入手及簡單配置
Traefik 與 nginx 一樣,是一款反向代理的工具,至於使用他原因基於以下幾點
- 漂亮的 dashboard 介面
- 可基於容器 label 進行配置
- 對 prometheus 和 k8s 的整合
- 嘗試一下...
接下來講一下它的基本功能以及檔案配置
安裝
下載二進位制檔案,指定配置檔案,直接執行可以啟動。
./traefik -c traefik.toml 複製程式碼
當然,你也可以通過 docker 啟動,參考Traefik Get Started。
另外,如果需要使用 docker 啟動,需要所有的服務都在一個 network 中,或者設定 traefik 的 network 為 host。
啟動成功後,可以訪問 localhost:8080
訪問 Dashboard 頁面。
問題
nginx -t
日誌
[accessLog] # Sets the file path for the access log. If not specified, stdout will be used. # Intermediate directories are created if necessary. # # Optional # Default: os.Stdout # filePath = "./traefik-access.json" # Format is either "json" or "common". # # Optional # Default: "common" # format = "json" 複製程式碼
日誌檔案配置為 json
格式,方便除錯。同時,強烈推薦 jq ,一款 linux 下解析 json 的工具。
以下是兩個常用的命令,統計某個站點的請求以及響應時間。不過最好建議有專門的日誌系統去處理,可以獲取更完善的,更定製化的資訊。另外,traefik 無法檢視請求的 body。
# 篩選特定站點的請求 cat traefik-access.json | jq 'select(.["RequestHost"] == "shici.xiange.tech") | {RequestPath, RequestHost, DownstreamStatus, "request_User-Agent", OriginDuration}' # 篩選大於 300ms 的介面 cat traefik-access.json | jq 'select(.["RequestHost"] == "shici.xiange.tech" and .OriginDuration > 300000000) | {RequestPath, RequestHost, DownstreamStatus, "request_User-Agent", OriginDuration, DownstreamContentSize}' 複製程式碼
prometheus + grafana
jq
雖然可以分析日誌,但是適合做日誌的統計以及更細化的分析。
Prometheus 作為時序資料庫,可以用來監控 traefik 的日誌,支援更加靈活的查詢,報警以及視覺化。traefik 預設設定 prometheus 作為日誌收集工具。另外可以使用 grafana 做為 prometheus 的視覺化工具。
某個服務的平均響應時間

PromQL 為
sum(traefik_backend_request_duration_seconds_sum{backend="$backend"}) / sum(traefik_backend_requests_total{backend="$backend"}) * 1000 複製程式碼
某個服務響應時長大於 300ms 的請求的個數
TODO
統計請求數大於 10000 的服務
TODO
entryPoint
http
http 配置在 entryPoints
中,暴露出80埠。開啟 gzip
壓縮,使用 compress = true
來配置。
[entryPoints] [entryPoints.http] address = ":80" compress = true # 如果配置了此項,會使用 307 跳轉到 https [entryPoints.http.redirect] entryPoint = "https" 複製程式碼
考慮到隱私以及安全,不對外公開的服務可以配置 Basic Auth
, Digest Auth
或者 WhiteList
,或者直接搭建 VPN,在內網內進行訪問。如在我伺服器上 xiange.tech
對外公開, xiange.me
只能通過VPN訪問。
更多文件檢視Traefik entrypoints。
https
使用 Let's Encrypt
安裝證書後,在 entryPoints.https.tls.certificats
中指定證書位置。
[entryPoints] [entryPoints.https] address = ":443" compress = true [[entryPoints.https.tls.certificates]] certFile = "/etc/letsencrypt/live/xiange.tech/fullchain.pem" keyFile = "/etc/letsencrypt/live/xiange.tech/privkey.pem" 複製程式碼
另外,traefik 預設開啟 http2。
other
另外,如果需要暴露其它的端口出去,如 consul 的 8500,類似於 nginx 的 listen 指令。
可以設定
[entryPoints] [entryPoints.consul] address = ":8500" 複製程式碼
Docker
traefik 會監聽 docker.sock
,根據容器的 label 進行配置。容器的埠號需要暴露出來,但是不需要對映到 Host。因為 traefik 可以通過 docker.sock
找到 container 的 IP 地址以及埠號,無需使用 docker-proxy
轉發到 Host。
version: '3' services: frontend: image: your-frontend-server-image labels: - "traefik.frontend.rule=Host:frontend.xiange.tech" api: image: your-api-server-image expose: 80 labels: # 同域配置, /api 走server - "traefik.frontend.rule=Host:frontend.xiange.tech;PathPrefix:/api" 複製程式碼
如何給一個服務配置多個域名
labels: - "traefik.prod.frontend.rule=Host:whoami.xiange.tech" - "traefik.another.frontend.rule=Host:who.xiange.tech" - "traefik.dev.frontend.rule=Host:whoami.xiange.me" 複製程式碼
如何把前端和後端配置在統一域名
services: frontend: image: your-frontend-server-image labels: - "traefik.frontend.rule=Host:frontend.xiange.tech" api: image: your-api-server-image expose: 80 labels: - "traefik.frontend.rule=Host:frontend.xiange.tech;PathPrefix:/api" 複製程式碼
部署時,如果專案程式碼有更新,如何當新服務 start 後,再去 drop 掉舊服務
TODO
負載均衡
如果使用docker,對一個容器進行擴充套件後,traefik 會自動做負載均衡,而 nginx 需要手動干預。
version: '3' services: whoami: image: emilevauge/whoami labels: - "traefik.frontend.rule=Host:whoami.xiange.tech" 複製程式碼
手動擴充套件為3個例項,可以自動實現負載均衡。實現效果可以直接訪問whoami.xiange.tech,每次通過 WRR 策略分配到不同的容器處理,可以通過 Hostname 和 IP 欄位看出。
docker-compose up whoami=3 複製程式碼
手動配置
當然,以上反向代理配置都是基於 docker,那如何像 nginx 一樣配置呢。如把 consul.xiange.me
轉發到 8500 這個埠。可以利用 traefik 的 file provider。
[file] [backends] # consul 是服務的名字,也可以叫張三,也可以叫李四 [backends.consul] [backends.consul.servers] [backends.consul.servers.website] url = "http://0.0.0.0:8500" weight = 1 [frontends] [frontends.consul] entryPoints = ["http"] backend = "consul" [frontends.consul.routes] # website 是路由的名字,也可以叫阿貓,也可以叫阿狗 [frontends.consul.routes.website] rule = "Host:consul.xiange.me" # 可以配置多個域名 [frontends.consul.routes.website2] rule = "Host:config.xiange.me" 複製程式碼