新一代LB - Traefik
Traefik突破以往我們對load balancer的觀點,他是一套直接與docker整合的load balancer套件... 透過Traefik,我們可以使用label的方式將後面啟動的docker instance掛載到load balancer中,且無需重新啟動Traefik,可直接生效...
Traefik基本介紹
Traefik是以動態重載新加入的docker instance的方式來替有附加相同domain label的docker instance建立網路附載平衡的關聯... 因此,設定上,與一般我們建立reverse proxy的過程剛好相反(一般我們會先建立服務,再建立reverse proxy將服務串連起來)...
Step1 - 建立Traefik服務
下面我們用官方的compose file來說明...
File: docker-compose.yaml
version: '2'
services:
proxy:
image: traefik
command: --api --docker --docker.domain=docker.localhost --logLevel=DEBUG
networks:
- webgateway
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
networks:
webgateway:
driver: bridge
其中traefik啟動時候,我們需要指定docker.domain來告訴taefik要聆聽的domain是哪一個,然後要事先開啟對應的port,讓外部服務可以連到traefik...,另外,我們將docker socket掛載進來,這是必要的設定,讓traefik可以透過docker socket來操控一些東西...,最後,traefik.toml檔案,我們保留空的,讓treafik自己建立...
啟動:
docker-compose -f docker-compose.yaml up -d
Step2 - 建立你的服務並加入Traefik
接下來,我們可以啟動我們的服務(ex: 網站),讓traefik掛載...
File: whoami.yaml
version: '2'
services:
whoami:
image: emilevauge/whoami
networks:
- web
labels:
- "traefik.backend=whoami"
- "traefik.frontend.rule=Host:whoami.docker.localhost"
networks:
web:
external:
name: traefik_webgateway
官方的說明是以whoami為例,他會顯示你連入的http協定與主機資訊...
上述的設定中,指定traefik的backend為whoami這個service,並且指定fontend rule為whoami.docker.local... 這個呼應traefik啟動時候所指定的domain,讓traefik可以知道該container instance要加入這個domain的路由群組...
啟動:
docker-compose -f whoami.yaml up -d
接下來你就可以用下面的方式測試
curl -H Host:whoami.docker.localhost http://127.0.0.1
這邊比較特別的是,traefik是透過domain的方式掛載你的服務,因此我們必須透過指定domain的方式來存取,如果使用curl,最快的就是加上Host header... 如果需要使用網路,那Mac的用戶建議修改/etc/hosts來對應whoami.docker.localhost到127.0.0.1... Windiws用戶可以參考相關設定。
官方文件中,另外還針對service做scale out,讓traefik可以round rabin的跑在scale出來的instance上,對於使用docker作為操控的開發者來說,真的相當方便唷!
Traefik透過LetsEncrypt啟用SSL
下面介紹以啟用SSL憑證到Traefik服務為主...
準備動作
建立自己的network,讓其他後續啟動的instance可以共用這個network...
docker network create web
建立docker-compose.yaml, traefik.toml, acme.json三個檔案... 該三個檔案需要在traefik啟動時候用到,下面會說明compose file跟toml檔案的內容... acme.json只要保持空的即可...
啟動Traefik
首先介紹Traefik的compose file,Traefik是透過掛載docker volume的方式來操控docker的實體,聆聽新加入的docker服務的相關資訊,再加上相關的load balancer設定來轉導相關的流量到指定的instance...
File: docker-compose.yaml
version: '2'
services:
traefik:
image: traefik
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/traefik.toml
- /opt/traefik/acme.json:/acme.json
container_name: traefik
networks:
web:
external: true
traefik.yaml是traefik的設定檔案,下面描述要開啟http, https的協定,並且聆聽label中domain為arecord.us的instance,將它掛載到traefik中...
File: traefik.toml
debug = true
logLevel = "INFO"
defaultEntryPoints = ["https","http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "arecord.us" #掛載你的domain
watch = true
exposedbydefault = false
[acme]
email = "[email protected]" #你的信箱
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
[acme.httpChallenge]
entryPoint = "http"
啟動:
docker-compose -f docker-compose.yaml up -d
啟動後,除非有打開traefik的管理介面,不然目前瀏覽應該都是404的錯誤ㄛ...,我們再往下,啟動backend的服務後,才可以瀏覽...
啟動你的docker instance
接著,我們可以啟動我們自己的服務... 下面以nginx為例,希望將網站掛載到gcpdemo.arecord.us這個網域名稱上...
File: web.yaml
version: '2'
services:
gcpdemo:
image: nginx
restart: always
networks:
- web
- default
labels:
- "traefik.backend=gcpdemo"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:gcpdemo.arecord.us"
- "traefik.enable=true"
- "traefik.default.protocol=http"
networks:
web:
external: true
上述的設定檔中,指定traefik要掛載名為gcpdemo的instance,並且使用web這個network... 最重要的是frontend rule這段,是指定真實打到該主機外部IP的domain(因此我們還是需要到DNS server上指定一筆紀錄,讓gcpdemo.arecord.us這個domain可以對應到這台機器的實體ip)...
啟動:
docker-compose -f web.yaml up -d
啟動後,需要稍微等待traefik跟LetsEncrypt取回SSL憑證,接下來就可以直接使用 https://gcpdemo.arecord.us 來瀏覽您的網站了!
參考
- 官方文件 - https://docs.traefik.io/
- 官方文件 - 設定Traefik SSL: https://docs.traefik.io/user-guide/docker-and-lets-encrypt/