traefik是一个反向代理工具,你可以认为它起到的功能和nginx差不多,但是又有所不同。traefik 的卖点是provider,它可以根据某个数据源动态配置反向代理。而nginx ingress controller 就需要生成 nginx 配置,显然设计难度比给traefik写个provider要难度大很多。Provider 赋予了 traefik 发现服务并自动配置的能力。
Provider: Docker
写一个docker-compose.yml
配置
version: '3'
services:
reverse-proxy:
# The official v2 Traefik docker image
image: traefik:v2.4
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- —api.insecure=true 可以开启管理界面,UI蛮好看的。
启动服务
docker-compose up -d reverse-proxy
这个 API可以测试一下 https://localhost:8080/api/rawdata
添加一个whoami服务用来测试反向代理效果
# ...
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
启动whoami服务
docker-compose up -d whoami
用curl测试一下效果
curl -H Host:whoami.docker.localhost http://127.0.0.1
返回的响应来自反向代理的 whoami 服务。
docker-compose scale=2 whoami
再用curl测试一下
curl -H Host:whoami.docker.localhost http://127.0.0.1
得到的结果是response中的host 和 ip 会来回变换。负载均衡已经生效。
原理
traefik 的端口探测基于映像的 expose。如果映像没有 expose 服务端口,你需要用 container label 手动指定 traefik.http.services.<service_name>.loadbalancer.server.port
如果网络类型是 host,那么 traefik 首先尝试一下 host.docker.internal
,不行的话回落到 127.0.0.1
。
:::danger
我在 docker-compose.yml 中指定的 socket 是未加保护的 Unix socket,实际上,docker 也具有 context 功能
:::
# 创建 context
docker context create \
--docker host=ssh://docker-user@host1.example.com \
--description="Remote engine" \
my-remote-engine
# 使用 context
docker context use my-remote-engine
# 切换上下文
docker context use default
# 上下文也可由环境变量配置
export DOCKER_HOST=ssh://docker-user@host1.example.com
为了提升体验,你可以修改 .ssh/config
启用 SSH 连结复用
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yes
CustomResource方式配置Traefik
参考文献
[1]: https://doc.traefik.io/traefik/
[2]: https://doc.traefik.io/traefik/providers/docker/
[3]: 保护 docker daemon Unix socket https://docs.docker.com/engine/security/protect-access/
[4]: https://github.com/traefik/traefik/tree/v2.4/pkg/provider/kubernetes/ingress/fixtures