GKE中NGINX Ingress能否用Google托管证书?cert-manager假证书排查
我来帮你拆解并解决这两个GKE + NGINX Ingress的HTTPS配置问题哈!
首先得明确一个关键点:networking.gke.io/managed-certificates这个注解是GKE原生Ingress Controller专属的,NGINX Ingress Controller完全不识别它,所以直接加到你的配置里是不会有效果的。你有两个可行的解决方案:
方案A:切换到GKE原生Ingress Controller
如果可以替换Ingress类,那修改你的配置就能直接用Google托管证书:
- 移除
kubernetes.io/ingress.class: "nginx"注解(GKE原生Ingress会自动识别,也可以改成gce明确指定) - 保留
networking.gke.io/managed-certificates: "managed-certificate"注解 - 删掉cert-manager相关的
cert-manager.io/issuer注解 - 移除整个
tls块,因为GKE原生Ingress会自动关联托管证书,不需要手动指定secret
修改后的示例配置:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-https namespace: non-default annotations: kubernetes.io/ingress.allow-http: "false" networking.gke.io/managed-certificates: "managed-certificate" spec: rules: - host: example.com http: paths: - path: "/" backend: serviceName: hello-service servicePort: hello-port - path: "/kube" backend: serviceName: hello-kubernetes servicePort: 80
⚠️ 注意:你需要提前创建好对应的ManagedCertificate资源,并且确保你的域名已经解析到GKE原生Ingress分配的外部IP。
方案B:继续用NGINX Ingress,用cert-manager签发证书替代GMC
如果不想换Ingress控制器,那放弃Google托管证书,专注让cert-manager正常工作就好——接下来就解决你遇到的「Fake Certificate」问题。
这个状态说明cert-manager没有成功为你的Ingress签发有效证书,所以NGINX只能 fallback到默认的假证书。我们一步步排查解决:
1. 先检查cert-manager的Issuer状态
首先确认你创建的letsencrypt-production Issuer(或ClusterIssuer)处于Ready状态:
kubectl get issuer letsencrypt-production -n non-default
如果状态不是Ready,赶紧看cert-manager的日志找原因:
kubectl logs -n cert-manager -l app=cert-manager
常见问题比如:ACME挑战失败(域名解析不对,或者NGINX拦截了验证请求)。
2. 检查Certificate资源的状态
cert-manager会根据Ingress的tls块和cert-manager.io/issuer注解自动创建Certificate资源,先看看它的状态:
kubectl get certificates -n non-default
如果对应的证书状态不是Ready,用describe看详细错误信息:
kubectl describe certificate selfsigned-cert-tls -n non-default
3. 修正Ingress配置里的冲突点
你的当前配置有几个冲突的地方,直接导致cert-manager无法正常工作:
- 同时指定了
networking.gke.io/managed-certificates(GKE原生Ingress用)和cert-manager.io/issuer(cert-manager用),这俩属于不同的控制器,会互相干扰,必须删掉其中一个。 tls块里的secretName是selfsigned-cert-tls,如果这个secret是你手动创建的自签名证书,cert-manager不会主动替换它,建议删掉这个自签名secret,让cert-manager重新生成。
修改后的NGINX + cert-manager配置:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-https namespace: non-default annotations: kubernetes.io/ingress.allow-http: "false" kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/ssl-redirect: "true" cert-manager.io/issuer: "letsencrypt-production" # 删掉GMC的注解,NGINX不认它 # networking.gke.io/managed-certificates: "managed-certificate" spec: tls: - hosts: - example.com # 这里的secretName可以随便取,cert-manager会自动创建并维护它 secretName: example-com-tls rules: - host: example.com http: paths: - path: "/" backend: serviceName: hello-service servicePort: hello-port - path: "/kube" backend: serviceName: hello-kubernetes servicePort: 80
4. 验证ACME挑战是否能正常访问
Let's Encrypt用HTTP-01挑战时,需要确保http://example.com/.well-known/acme-challenge/xxx能访问到cert-manager的挑战Pod:
- 确认cert-manager的Pod在运行
- 检查域名
example.com已经解析到NGINX Ingress的外部IP - 可以临时关掉
kubernetes.io/ingress.allow-http: "false",等证书签发成功后再打开,避免挑战请求被拦截
5. 手动触发证书签发(如果需要)
如果Certificate一直处于Pending状态,可以删掉它让cert-manager重新创建:
kubectl delete certificate example-com-tls -n non-default
然后实时跟踪cert-manager的日志,看签发过程有没有报错:
kubectl logs -f -n cert-manager -l app=cert-manager
内容的提问来源于stack exchange,提问作者Ram

