Traefik 與 nginx 一樣,是一款反向代理的工具,至於使用他原因基於以下幾點
- 漂亮的 dashboard 介面
- 可基於容器 label 進行配置
- 新添服務簡單,不用像 nginx 一樣複雜配置,並且不用頻繁重啟
- 對 prometheus 和 k8s 的整合
- 嘗試一下...
接下來講一下它的基本功能以及檔案配置
安裝
下載二進位制檔案,指定配置檔案,直接執行可以啟動。
./traefik -c traefik.toml
複製程式碼
當然,你也可以通過 docker 啟動,參考 Traefik Get Started。
另外,如果需要使用 docker 啟動,需要所有的服務都在一個 network 中,或者設定 traefik 的 network 為 host。
啟動成功後,可以訪問 localhost:8080
訪問 Dashboard 頁面。
問題
- 每當有配置改動需要重啟時,只能殺了程式,然後啟動,導致服務有短暫的暫停
- 補充一下,每當使用 docker 新添一個服務時,不需要更改配置,或者更改部分配置時,如 file provider,traefik 會監聽配置檔案變化並自動重啟。但是需要修改 https 的證書或者日誌的路徑時,需要手動重啟。所以需要手動重啟的時候並不是很多。
- 當配置檔案修改後,會有語法錯誤,無法向
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"
複製程式碼