更簡單的 Traefik 2 使用方式

更簡單的 Traefik 2 使用方式
經過一年多的實踐,對於使用 Traefik 有了一些更深入的體會,本篇先來介紹如何簡化使用,後續會逐步展開聊聊如何在雲上使用這款“雲原生”工具,以及結合它做一些提升業務效率和開發效率的實踐。

在 Traefik 2 使用指南,愉悅的開發體驗、配置基於Traefik v2的 Web 服務器 文章中,使用 Traefik 的方案引入了比較多的配置,如果你並不是在一個複雜場景使用,這樣的配置是可以簡化的。

簡化程序配置文件
一般情況下將參數變爲配置,更利於在版本控制軟件中進行版本管理。在 v2 版本中,因爲有了動態配置的概念,傳統的固定配置,使用簡寫的參數來替換,並記錄在容器啓動配置中,可以在減少分發文件數量的情況下,達到相同的效果。

使用參數取代 traefik.toml
在之前的文章中,我提供了一般情況下,使用的默認配置內容:


[global]
  checkNewVersion = false
  sendAnonymousUsage = false

[log]
  level = "WARN"
  format = "common"

[api]
  dashboard = true
  insecure = true

[ping]

[accessLog]

[providers]
  [providers.docker]
    watch = true
    exposedByDefault = false
    endpoint = "unix:///var/run/docker.sock"
    swarmMode = false
    useBindPortIP = false
    network = "traefik"
  [providers.file]
    watch = true
    directory = "/etc/traefik/config"
    debugLogGeneratedTemplate = true

[entryPoints]
  [entryPoints.http]
    address = ":80"
  [entryPoints.https]
    address = ":443"

想要達到相同的效果,只需要在 command 字段內添加下面的內容即可:

version: '3'

services:

  traefik:
...
    command:
      - "--global.sendanonymoususage=false"
      - "--global.checknewversion=false"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--api.debug=false"
      - "--ping=true"
      - "--log.level=warn"
      - "--log.format=common"
      - "--accesslog=false"
      - "--providers.docker=true"
      - "--providers.docker.watch=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.swarmMode=false"
      - "--providers.docker.useBindPortIP=false"
      - "--providers.docker.network=traefik"
      - "--providers.file=true"
      - "--providers.file.watch=true"
      - "--providers.file.directory=/etc/traefik/config"
      - "--providers.file.debugloggeneratedtemplate=true"
...

現在,你就可以將 traefik.toml 配置文件刪除掉了。

簡化 dashboard.toml
前文中,我們將 Traefik 的內置 dashboard 等路由通過配置文件來定義,像下面這樣。


[http.middlewares.dash-compress.compress]
[http.middlewares.dash-auth.basicAuth]
  users = [
    "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
  ]

[http.routers.dashboard-redirect-https]
  rule = "Host(`dashboard.lab.io`, `dashboard.lab.com`)"
  entryPoints = ["http"]
  service = "noop"
  middlewares = ["https-redirect"]
  priority = 100

[http.routers.dashboard]
  rule = "Host(`dashboard.lab.io`, `dashboard.lab.com`)"
  entrypoints = ["https"]
  service = "dashboard@internal"
  middlewares = ["dash-compress"]
  [http.routers.dashboard.tls]

[http.routers.api]
  rule = "Host(`dashboard.lab.io`, `dashboard.lab.com`) && PathPrefix(`/api`)"
  entrypoints = ["https"]
  service = "api@internal"
  middlewares = ["dash-compress"]
  [http.routers.api.tls]

[http.routers.ping]
  rule = "Host(`dashboard.lab.io`, `dashboard.lab.com`) && PathPrefix(`/ping`)"
  entrypoints = ["https"]
  service = "ping@internal"
  middlewares = ["dash-compress"]
  [http.routers.ping.tls]

其實,只需要將配置保留剩下這兩條需要被預先定義的“中間件”即可,如果你不需要頁面壓縮,或者不需要訪問密碼,那麼也可以不對下面的內容進行保存:


[http.middlewares.dash-compress.compress]
[http.middlewares.dash-auth.basicAuth]
  users = [
    "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
  ]

接着在容器配置中添加一些 traefik 能夠解析處理的規則在 labels 字段中即可:


version: '3'

services:

  traefik:
