本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2026年05月29日 统计字数: 7776字 阅读时间: 16分钟阅读 本文链接: https://soulteary.com/2026/05/29/traefik-alibaba-cloud-auto-tls-and-service-routing.html ----- # Traefik 阿里云使用方案:自动证书与服务接入 本篇文章聊聊在阿里云环境中,目前使用的一套 Traefik 配置方案。 这套方案的目标很简单:新服务上线不需要修改 Traefik 配置、自动申请和续签 SSL 证书、最小权限访问阿里云 DNS、支持大量业务服务长期维护、迁移服务器成本尽可能低。 ## 写在前面 最近在整理团队服务器,将域名管理切换到了阿里云。因此,之前基于 Cloudflare DNS Challenge 的证书自动签发配置,也需要同步调整。借着这次迁移的机会,我顺便把 Traefik 的整体配置重新整理了一遍。 如果你还不熟悉 Traefik 的基础部署和使用,可以先阅读:《[Docker 环境下使用 Traefik 3 的最佳实践:快速上手](https://soulteary.com/2024/08/04/best-practices-for-traefik-3-in-docker-getting-started-quickly.html)》。 ## 方案设计 在开始部署之前,先聊聊这套方案为什么这样设计。 很多人在使用 Traefik 的时候,会直接把所有业务域名都写在 Traefik 的配置文件中: ```yaml example.com api.example.com app.example.com ``` 服务越来越多之后,Traefik 配置会越来越长。 每新增一个服务,都需要做下面的事情:修改 Traefik 配置、重启 Traefik、检查证书、验证路由。 这样下去,维护成本会越来越高。 因此,一直以来我更倾向于:**Traefik 只负责入口,业务服务自己声明域名和路由规则。** 例如: ```yaml labels: - traefik.http.routers.blog.rule=Host(`app.example.com`) ``` **其实,证书需求也应该由业务来声明。** 这样做会有下面几个明显优点。 ### 服务自治 新增服务时,只需要执行下面的命令,就能够自动接入: ```bash docker compose up -d ``` 不需要再调整 Traefik 的配置,包括**接入新的域名**。 ### 配置解耦 Traefik 不关心业务;业务也不关心 Traefik 内部实现,两者**完全解耦**。 ### 更容易迁移 未来迁移服务器时,只需要把所有配置带走,就可以跨机器直接部署,恢复服务: ```bash scp compose.yaml docker compose up -d ``` 所有服务配置,都跟随业务一起迁移,而不锁定网关。 ### DNS Challenge 的优势 这里没有选择 `HTTP Challenge`,而是选择 `DNS Challenge` 的原因很简单:DNS Challenge 支持通配符证书。 例如,我们可以申请 `*.yourdomain.ltd`,申请完毕之后: ```bash api.yourdomain.ltd grafana.yourdomain.ltd harbor.yourdomain.ltd ``` 这类域名就都可以通过 HTTPS 进行访问了,未来新增类似的服务无需重新申请证书。以及这样做也不依赖公网 80 端口、可以用于内网服务、灵活性也更高。 ### 安全设计 因为自动签发证书需要修改 DNS,因此需要阿里云 API 权限。这里不建议直接使用主账号,而是使用有限权限的 RAM 账号进行操作。规避因为主账号权限太大,一旦泄露各种账号资源都有风险的问题。 让 Traefik 只能查询域名、创建 TXT 记录、删除 TXT 记录,禁止访问其他资源,这样即使密钥泄露,影响范围也非常有限。 ## 初始化阿里云相关资源 为了更低的维护成本,在部署和使用 Traefik 之前,我们首先要初始化一些阿里云上的资源:运行 Traefik 和相关 Web 服务的服务器、能够更新指定域名的账号。 服务器我使用 Ubuntu 26.04 操作系统的 ECS,其他版本的操作系统类似,只要能够使用 Docker 运行服务即可。如果你还不熟悉配置 Docker 环境,可以参考《[搭建 Ubuntu 24.04 基础开发环境指南](https://soulteary.com/2025/01/17/guide-to-setting-up-ubuntu-24-04-basic-development-environment.html)》几条命令完成 Docker 的安装和基础配置。 为了整个账号下资源安全,我们需要创建一个独立的 RAM 账号,缩小权限范围到只能操作指定域名,来配合 Traefik 进行指定域名的 SSL 证书持续的自动申请。 我们先访问 [RAM 控制台](https://ram.console.aliyun.com/),创建一个新的账号。 ![创建 RAM 账号](https://attachment.soulteary.com/2026/05/29/create-ram-user.jpg) 创建账号时,关闭访问控制台访问权限,仅允许 API 调用。 ![创建完毕,保存好 AK 和 SK](https://attachment.soulteary.com/2026/05/29/ram-user-created.jpg) 创建完毕,保存好用户的 `ACCESS KEY` 和 `ACCESS KEY SECRET`,我们后续要使用。 接着,先创建域名全局查询策略。 ![创建资源策略](https://attachment.soulteary.com/2026/05/29/create-new-policy.jpg) 因为 Traefik 会调用 `DescribeDomains`,需要 `"Resource": "*"`权限,所以我们的配置需要这样写: ```yaml { "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "alidns:DescribeDomains" ], "Resource": "*" } ] } ``` 完成之后,我们继续创建第二个策略,这个策略允许进行指定域名的编辑: ```yaml { "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "alidns:AddDomainRecord", "alidns:DeleteDomainRecord", "alidns:UpdateDomainRecord", "alidns:DescribeDomainRecords" ], "Resource": [ "acs:alidns:*:*:domain/yourdomain.ltd" ] } ] } ``` 上面配置中的 `yourdomain.ltd` 就是我们要使用 Traefik 自动申请证书的域名。 ![关联资源策略](https://attachment.soulteary.com/2026/05/29/assign-new-policy.jpg) 完成之后,分别将两个策略关联到我们上面创建的用户上。 然后,我们开始配置 Traefik。 ## Traefik基础配置 在进行配置和部署服务之前,我们需要确认: 域名已经解析到服务器(或者手动绑定本地 hosts 到目标服务器)、ECS 安全组开放 80、443 的公网访问,Docker 已正常安装。 这里使用独立的 Docker 网络: ```bash docker network create traefik ``` 这样做的好处是,未来所有业务服务想要通过 Traefik 提供服务时,都只需要在配置中加入下面的内容: ```yaml networks: - traefik ``` 即可自动被 Traefik 发现,提供被访问能力,而无需额外暴露端口(无额外端口占用)。 如果不这样做,我们始终需要声明容器的可访问端口,例如: ```yaml ports: - 8080:8080 ``` 有了独立的 Docker 网络后,上面这样的配置就可以省略了,也减少了不必要的公网暴露。 ## Traefik 配置说明 使用 SSH 登录服务器后,我们先创建一个存放 Traefik 配置的目录,并切换工作目录: ```bash mkdir traefik cd traefik/ ``` 然后,编写容器配置 `compose.yaml`: ```yaml name: traefik services: traefik: image: ghcr.io/traefik/traefik:3.6 container_name: traefik restart: unless-stopped env_file: - .env command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.http.address=:80 - --entrypoints.https.address=:443 - --entrypoints.http.http.redirections.entrypoint.to=https - --entrypoints.http.http.redirections.entrypoint.scheme=https - --certificatesresolvers.aliyun.acme.email=${ACME_EMAIL} - --certificatesresolvers.aliyun.acme.storage=/letsencrypt/acme.json - --certificatesresolvers.aliyun.acme.dnschallenge=true - --certificatesresolvers.aliyun.acme.dnschallenge.provider=alidns - --certificatesresolvers.aliyun.acme.dnschallenge.delaybeforecheck=10 - --ping=true - --ping.entrypoint=traefik - --entrypoints.traefik.address=:8080 ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik/letsencrypt:/letsencrypt healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 30s timeout: 5s retries: 3 start_period: 10s logging: driver: json-file options: max-size: "50m" max-file: "5" security_opt: - no-new-privileges:true networks: - traefik networks: traefik: external: true ``` 在上面的配置中,Traefik 仅处理 ACME证书申请,不再需要保存任何业务域名,更利于维护。 接着,创建这个配置需要的 `.env`文件,将细节配置和刚刚创建的阿里云账号的 AK 和 SK 写入配置: ```yaml # Let's Encrypt 通知邮箱 ACME_EMAIL=ops@yourdomain.ltd # 阿里云 DNS API ALICLOUD_ACCESS_KEY=xxxxxxxxxxxxxxxx ALICLOUD_SECRET_KEY=xxxxxxxxxxxxxxxx # 可选:调试环境 TZ=Asia/Shanghai ``` 完成之后,在目录中执行命令 `docker compose up -d`,能够看到服务就正常运行起来了: ```yaml # docker compose up -d [+] up 2/4 ✔ Image ghcr.io/traefik/traefik:3.6 Pulled 11.2s ✔ Container traefik Started ``` 稍等几秒,执行 `docker ps` ,或 `docker inspect traefik` 可以检查容器运行是否正常: ```bash # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 947d3b6c3d0d ghcr.io/traefik/traefik:3.6 "/entrypoint.sh --pr…" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp traefik ``` ```bash # docker inspect traefik --format='{{json .State.Health}}' | jq { "Status": "healthy", "FailingStreak": 0, "Log": [ { "Start": "2026-05-29T20:56:22.98906195+08:00", "End": "2026-05-29T20:56:23.038763907+08:00", "ExitCode": 0, "Output": "OK: http://:8080/ping\n" }, { "Start": "2026-05-29T20:56:53.040007578+08:00", "End": "2026-05-29T20:56:53.091085376+08:00", "ExitCode": 0, "Output": "OK: http://:8080/ping\n" } ] } ``` 到此,基本的配置就都完成了。 ### Docker Provider 上面的配置中,指定了 `--providers.docker=true`,这个配置是关键配置之一,开启后 Traefik 会自动监听 Docker 事件。 我们无需重启 Traefik 容器,就能够让各种业务容器的配置自动生效。 ### 统一 HTTPS 访问 ```yaml --entrypoints.http.http.redirections.entrypoint.to=https ``` 为了避免业务提供不安全的 HTTP 访问,我们默认强制所有请求都是 HTTPS,非 HTTPS 的请求会被自动跳转。 ### 自动续签证书 ```yaml --certificatesresolvers.aliyun.acme ``` 使用这个配置后,Traefik 会自动续签证书,正常情况下无需人工维护。 ### 自动健康检查 ```yaml healthcheck: ``` 可以让 Docker 自动判断 Traefik 状态,避免入口服务异常却无法及时发现。 ## 配置自动申请证书的服务 让我们来配置自动申请证书的服务。 切换到上级目录,或你计划存放这些服务的工作目录,然后创建一个新的工作目录,来存放用来自动申请证书的 Web 服务。 ```bash cd .. mkdir service-for-issue-domain cd service-for-issue-domain/ ``` 这次让我们先创建 `.env` 文件,明确我们要创建的服务信息:允许被访问的 URL 域名、计划申请证书要包含的域名列表、要使用的容器镜像名称等。 ```yaml # Domain APP_NAME=whoami APP_DOMAIN=whoami.yourdomain.ltd # TLS ACME_MAIN_DOMAIN_1=yourdomain.ltd ACME_MAIN_DOMAIN_2=sub.yourdomain.ltd # Container IMAGE=ghcr.io/traefik/whoami IMAGE_TAG=v1.11 # Docker TZ=Asia/Shanghai ``` 接着,创建 `compose.yaml`: ```yaml name: ${APP_NAME} services: app: image: ${IMAGE}:${IMAGE_TAG} container_name: ${APP_NAME} restart: unless-stopped environment: TZ: ${TZ} expose: - 80 labels: - traefik.enable=true - traefik.docker.network=traefik # Router - traefik.http.routers.${APP_NAME}.rule=Host(`${APP_DOMAIN}`) - traefik.http.routers.${APP_NAME}.entrypoints=https - traefik.http.routers.${APP_NAME}.tls=true - traefik.http.routers.${APP_NAME}.tls.certresolver=aliyun # Wildcard Certificate - traefik.http.routers.${APP_NAME}.tls.domains[0].main=${ACME_MAIN_DOMAIN_1} - traefik.http.routers.${APP_NAME}.tls.domains[0].sans=*.${ACME_MAIN_DOMAIN_1} - traefik.http.routers.${APP_NAME}.tls.domains[1].main=${ACME_MAIN_DOMAIN_2} - traefik.http.routers.${APP_NAME}.tls.domains[1].sans=*.${ACME_MAIN_DOMAIN_2} - traefik.http.services.${APP_NAME}.loadbalancer.server.port=80 logging: driver: json-file options: max-size: "50m" max-file: "5" compress: "true" networks: - traefik networks: traefik: external: true ``` 在这个配置中,我们创建了一个能够被用户通过 `whoami.yourdomain.ltd` 访问的服务,这个服务将会自动的申请证书,申请的证书支持配置 `yourdomain.ltd,*.yourdomain.ltd,*.sub.yourdomain.ltd`中包含的任何域名。 使用 `docker compose up -d` 启动服务后,访问 `https://whoami.yourdomain.ltd`,就能够看到正常使用 SSL 证书的 whoami 服务页面啦。 ## 最后 相比传统 Nginx 或集中式 Traefik 配置,这套方案最大的特点是:**入口与业务彻底解耦。** Traefik 只负责:服务发现、路由转发、TLS 管理;而业务服务负责:域名声明、路由规则、生命周期管理。 当我们新增服务时,只需要执行:`docker compose up -d` 就可以完成服务上线、HTTPS 配置、证书申请、自动续签等一系列工作,而无需修改 Traefik 配置。 对于长期维护几十甚至上百个服务的环境来说,这种方式会比传统配置轻松很多。 --EOF