所有文章 > 技术杂货铺 > Traefik Docker 自动证书崩溃应急方案:ZeroSSL 快速接入指南
Traefik Docker 自动证书崩溃应急方案:ZeroSSL 快速接入指南

Traefik Docker 自动证书崩溃应急方案:ZeroSSL 快速接入指南

下文包含大量真实熬夜痕迹、心跳骤停截图、以及一份能在 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 点的冰美式。

#你可能也喜欢这些API文章!

我们有何不同?

API服务商零注册

多API并行试用

数据驱动选型,提升决策效率

查看全部API→
🔥

热门场景实测,选对API

#AI文本生成大模型API

对比大模型API的内容创意新颖性、情感共鸣力、商业转化潜力

25个渠道
一键对比试用API 限时免费

#AI深度推理大模型API

对比大模型API的逻辑推理准确性、分析深度、可视化建议合理性

10个渠道
一键对比试用API 限时免费