...    
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      # 默認請求轉發 https 端口
      - "traefik.http.routers.traefik-dash-default.middlewares=https-redirect@file"
      - "traefik.http.routers.traefik-dash-default.entrypoints=http"
      - "traefik.http.routers.traefik-dash-default.rule=Host(`dashboard.guava.lab.com`)"
      - "traefik.http.routers.traefik-dash-default.service=dashboard@internal"
      # 處理網頁
      - "traefik.http.routers.traefik-dash-web.entrypoints=https"
      - "traefik.http.routers.traefik-dash-web.rule=Host(`dashboard.guava.lab.com`) && PathPrefix(`/`)"
      - "traefik.http.routers.traefik-dash-web.tls=true"
      - "traefik.http.routers.traefik-dash-web.service=dashboard@internal"
      # 處理接口
      - "traefik.http.routers.traefik-dash-api.entrypoints=https"
      - "traefik.http.routers.traefik-dash-api.rule=Host(`dashboard.guava.lab.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.traefik-dash-api.tls=true"
      - "traefik.http.routers.traefik-dash-api.service=api@internal"
...

單獨抽象保存的 default.toml 配置
雖然我們將 90% 的內容都遷移到了 compose 配置文件中,但是還是有一些內容暫時是不好進行重寫的,比如下面提到的“內容Gzip壓縮”和“HTTP轉發HTTPS”:

# 提供 Gzip 壓縮
[http.middlewares.gzip.compress]

# tricks 實現,提供 HTTP 默認轉發 HTTPS
# https://github.com/containous/traefik/issues/4863#issuecomment-491093096
[http.services]
  [http.services.noop.LoadBalancer]
     [[http.services.noop.LoadBalancer.servers]]
        url = "" # or url = "localhost"

[http.routers]
  [http.routers.https-redirect]
    entryPoints = ["http"]
    rule = "HostRegexp(`{any:.*}`)"
    middlewares = ["https-redirect"]
    service = "noop"

[http.middlewares.https-redirect.redirectScheme]
  scheme = "https"

這裏倒不是說不能夠在應用內配置,而是如果這兩個中間件在應用內配置,會出現每個應用都需要配置重複配置的問題。儘管獨立的配置會讓應用的可遷移性更好,然而這份配置可以提供不論是在本地、私有云,還是公有云 SLB 環境下的一致行爲,維護一份配置,總比維護幾份要來的方便,不是嗎?

完整的容器配置
一如既往,這裏給出完整的 compose 配置:


version: '3'

services:

  traefik:
    container_name: traefik
    image: traefik:v2.3.4
    restart: always
    ports:
      - 80:80
      - 443:443
    networks:
      - traefik
    command:
      - "--global.sendanonymoususage=false"
      - "--global.checknewversion=false"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--api.debug=false"
      - "--ping=true"
      - "--log.level=warn"
      - "--log.format=common"
      - "--accesslog=false"
      - "--providers.docker=true"
      - "--providers.docker.watch=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.swarmMode=false"
      - "--providers.docker.useBindPortIP=false"
      - "--providers.docker.network=traefik"
      - "--providers.file=true"
      - "--providers.file.watch=true"
      - "--providers.file.directory=/etc/traefik/config"
      - "--providers.file.debugloggeneratedtemplate=true"
    volumes:
      # 僅限標準的 Linux 環境
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config/:/etc/traefik/config/:ro
      - ./ssl/:/data/ssl/:ro
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      # 默認請求轉發 https 端口
      - "traefik.http.routers.traefik-dash-default.middlewares=https-redirect@file"
      - "traefik.http.routers.traefik-dash-default.entrypoints=http"
      - "traefik.http.routers.traefik-dash-default.rule=Host(`dashboard.guava.lab.com`)"
      - "traefik.http.routers.traefik-dash-default.service=dashboard@internal"
      # 處理網頁
      - "traefik.http.routers.traefik-dash-web.entrypoints=https"
      - "traefik.http.routers.traefik-dash-web.rule=Host(`dashboard.guava.lab.com`) && PathPrefix(`/`)"
      - "traefik.http.routers.traefik-dash-web.tls=true"
      - "traefik.http.routers.traefik-dash-web.service=dashboard@internal"
      # 處理接口
      - "traefik.http.routers.traefik-dash-api.entrypoints=https"
      - "traefik.http.routers.traefik-dash-api.rule=Host(`dashboard.guava.lab.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.traefik-dash-api.tls=true"
      - "traefik.http.routers.traefik-dash-api.service=api@internal"
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:8080/ping || exit 1"]
      interval: 3s
      retries: 12
    logging:
      driver: "json-file"
      options:
        max-size: "1m"

networks:
  traefik:
    external: true

最後
官方在前一陣推出了 https://traefik.io/traefik-pilot/,除了作爲統一的管理中心之外,還提供了許多有用的中間件,比如請求/響應頭改寫、IP 禁止名單、IP地址轉換、fail2ban 等等。

因爲暫時官方無意將 pilot 開源(可能也會是長期狀況),如果你不介意“聯公網”使用,可以試試註冊 pilot 使用。

--EOF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章