Google Cloud中Let's Encrypt证书dns01挑战未生效问题排查
我之前也碰到过一模一样的情况——明明在Certificate里指定了DNS01验证,结果Order还是固执地用HTTP-01,导致CloudDNS根本不生成ACME TXT记录,证书一直处于未就绪状态。结合你的配置和报错信息,咱们一步步来排查解决:
1. 先检查Issuer/ClusterIssuer的核心配置
这是最容易踩坑的点:如果你的letsencrypt Issuer(或ClusterIssuer)本身没配置DNS01的求解器,哪怕Certificate里写了dns01也没用,Cert-Manager会直接回退到默认的HTTP-01。
你需要确保Issuer里有完整的solvers配置,针对CloudDNS的示例如下:
apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-admin-email@evolut.net # 换成你的邮箱 privateKeySecretRef: name: letsencrypt solvers: - dns01: clouddns: project: your-gcp-project-id # 替换成你的GCP项目ID serviceAccountSecretRef: name: clouddns-service-account # 存储GCP服务账号密钥的Secret名称 key: key.json # Secret里密钥文件的键名
划重点:如果用的是ClusterIssuer,后面Certificate的
issuerRef里必须加上kind: ClusterIssuer,不然Cert-Manager会在default namespace里找同名的Issuer,直接导致配置不生效。
2. 清理旧的Order和Challenge资源
当你修改了Certificate的验证方式后,之前生成的Order还会保留旧的HTTP-01配置,不会自动更新。手动删掉这些旧资源,让Cert-Manager重新生成符合新配置的Order:
# 删除关联的Order资源 kubectl delete orders -l certmanager.k8s.io/certificate-name=san-tls # 顺带删掉对应的Challenge kubectl delete challenges -l certmanager.k8s.io/certificate-name=san-tls
删完之后等个几十秒,Cert-Manager会自动重新创建Order,这时候应该就会用DNS01挑战了。
3. 简化Certificate配置,避免字段冲突
你的配置里同时写了commonName、altNames和dnsNames,在Cert-Manager v1alpha1版本里,dnsNames是优先级更高的字段,多个重复的域名配置可能会导致"DNS names DoesNotMatch"的报错。建议简化成只保留dnsNames:
apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: san-tls namespace: default spec: secretName: san-tls issuerRef: name: letsencrypt kind: ClusterIssuer # 如果是ClusterIssuer必须加这个 dnsNames: - www.evolut.net - portal.evolut.net acme: config: - dns01: provider: clouddns domains: - www.evolut.net - portal.evolut.net
4. 确认CloudDNS的权限配置
如果上面几步都做了还是没生成TXT记录,就得检查GCP服务账号的权限了:
- 给对应的GCP服务账号添加
roles/dns.admin角色,确保它有权限修改CloudDNS记录 - 确认存储服务账号密钥的Secret已经正确创建,并且Cert-Manager的Pod能正常读取它
你可以通过查看Cert-Manager的日志来排查权限问题:
kubectl logs -n cert-manager -l app=cert-manager
如果日志里出现"permission denied"之类的报错,直接去GCP IAM里调整服务账号权限就行。
5. 验证最终状态
做完上面的步骤后,等个2-3分钟,然后查看证书和Order的状态:
kubectl describe certificate san-tls kubectl describe order -l certmanager.k8s.io/certificate-name=san-tls
正常情况下,Order的挑战类型会显示为dns-01,CloudDNS里也会自动生成_acme-challenge.xxx.evolut.net的TXT记录,验证通过后Certificate的Ready状态就会变成True了。
内容的提问来源于stack exchange,提问作者Patrick Geyer

