ClusterIssuer的Secret无法跨Ingress复用,如何用单实例管理集群所有Ingress?
原本以为ClusterIssuer的核心价值是无需在不同资源中重复创建,能用一个主ClusterIssuer管理集群内所有Ingress。但实际观察发现,当第一个Ingress使用ClusterIssuer生成的Secret后,第二个Ingress无法正常创建对应Secret,提示名称已被占用。请问有没有办法用一个ClusterIssuer管理集群内所有Ingress?
ClusterIssuer 配置
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-grafana namespace: cert-manager spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: foo@gmail.com privateKeySecretRef: name: letsencrypt-grafana solvers: - selector: dnsZones: - "foo.com" dns01: route53: region: eu-central-1 hostedZoneID: foo accessKeyID: foo secretAccessKeySecretRef: name: aws-route53-creds key: password.txt
Ingress 配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana-ingress namespace: loki annotations: cert-manager.io/cluster-issuer: letsencrypt-grafana kubernetes.io/tls-acme: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "125m" nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx tls: - hosts: - grafana.foo.com secretName: letsencrypt-grafana # cert-manager 会将生成的证书存储在此Secret中。 rules: - host: grafana.foo.com http: paths: - path: / pathType: Prefix backend: service: name: loki-grafana port: number: 80
问题根源是多个Ingress重复使用了同一个Secret名称,而非ClusterIssuer本身的限制。ClusterIssuer作为集群级资源,完全支持管理所有namespace下Ingress的证书申请,正确做法如下:
每个Ingress使用独立的Secret名称
不要让多个Ingress共用同一个secretName,每个Ingress的tls.secretName需设置为唯一值(比如对应域名的标识)。例如第二个Ingress若对应prometheus.foo.com,则将secretName设为letsencrypt-prometheus。复用同一个ClusterIssuer
保持所有Ingress的cert-manager.io/cluster-issuer注解指向同一个ClusterIssuer即可,ClusterIssuer的跨namespace能力会自动处理不同namespace下的证书签发请求。
示例第二个Ingress配置:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: prometheus-ingress namespace: monitoring annotations: cert-manager.io/cluster-issuer: letsencrypt-grafana # 复用同一个ClusterIssuer spec: ingressClassName: nginx tls: - hosts: - prometheus.foo.com secretName: letsencrypt-prometheus # 唯一的Secret名称 rules: - host: prometheus.foo.com http: paths: - path: / pathType: Prefix backend: service: name: prometheus-service port: number: 80
- 额外说明:ClusterIssuer的私钥Secret
ClusterIssuer的privateKeySecretRef是存储ACME账户私钥的Secret,仅会创建一次,所有通过该ClusterIssuer申请的证书都会用此私钥签名,这是正常逻辑,不会影响多证书生成。
总结:只要每个Ingress指定唯一的secretName,同一个ClusterIssuer就能轻松管理集群内所有Ingress的证书需求。
内容的提问来源于stack exchange,提问作者Elazar

