Traefik Docker 自动证书崩溃应急方案:ZeroSSL 快速接入指南
作者:xiaoxin.gao · 2025-08-07 · 阅读时间:5分钟
Docker Traefik SSL
Let’s Encrypt rate limit
Let’s Encrypt TXT 记录
Let’s Encrypt wildcard limit
Let’s Encrypt 泛域名证书
Traefik 3.2
下文包含大量真实熬夜痕迹、心跳骤停截图、以及一份能在 5 分钟内落地的「LE → ZeroSSL」逃生脚本。阅读前请确认你手边有一杯高浓度咖啡,或者一份随时能跑路的新简历。
0. 开场白:当浏览器红锁亮起
2025-06-02 03:27(对,又是凌晨),监控群里突然蹦出一条 Prometheus 告警:
probe_ssl_earliest_cert_expiry{job="blackbox-https"} < 86400
配图是一片血红。我揉揉眼睛,以为只是 Let’s Encrypt 提前 30 天续期的例行提醒,结果下一秒同事甩来截图:
客户域名
*.mall.example.com泛域名证书全部失效,Chrome 直接大红锁,iOS Safari 直接弹「此连接不受信任」。
那一刻,我听见了自己心跳的声音——比 Traefik 的 404 页面还响。
1. 时间线复盘:90 天前埋的雷,今晚一起爆
| 时间 | 事件 | 当时心态 |
|---|---|---|
| 2025-03-04 10:00 | 用 Traefik 3.2 起新集群,顺手配了 Let’s Encrypt 泛域名证书,觉得“90 天后再说” | 稳如老狗 |
| 2025-05-30 22:00 | 证书还剩 5 天,Traefik 日志出现 rate limit 关键字,当时以为是常规抖动 |
佛系 |
| 2025-06-02 03:27 | 证书集体过期,Prometheus 爆炸,用户疯狂 @ 运维 | 原地升天 |
2. 坑点解剖:Let’s Encrypt 到底怎么把我们坑到断网
2.1 Let’s Encrypt 的隐藏限制:每周 泛域名重复验证 5 次
- 我们为了测试,在 90 天内故意删了 6 次 TXT 记录做演练;
- 结果第 6 次触发 Let’s Encrypt exact duplicate limit —— 同一组域名 7 天内不能再申请;
- Traefik 3.2 默认 ACME Preferred Chain 选 ISRG Root X1,老 Android 不信任,导致证书链断裂。
2.2 Traefik 的“静默失败”机制
- Traefik 在无法续签时不会主动退出,也不会把 443 端口关掉,而是直接返回 404;
- 这让负载均衡健康检查误以为「应用还活着」,结果流量全打到故障节点。
2.3 DNS 验证的 TXT 记录地狱
Let’s Encrypt 的泛域名验证要求 两条 TXT 记录同名不同值:
_acme-challenge.mall.example.com → TXT1
_acme-challenge.mall.example.com → TXT2
而公司 DNS 托管在阿里云,API 有 60 秒缓存,我们脚本把第一条记录冲掉了,于是验证失败率 100%。
3. 逃亡剧本:一条 label 把 ZeroSSL 拉进战场
3.1 ZeroSSL 的 3 个救命优势
| 特性 | Let’s Encrypt | ZeroSSL | 备注 |
|---|---|---|---|
| 泛域名免费额度 | 无限制 | 3 个/免费 | 对我们够用了 |
| ACME 速率限制 | 5 次/周 | 300 次/天 | 直接碾压 |
| 根证书兼容性 | ISRG X1 | AAA Certificate Services | 老 Android 6 都信 |
3.2 Traefik 3.2 的 fallback 魔法
官方文档只写了 多 CA 并行申请,但没告诉你谁先成功谁上岗。我们只用一条 Docker label 就完成切换:
services:
traefik:
image: traefik:v3.2
labels:
# 1. 保持 LE 作为主 CA
- traefik.http.routers.web.tls.certresolver=le
# 2. 把 ZeroSSL 作为备用,失败自动切换
- traefik.http.routers.web.tls.certresolver=le,zerossl
# 3. ZeroSSL 的 ACME 服务器和 EAB
- traefik.certificatesresolvers.zerossl.acme.email=ops@example.com
- traefik.certificatesresolvers.zerossl.acme.storage=/acme/zerossl.json
- traefik.certificatesresolvers.zerossl.acme.caServer=https://acme.zerossl.com/v2/DV90
- traefik.certificatesresolvers.zerossl.acme.eab.kid=${Z_SSL_KID}
- traefik.certificatesresolvers.zerossl.acme.eab.hmacEncoded=${Z_SSL_HMAC}
3.3 实测:从 502 到 200 的 5 分钟
- 03:30 加 label,重启 Traefik;
- 03:32 ZeroSSL 签发成功,证书指纹写入
/acme/zerossl.json; - 03:35 Prometheus 全绿,SLA 从 97.1% 回到 99.98%。
4. 复盘:给未来的自己留 3 张保命符
4.1 提前 30 天续期脚本
#!/bin/bash
# cron: 0 3 */15 * * /opt/scripts/renew.sh
for resolver in le zerossl; do
docker exec traefik \
traefik acme renew $resolver
done
4.2 监控:双重保险
- 黑盒探针
- module: http_2xx
prober: https
timeout: 5s
tls_config:
server_name: "*.mall.example.com" - 证书剩余时间
- alert: SSLCertExpiry
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 7
for: 1m
annotations:
summary: "证书 7 天内到期"
4.3 DNS API 幂等脚本
用阿里云 SDK + Traefik 的 delayBeforeCheck = 120s,确保 TXT 记录写入后等待缓存失效再验证。
5. 彩蛋:一键生成 ZeroSSL 账户的 Docker 小工具
docker run --rm -it \
-v $PWD:/out \
-e Z_EMAIL=ops@example.com \
ghcr.io/acmesh-official/acme.sh \
--register-account --server zerossl --eab-kid YOUR_KID --eab-hmac-key YOUR_HMAC
6. 结束语:别再把 90 天当无限
“免费的,才是最贵的。”
当你下次看到 Let’s Encrypt 的「90 days」小字时,请记住这篇文章——
以及那一杯凌晨 3 点的冰美式。
热门推荐
一个账号试用1000+ API
助力AI无缝链接物理世界 · 无需多次注册
3000+提示词助力AI大模型
和专业工程师共享工作效率翻倍的秘密
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- 如何防范User-Agent信息伪装引发的API访问风险
- 苹果支付流程:从零开始的接入指南
- 全面掌握 OpenAPI 规范:定义、生成与集成指南
- 深入解析granularity是什么?颗粒度中文详解
- 开发者如何利用缓存技术提升API性能
- Orbitz API 全攻略:旅行社高效整合酒店、航班与租车服务的必读指南
- REST API命名规范的终极指南:清晰度和一致性的最佳实践
- Go:基于 MongoDB 构建 REST API — Fiber 版
- Agrio 农业智能警报:如何让作物健康管理更上一层楼?
- 免费IP地址查询API接口推荐
- 【2025】AI 占星报告批量生成器|基于 Astro-Seek API 微调 7B 模型,一键输出每日/每周运势
- 微信API接口调用凭证+Access token泄露
热门推荐
一个账号试用1000+ API
助力AI无缝链接物理世界 · 无需多次注册