在 Docker 上使用 Traefik 暴露服务:基础篇¶
本指南帮助你开始在 Docker 上通过 Traefik Proxy 暴露服务。你将学习 HTTP 流量路由的基础知识、基于路径的路由配置,以及使用 TLS 保护服务的方法。
前提条件¶
- 已安装 Docker 和 Docker Compose
- 基本了解 Docker 概念
- 已按照 Traefik Docker 部署指南 部署 Traefik
暴露你的第一个 HTTP 服务¶
我们将使用 whoami 应用暴露一个简单的 HTTP 服务,以演示到后端服务的基本路由。
首先,创建一个 docker-compose.yml 文件:
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
将其保存为 docker-compose.yml,然后启动服务:
docker compose up -d
验证服务¶
现在可以通过 http://whoami.docker.localhost/ 访问服务。测试服务是否正常工作:
curl -H "Host: whoami.docker.localhost" http://localhost/
你应该看到类似以下内容的输出:
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
这说明 Traefik 已成功将请求路由到 whoami 应用。
添加路由规则¶
接下来,我们将根据 URL 路径 将流量分发到不同服务,增强路由配置。这适用于 API 版本管理、前后端分离或微服务组织。
更新 docker-compose.yml,添加另一个服务:
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
应用更改:
docker compose up -d
测试基于路径的路由¶
验证不同路径是否会路由到不同服务:
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
对于 /api 请求,你应该在响应的环境变量部分看到“API Service”,这说明基于路径的路由工作正常。
启用 TLS¶
下面添加 TLS,通过 HTTPS 保护服务。我们先使用适合本地开发的自签名证书。
创建自签名证书¶
生成自签名证书:
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
创建存放动态配置的目录,并添加 TLS 配置文件:
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
按照以下内容更新 docker-compose.yml 文件:
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
应用更改:
docker compose up -d
你可以在浏览器中通过 https://whoami.docker.localhost/ 访问服务。你需要接受自签名证书的安全警告。
后续步骤¶
现在你已掌握在 Docker 上使用 Traefik 暴露服务的基础知识,可以继续探索中间件、Let's Encrypt 证书、粘性会话和多层路由等高级功能。
继续阅读高级指南,了解:
- 添加用于安全防护和访问控制的中间件
- 使用 Let's Encrypt 生成证书
- 为有状态应用配置粘性会话
- 设置多层路由,实现基于身份认证的路由