Traefik 配合 Docker 暴露服务实战:从第一个 HTTP 服务到路径路由与 TLS 加密 Traefik 配合 Docker 暴露服务实战从第一个 HTTP 服务到路径路由与 TLS 加密【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefik本文以 Traefik 仓库中的官方入门指南expose/docker/basic.md为主体完整讲解如何在 Docker 环境中让 Traefik 通过容器标签自动发现并暴露 HTTP 服务从搭建第一个 whoami 路由、按 URL 路径分流到不同后端再到为服务启用 TLS 终止。读完本文你将掌握traefik.http.routers.*标签的编写方式、Docker provider 的动态配置生成机制以及结合 File provider 挂载自签证书的完整 HTTPS 部署方案。前置条件开始前需要满足以下条件已安装 Docker 与 Docker Compose对 Docker 网络network与标签labels有基本了解Traefik 已通过 Traefik Docker 部署指南完成基础部署本文会给出完整的自包含 Compose 文件也可独立运行。暴露你的第一个 HTTP 服务Traefik 仓库配套提供了一个traefik/whoami镜像它会把收到的请求头、IP、来源地址原样回显是验证反向代理路由结果最直观的工具。下面用它演示一次完整的基础路由。编写 docker-compose.yml创建docker-compose.yml文件定义 Traefik 与 whoami 两个服务services: traefik: image: traefik:v3.4 container_name: traefik restart: unless-stopped security_opt: - no-new-privileges:true networks: - proxy command: - --providers.dockertrue - --providers.docker.exposedbydefaultfalse - --providers.docker.networkproxy - --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.enabletrue - traefik.http.routers.whoami.ruleHost(whoami.docker.localhost) - traefik.http.routers.whoami.entrypointsweb networks: proxy: name: proxy各关键配置项的含义如下配置项作用--providers.dockertrue启用 Docker provider让 Traefik 通过 Docker API 发现容器--providers.docker.exposedbydefaultfalse默认不暴露任何容器只有带traefik.enabletrue标签的容器才会生成路由--providers.docker.networkproxy指定 Traefik 使用哪个网络中的容器 IP 来访问后端见下文源码分析--entryPoints.web.address:80定义名为web的 HTTP 入口监听 80 端口/var/run/docker.sock只读挂载提供 Docker API 访问通道:ro保证只读traefik.http.routers.whoami.rule路由匹配规则Host(\whoami.docker.localhost) 表示 Host 为该域名时命中traefik.http.routers.whoami.entrypointsweb该路由绑定到web入口保存文件后启动服务docker compose up -d验证路由生效服务此时应当可以通过 http://whoami.docker.localhost/ 访问。由于该域名未必在本地解析可以手动指定 Host 头测试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响应中出现的X-Forwarded-Host、X-Forwarded-Proto、X-Real-Ip等请求头说明请求确实经过了 Traefik 的反向代理层——它向 whoami 转发了请求并附加了标准的转发头。源码级原理Docker provider 如何把标签变成路由上面的效果在 Traefik 源码中由 Docker provider 完成核心实现位于 pkg/provider/docker/pdocker.go首次全量同步provider 启动后调用listContainers列出全部容器经builder.build生成动态配置推送到configurationChan通道见 pdocker.go#L82-L92。事件驱动增量更新当watch开启默认开启时Traefik 订阅容器事件流收到start、die或health_status前缀的事件时重新构建配置见 pdocker.go#L94-L136。这也是为什么新起的 whoami 容器无需重启 Traefik 就能被自动发现。容器过滤pkg/provider/docker/config.go 的keepContainer实现了本文exposedbydefaultfalse的行为——若容器没有traefik.enabletrue标签ExtraConf.Enable为false容器直接被过滤见 config.go#L197-L234。traefik.enable的默认值即 provider 的ExposedByDefault配置默认true见 shared_labels.go#L42-L63。同一函数还表明非 running 状态或 healthcheck 不健康的容器会被过滤其 service 保留空负载列表可用allowEmptyServices调整。后端地址解析Traefik 用--providers.docker.networkproxy指定的网络proxy来取容器 IP——getIPAddress优先从该网络中查找network.Addr找不到会降级到第一个可用网络并打警告日志见 config.go#L359-L425。这就是为什么 whoami 必须和 traefik 容器接入同一个proxy网络。端口探测若没有用traefik.http.services.name.loadbalancer.server.port标签指定端口Traefik 取容器暴露的最低端口见 shared.go#L189-L207服务名则默认取自 Compose 注入的com.docker.compose.service标签格式为服务名_项目名见 shared.go#L209-L217。关于 Docker provider 的更多安装配置选项如endpoint、constraints、useBindPortIP可查阅 Docker provider 参考文档可使用的完整标签清单见 Docker 路由标签参考。添加路由规则基于路径分流接下来按 URL 路径将流量导向不同服务——这在 API 版本化、前后端分离、微服务分组中非常实用。在docker-compose.yml中追加一个whoami-api服务# ... # New service whoami-api: image: traefik/whoami networks: - proxy container_name: whoami-api environment: - WHOAMI_NAMEAPI Service labels: - traefik.enabletrue # Path-based routing - traefik.http.routers.whoami-api.ruleHost(whoami.docker.localhost) PathPrefix(/api) - traefik.http.routers.whoami-api.entrypointsweb两个路由同时命中whoami.docker.localhost这个 Host为什么/api请求会走whoami-api关键在于Traefik 的路由优先级机制默认情况下优先级等于规则字符串的长度更长的规则更具体、优先级更高priority显式设置为 0 时才回到按长度排序。本文的whoami-api规则Host(...) PathPrefix(/api)比whoami规则长因此/api前缀的请求优先命中whoami-api其余路径落到whoami。更完整的匹配器Path/PathPrefix/PathRegexp、Host/HostRegexp、Query、Header、Method等与优先级计算细节参见 路由规则与优先级参考。应用变更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的请求whoami 会在环境变量部分回显WHOAMI_NAMEAPI Service证明路径分流工作正常。启用 TLS自签证书 File provider 动态配置下面为服务启用 HTTPS。本地开发环境先使用自签证书生产环境则应换成可信 CA 签发的证书例如 Lets Encrypt见 进阶指南。生成自签证书mkdir -p certs openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout certs/local.key -out certs/local.crt \ -subj /CN*.docker.localhost*.docker.localhost的通配符 CN 可以覆盖whoami.docker.localhost、dashboard.docker.localhost等子域注意通配只匹配一层子域。然后创建动态配置目录写入 TLS 证书配置mkdir -p dynamic cat dynamic/tls.yml EOF tls: certificates: - certFile: /certs/local.crt keyFile: /certs/local.key EOF这里certFile/keyFile指向的是容器内路径/certs/...与下面的 volume 挂载目标一致。更新 docker-compose.yml 启用 HTTPSservices: traefik: image: traefik:v3.4 container_name: traefik restart: unless-stopped security_opt: - no-new-privileges:true networks: - proxy command: - --api.insecurefalse - --api.dashboardtrue - --providers.dockertrue - --providers.docker.exposedbydefaultfalse - --providers.docker.networkproxy - --providers.file.directory/etc/traefik/dynamic - --entryPoints.web.address:80 - --entryPoints.websecure.address:443 - --entryPoints.websecure.http.tlstrue 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.enabletrue - traefik.http.routers.dashboard.ruleHost(dashboard.docker.localhost) - traefik.http.routers.dashboard.entrypointswebsecure - traefik.http.routers.dashboard.serviceapiinternal # Add the following label - traefik.http.routers.dashboard.tlstrue whoami: image: traefik/whoami restart: unless-stopped networks: - proxy labels: - traefik.enabletrue - traefik.http.routers.whoami.ruleHost(whoami.docker.localhost) - traefik.http.routers.whoami.entrypointswebsecure # Add the following label - traefik.http.routers.whoami.tlstrue whoami-api: image: traefik/whoami container_name: whoami-api restart: unless-stopped networks: - proxy environment: - WHOAMI_NAMEAPI Service labels: - traefik.enabletrue - traefik.http.routers.whoami-api.ruleHost(whoami.docker.localhost) PathPrefix(/api) - traefik.http.routers.whoami-api.entrypointswebsecure # Add the following label - traefik.http.routers.whoami-api.tlstrue networks: proxy: name: proxy与 HTTP 版本相比关键变化有新增websecure入口--entryPoints.websecure.address:443并通过--entryPoints.websecure.http.tlstrue强制该入口所有 HTTP 流量走 TLSFile provider 加载动态 TLS 配置--providers.file.directory/etc/traefik/dynamic对应挂载的./dynamic目录dynamic/tls.yml中的证书被注册进 TLS store各路由迁移到websecure入口并加tlstruetraefik.http.routers.name.tlstrue是路由级开关声明该路由需要 TLS 终止Traefik 会按 SNI 从 TLS store 中匹配证书Dashboard 自路由Traefik 容器自身也打了traefik.enabletrue标签通过serviceapiinternal把仪表盘挂在dashboard.docker.localhost上配合--api.insecurefalse仪表盘不会裸露在 8080 管理端口只能通过这条受 TLS 保护的 HTTPS 路由访问。应用变更docker compose up -d现在浏览器访问 https://whoami.docker.localhost/ 即可打开服务自签证书会触发安全警告接受后即可正常访问。小结与进阶方向本文完整走通了 Traefik Docker 的三条基本能力链标签驱动的容器发现Docker provider 事件监听与traefik.enable过滤、规则路由HostPathPrefix组合与基于规则长度的优先级仲裁、TLS 终止websecure.http.tlstrue入口级强制 路由级tlstrue File provider 证书配置。三者叠加后一个 Docker Compose 文件即可承载多域名、多路径、加密的反向代理。掌握了这些基础之后可以继续探索 进阶指南使用 middlewares 实现安全响应头与访问控制使用 Lets EncryptACME自动签发与续期证书为有状态应用配置 sticky sessions搭建基于认证结果的多层路由。【免费下载链接】traefikThe Cloud Native Application Proxy项目地址: https://gitcode.com/GitHub_Trending/tr/traefik创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考