一月 14, 2022 | 伺服器和Devops

【Traefik 教學】用10分鐘學會Traefik v2的安裝 + 自動續約Lets Encrypt

Reverse Proxy的最佳選擇
Traefik是一個用Go語言開發出來的反向代理工具Reverse Proxy,可以完美的跟Docker整合,這篇文章將是著重在Traefik v2的安裝,若您想要學習的是v1版本,不妨參考另外一篇文章“【網站架設】簡易方便的反向代理工具Traefik”,相信可以幫助到您。

簡介Traefik 2.x 與 1.x 的差別

V2跟V1就體質上有非常大的改變,對我們來說最大的變革不外乎就是支援了YAML檔案的編排、可以完全支援Middleware控制各種行為更漂亮且方便的WebUI支援A/B Testing,但V2還遠遠不止這樣而已,就官方寫的這句話,我想就不難看出來。

We forgot what was impossible so we could build it!

功能更新:

  1. TCP Support with SNI Routing & Multi-Protocol Ports
  2. Fully Customize Your Routes with Middleware
  3. A New Dashboard & WebUI
  4. Canary Deployments with Service Load Balancers
  5. Mirroring with Service Load Balancers

上述這些也只是其中比較大的項目而已,官方指出還有更多更多的功能,都是1.x所沒有的,因此,雖然我們的服務絕大部分都是在1.x的版本,而且很穩定,但我們還是決定毅然決然的邁向2.x的懷抱。

2.x對我們最大的影響

對於HelloSanta來說,升級到了2.x除了設定跟以前一樣方便之外,最大最大的好處當然就是可以完全支援Middleware控制各種行為。由於我們是一間協助客人製作客製化網站的公司,往往會需要應付各種不同客戶的需求,再加上跟Docker的完美整合,讓我們對於升級到2.x,實在是想到都會笑,不僅能夠更省時間,更讓我們覺得更穩定。 下面就讓我們一起來試試看吧!

