Microk8s/Kubernetes中Ingress未正确使用Let's Encrypt证书的解决方法
现有K8s配置
--- kind: Namespace apiVersion: v1 metadata: name: test labels: name: test --- apiVersion: apps/v1 kind: Deployment metadata: namespace: test name: test-depl spec: selector: matchLabels: app: test-app template: metadata: labels: app: test-app spec: containers: - name: test-app image: jfsanchez91/http-test-server --- apiVersion: v1 kind: Service metadata: namespace: test name: test-svc spec: selector: app: test-app ports: - name: test-app protocol: TCP port: 80 targetPort: 8090 --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: namespace: test name: letsencrypt-cert-issuer-test-staging spec: acme: email: email@example.com server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-cert-issuer-test-staging solvers: - http01: ingress: class: public --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: namespace: test name: letsencrypt-cert-issuer-test-prod spec: acme: email: email@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-cert-issuer-test-prod solvers: - http01: ingress: class: public --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: test name: ingress-routes annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: "letsencrypt-cert-issuer-test-prod" spec: tls: - hosts: - test.example.com secretName: tls-secret rules: - host: test.example.com http: paths: - path: / pathType: Prefix backend: service: name: test-svc port: number: 80
问题描述
Let's Encrypt证书已成功签发并正确存储于tls-secret中,但访问test.example.com时,浏览器提示证书无效(错误码:NET::ERR_CERT_AUTHORITY_INVALID),实际使用的是Kubernetes默认证书:
Common Name (CN): Kubernetes Ingress Controller Fake Certificate
Organization (O): Acme Co
技术问询:如何正确配置Ingress以使用已生成的Let's Encrypt证书?是否还有其他需要配置的内容?
更新说明
tls-secret的类型为kubernetes.io/tls,详情如下:
$ kubectl -n test describe secrets tls-secret Name: tls-secret Namespace: test Labels: <none> Annotations: cert-manager.io/alt-names: test.example.com cert-manager.io/certificate-name: tls-secret cert-manager.io/common-name: test.example.com cert-manager.io/ip-sans: cert-manager.io/issuer-group: cert-manager.io cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: letsencrypt-cert-issuer-test-prod cert-manager.io/uri-sans: Type: kubernetes.io/tls Data ==== tls.key: 1679 bytes tls.crt: 5599 bytes
解决方案
1. 统一Ingress Class配置
当前Ingress使用的kubernetes.io/ingress.class是nginx,但ClusterIssuer的HTTP01 solver指定的ingress class是public,两者不匹配会导致cert-manager签发证书时的临时Ingress无法被正确处理,也可能影响主Ingress的证书加载。
修改ClusterIssuer的solver配置,将ingress class改为nginx:
# 生产环境ClusterIssuer示例 apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: namespace: test name: letsencrypt-cert-issuer-test-prod spec: acme: email: email@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-cert-issuer-test-prod solvers: - http01: ingress: class: nginx # 改为与Ingress一致的class
2. 检查Ingress Controller日志
执行命令查看Ingress Controller日志,确认是否有加载tls-secret的错误:
# 假设Ingress Controller部署在ingress-nginx命名空间 kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
如果日志中出现无法读取tls-secret的错误,检查secret权限或名称拼写。
3. 重新应用Ingress配置
虽然当前Ingress的TLS配置正确,但可以重新应用配置触发刷新:
kubectl apply -f 你的Ingress配置文件.yaml
4. 修正ClusterIssuer的命名空间配置
ClusterIssuer是集群级资源,不需要指定namespace字段,建议移除该字段避免潜在问题:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-cert-issuer-test-prod # 移除namespace字段 spec: # 其余配置保持不变
5. 重启Ingress Controller
如果上述步骤完成后仍未生效,重启Ingress Controller Pod强制加载最新配置:
kubectl rollout restart deployment -n ingress-nginx ingress-nginx-controller
内容的提问来源于stack exchange,提问作者Jorge F. Sanchez

