K8s内部ACME server搭配cert-manager签发集群内证书的HTTP挑战问题
可行性结论
完全可以实现,整个证书签发流程可以100%在集群内部完成,不需要创建Ingress资源,也不会有挑战流量流出集群。你之前了解的HTTP/DNS挑战流程仅针对对接公网公共ACME服务(如Let's Encrypt)的场景,私有内部ACME服务不需要这套验证逻辑。
核心实现步骤
- 优先选择更简单的CA Issuer方案(无需走ACME协议,完全无挑战环节):
- 将你部署的step-ca根证书和签名密钥导出,存为集群内的Secret资源
- 创建跨namespace可用的ClusterIssuer,类型指定为
ca,引用上述Secret:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: internal-ca-issuer spec: ca: secretName: step-ca-root-secret # 存储step-ca根证书和签名密钥的Secret名称 - 如果你必须使用ACME协议对接step-ca:
- 先配置step-ca的ACME接口关闭域名所有权验证,允许直接为
${app}.${namespace}格式的内部域名签发证书 - 创建ACME类型的ClusterIssuer,server地址填写step-ca的集群内部Service域名,无需配置任何挑战规则:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: internal-step-ca-acme spec: acme: server: https://step-ca.${你的step-ca所在命名空间}.svc.cluster.local/acme/directory privateKeySecretRef: name: step-ca-acme-account-key solvers: [] # 留空即可,私有ACME不需要挑战配置 - 先配置step-ca的ACME接口关闭域名所有权验证,允许直接为
- 为工作负载创建Certificate资源,指定你需要的通用名称格式:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: stunnel-cert namespace: ${你的应用所在命名空间} spec: commonName: ${app}.${namespace} dnsNames: - ${app}.${namespace} secretName: stunnel-cert-secret # 生成的证书会存在这个Secret里 issuerRef: name: internal-ca-issuer # 替换为你创建的Issuer名称 kind: ClusterIssuer
Istio场景适配
- 配置cert-manager命名空间的Sidecar资源,允许cert-manager组件访问step-ca所在命名空间的Service,避免Istio侧车拦截请求导致签名失败
- 生成的证书Secret直接挂载到stunnel容器的证书读取路径即可,Istio的出站流量代理规则不会影响stunnel对证书的读取和使用
内容的提问来源于stack exchange,提问作者Maciek Leks
相关产品推荐
相关产品推荐