(圖片來自於 Traefik Labs

如何安裝

在這裡一樣是使用Docker來進行安裝,若您想要用其他方式,可以參考官方文件。當然官方文件中一樣有Docker的安裝模式,但若您不想要看長長的文章,不妨直接跟著一下的步驟走,可以10分鐘以內安裝完畢。

  1. 建立Network 為了要讓Reverse Proxy的彈性發揮到極致,所以用這個方法,獨立建立Network,而不是全部綁定在docker-compose裡面
$ docker create network ReverseProxy
  1. 建立一個traefik資料夾,並且準備traefik設定檔案
# 建立資料夾
$ mkdir -p traefik/conf

# 進入資料夾,並且建立相對應設定檔案
$ cd traefik
$ touch conf/acme.json
$ chmod 400 conf/acme.json
$ touch conf/traefik.yml && touch conf/dynamic_conf.yml
  1. 建立Traefik v2的設定檔案 如果有興趣,可以參考官方的Traefik.yml設定文件,可以看到全部的設定檔案
  • traefik.yml 設定檔案
################################################################
# Global configuration
################################################################
global:
  checkNewVersion: true
  sendAnonymousUsage: true

################################################################
# EntryPoints configuration
################################################################

# EntryPoints definition
#
# Optional
#
entryPoints:
  web:
    address: ":80"

  websecure:
    address: :443
    http:
      tls:
        certResolver: myresolver

################################################################
# Enabling ACME Data
################################################################
certificatesResolvers:
  myresolver:
    acme:
      email: [email protected]
      storage: acme.json
      httpChallenge:
        entryPoint: web


################################################################
# Traefik logs configuration
################################################################

# Traefik logs
# Enabled by default and log to stdout
#
# Optional
#
log:
  # Log level
  #
  # Optional
  # Default: "ERROR"
  #
 level: INFO

  # Sets the filepath for the traefik log. If not specified, stdout will be used.
  # Intermediate directories are created if necessary.
  #
  # Optional
  # Default: os.Stdout
  #
 filePath: /log/traefik.log

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
 format: json

################################################################
# Access logs configuration
################################################################

# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
#
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: /log/access.log

  # Format is either "json" or "common".
  #
  # Optional
  # Default: "common"
  #
format: json

################################################################
# Docker configuration backend
################################################################

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: true
  file:
    filename: /etc/traefik/dynamic_conf.yml

  • dynamic_conf.yml 如果有興趣,可以參考官方文件,這裡的設定,基本上就是為了加強HTTPS的強度
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  1. 建立docker-compose.yml檔案
version: '3'

services:
  reverse-proxy:
    image: traefik:v2.5
    command: --api.insecure=true --providers.docker
    restart: always
    container_name: traefik-reverse-proxy
    networks:
      - ReverseProxy
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./conf/traefik.yml:/etc/traefik/traefik.yml
      - ./conf/dynamic_conf.yml:/etc/traefik/dynamic_conf.yml
      - ./conf/acme.json:/acme.json
      - ./log:/log

networks:
  ReverseProxy:
    external: true

  1. 啟動Traefik服務 上述的步驟完成後,基本上就可以啟動Traefik了,Follow 下面指令就可以啟動完畢一個以Traefik為Base的Reverse Proxy
$ docker-compose up -d

使用Traefik建立自動HTTPS續約服務

當我們順利建立完畢Traefik的反向代理服務後,再來就可以通過Docker的label方式,來直接制定要如何讓外部的連線連到這個容器。

以下例子是我其中一個容器的docker-compose.yml。 達到的效果是:

  1. 網址是 example.com or www.example.com
  2. Force http to https
  3. no-www redirect to www
  4. Traefik 自動續約HTTPS服務
version: "3.5"
services:

  example:
    image: nginx:latest
    networks:
      - ReverseProxy
    labels:
      - traefik.http.middlewares.example-redirect-to-websecure.redirectscheme.scheme=https
      - traefik.http.middlewares.example-web-www-https-redirect.redirectregex.regex=^https://(?:www.)?example.com/(.*)
      - traefik.http.middlewares.example-web-www-https-redirect.redirectregex.replacement=https://www.example.com/$${1}
      - traefik.http.middlewares.example-web-www-https-redirect.redirectregex.permanent=true
      - traefik.http.middlewares.example-secured.chain.middlewares=example-redirect-to-websecure,example-web-www-https-redirect
      - traefik.http.routers.example.middlewares=example-secured
      - traefik.http.routers.example.rule=Host(`www.example.com`) || Host(`example.com`)
      - traefik.http.routers.example.tls=true
      - traefik.http.routers.example.tls.options=default
      - traefik.http.routers.example.entrypoints=web, websecure
      - traefik.http.services.example.loadbalancer.server.port=80
      - traefik.http.routers.example.tls.certresolver=myresolver

networks:
  ReverseProxy:
    external: true

結論

Traefik V2就設定上面來說,雖然稍微複雜了一些,但是整體上還是屬於很方便且簡單,在上述的範例中,也有簡單的呈現了如何使用middlewares來達成轉換https 還有強制讓網址有www的Chain控制方式,如此可以體現出在控制連線行為上,能夠有更豐富且彈性的作法,後續還有更多更多的應用,我們再陸續分享上來囉。

參考資料

  1. https://traefik.io/blog/traefik-2-0-6531ec5196c2/

常見問題

我們是從1.x開始使用,基本上就網站服務來說已經可以解決9成的問題了,剩下1成的問題是當我們要提供更多客製化服務的時候,Traefik還是有一些限制,尤其我們很多配置是一台虛擬機器有多個容器的配置,每個容器可能都是不同的客人,需要解決的問題相對來說就會需要2.x的新功能middleware才能夠順利解決,因此全面移轉到2.x,將會是我們勢在必行的囉。
1.x 相對來說簡單多了,畢竟彈性沒有像2.x這麼高,但也不是說2.x就是比較難,而是功能多,自然而然設計就複雜了些。