Using traefik as proxy in docker
Page content
使用 Traefik 作为前端反代替换 nginx
前言
Traefik 是一组 go 写的网络代理,不过这次我们只用它 Proxy 这一部分来替换 nginx 作为网页前端反代使用喵~(其实它还可以作为 HAProxy 的替换喵)
优点:
Drop in config
完善支持,也就是你只需要设置watch: true
然后直接修改目录里的配置文件,在不重启的前提下立即就能反应到服务配置里,这个比nginx -t
反复重启可是进步太多了喵;Label config
通过直接给服务打label
自动配置代理,无需复杂操作;
服务环境
因为 k8s
对于个人服务器来说太过折腾(虽然咱成功部署过,但是最终还是全拆了喵),所以咱的服务器仍旧是 docker-compose
启动的一堆服务配置文件,然后通过 traefik
以及共享桥接网络来与服务通信;
默认部署
不折腾的方式,但是效率会打折扣(因为多加了一层 docker-proxy
在前面)
traefik/docker-compose.yaml
version: '3'
services:
traefik:
# The official v2 Traefik docker image
image: traefik:v2.9
container_name: traefik
restart: always
user: "user-id:group-id"
ports:
- "80:80"
- "443:443"
# Network configure.
networks:
proxy:
aliases:
# 这里添加别名,可以让其它服务直接通过域名经过反代直接访问其它服务
- a.mydomain.com
- b.mydomain.com
- c.mydomain.com
- d.mydomain.com
- e.mydomain.com
- f.mydomain.com
- traefik.mydomain.com
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
# Configure files/folders to drop in.
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./config:/config:ro
# Plugins folder
- ./plugins-storage:/plugins-storage
labels:
- "traefik.enable=false"
networks:
proxy:
# 因为在 traefik 目录里,所以 docker-compose up 后会创建 traefik_proxy 网桥
driver: bridge
注意,这个配置文件是唯一无法热替换的喵!
traefik/traefik.yml
entryPoints:
web:
address: ":80"
# 这里可以定义所有 http 都自动转 https,根据自身需要启用
# 为了某些边界测试方便,我用了 Drop in config 来配置这项功能
# http:
# redirections:
# entryPoint:
# to: websecure
# scheme: https
websecure:
address: ":443"
http:
tls:
domains:
- main: mydomain.com
sans:
- "*.mydomain.com"
- main: mydomain2.com
sans:
- "*.mydomain2.com"
http2:
maxConcurrentStreams: 1000
http3:
advertisedPort: 443
providers:
docker:
watch: true
# 这里就是前文提到的网桥,最好需要代理的服务都走这个网桥通信。
network: traefik_proxy
file:
# Dropin config folder
directory: "/config"
watch: true
api:
# 开启 Traefik 内置面板,但是不使用不安全的 8008 服务
# 编写一个 Dropin config 可以轻松反代出来,并且可以加权限校验
dashboard: true
insecure: false
experimental:
plugins:
# 将合法的 CF 代理头转换成 X-Forward 头,以便服务获取真实客户端地址喵
cloudflarewarp:
modulename: github.com/BetterCorp/cloudflarewarp
version: v1.3.3
使用 Host network
默认的 traefik:v2.9
镜像是无法直接使用 network_mode: host
然后监听 1024 以下端口(80/443)的,此时需要一个 setcap
操作来赋予 posix 权限喵~
traefik/build/Dockerfile
:
FROM traefik:v2.9
RUN apk update && apk add libcap && setcap cap_net_bind_service=+ep /usr/local/bin/traefik
Tips: 如果使用 zfs 作为 docker 的存储 driver, 则可能还需要 sudo zfs set acltype=posixacl tank/docker
来让 zfs 启用 posix acl 支持喵~
然后可以直接修订 traefik/docker-compose.yaml
version: '3'
services:
traefik:
build: ./build
container_name: traefik
restart: always
user: "uid:gid"
# Docker 的 cap 修订
cap_add:
- NET_BIND_SERVICE
- NET_RAW
# Network configure.
# 因为直接绑定了 Host 网络,所以 ports 转发设置不需要了喵。
network_mode: host
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
# Configure files/folders to drop in.
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./config:/config:ro
# Plugins folder
- ./plugins-storage:/plugins-storage
labels:
- "traefik.enable=false"
networks:
proxy:
# 这个 Proxy 桥可保留(作为其它服务配置的 default way)可不保留(因为 Host 基本能直接访问所有服务)
driver: bridge
让 DNS 配置也自动化喵~
配置 cloudflare-companion
工具让它自动同步 traefik
的状态来更新 DNS 喵~这可是解放小服务器自己运维的一大乐趣喵~
cloudflare-companion/docker-compose.yaml
version: '3'
services:
cloudflare-companion:
image: tiredofit/traefik-cloudflare-companion:latest
container_name: cloudflare-companion
user: "root:root"
volumes:
# 如果直接跟随 traefik 这个配置可以不需要喵
- /var/run/docker.sock:/var/run/docker.sock:ro
env_file:
# 大部分配置放这个文件里喵
- cf.env
restart: always
labels:
# 这个服务不需要反向代理喵~
- "traefik.enable=false"
networks:
default:
# 直接用 traefik 的网络作为默认网络
name: traefik_proxy
external: true
cf.env
# Traefik config.
TRAEFIK_VERSION=2
ENABLE_TRAEFIK_POLL=TRUE
TRAEFIK_POLL_URL=http://traefik.mydomain.com #这个最好指向 traefik 服务能直接访问到的内部域名/地址
TRAEFIK_POLL_SECONDS=60
# CF config.
CF_EMAIL=
CF_TOKEN=Cloudflare API Token
# domain
TARGET_DOMAIN=traefik.mydomain.com
# mydomain.com
DOMAIN1=mydomain.com
DOMAIN1_ZONE_ID=这个ID去CF页面上找喵~
DOMAIN1_PROXIED=TRUE #是否需要启用 CF 代理,个人服务建议启用喵
DOMAIN1_TARGET_DOMAIN=traefik.mydomain.com #这个域名手动配置到指向 Traefik Host IP
# mydomain2.com
DOMAIN2=mydomain2.com
DOMAIN2_ZONE_ID=同上
DOMAIN2_PROXIED=FALSE
DOMAIN2_TARGET_DOMAIN=traefik.mydomain2.com
# docker config.
DOCKER_ENTRYPOINT=unix://var/run/docker.sock
SWARM_MODE=FALSE # 这个根据 Docker 是否启用 SWARM 模式来配置
# DOCKER_HOST=tcp://198.51.100.32:2376
# DOCKER_CERT_PATH=/docker-certs
# DOCKER_TLS_VERIFY=1
# Just in case.
DRY_RUN=FALSE #如果配置 Dry run 则不会做实际修改,适合拿来测试配置文件是否正确
REFRESH_ENTRIES=TRUE #是否修改已经存在的项目,慎用喵~