同一AKS集群部署两个带Nginx Ingress和TLS的隔离应用实例失败求助
故障根因排查
你当前配置存在4个核心错误,直接导致证书签发失败,Nginx使用默认自签名证书返回:
- 错误1:IngressClass配置错误:IngressClass属于集群级资源,不能指定namespace参数,你手动创建的
ingress-class11.yaml/ingress-class12.yaml中填写的namespace: tenant11是无效配置,同时你通过helm安装Nginx Ingress控制器时已经指定了ingressClassResource参数,helm会自动创建对应IngressClass,重复手动创建会导致资源冲突,控制器无法匹配到正确的Ingress规则。 - 错误2:多cert-manager实例冲突:cert-manager默认会监听全集群所有Ingress资源,你在两个租户命名空间分别部署cert-manager实例,会导致两个实例抢着处理同一个证书请求,出现调度混乱。
- 错误3:ClusterIssuer配置错误:ClusterIssuer属于cert-manager的集群级资源,不支持填写
namespace参数,你配置中的namespace: tenant11是无效字段,会导致ClusterIssuer状态异常。 - 错误4:ACME挑战被跳转HTTPS:从日志可见cert-manager发起的HTTP 80端口ACME挑战请求被Nginx返回308跳转到HTTPS,此时证书还未签发,Nginx使用自签名证书响应,导致Let's Encrypt挑战失败,无法成功签发正式证书。
修复步骤
1. 清理无效资源
先删除所有冲突的错误配置:
# 删除手动创建的无效IngressClass kubectl delete ingressclass class11 class12 # 删除无效ClusterIssuer kubectl delete clusterissuer letsencrypt11 letsencrypt12 # 卸载两个租户级cert-manager helm uninstall certman11 -n tenant11 helm uninstall certman12 -n tenant12 # 删除未签发的证书Secret kubectl delete secret tls-secret11 -n tenant11 kubectl delete secret tls-secret12 -n tenant12
2. 部署全局cert-manager
仅部署一个全局cert-manager实例即可满足多租户证书签发需求:
helm install cert-manager jetstack/cert-manager --namespace kube-system --create-namespace --set installCRDs=true
3. 修正ClusterIssuer配置
去掉namespace字段,两个ClusterIssuer分别绑定对应IngressClass:
# cluster-issuer11.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt11 spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: <替换为你的邮箱> privateKeySecretRef: name: letsencrypt11 solvers: - http01: ingress: class: class11
cluster-issuer12.yaml仅需把所有11替换为12即可,修改完成后执行:
kubectl apply -f cluster-issuer11.yaml kubectl apply -f cluster-issuer12.yaml
4. 修正Ingress配置
新增注解避免ACME挑战请求被跳转HTTPS:
# ingress11.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tenant11-rms-ingress namespace: tenant11 annotations: cert-manager.io/cluster-issuer: letsencrypt11 # 新增以下配置,跳过ACME路径的HTTPS跳转 nginx.ingress.kubernetes.io/configuration-snippet: | if ($request_uri ~ ^/\.well-known/acme-challenge/) { break; } spec: ingressClassName: class11 tls: - hosts: - tenant11.australiaeast.cloudapp.azure.com secretName: tls-secret11 rules: - host: tenant11.australiaeast.cloudapp.azure.com http: paths: - path: / pathType: Prefix backend: service: name: tenant11-rms-service port: number: 80
同样修改ingress12.yaml后执行生效:
kubectl apply -f ingress11.yaml kubectl apply -f ingress12.yaml
验证方法
等待1-2分钟后执行以下命令查看证书状态,当READY列显示为True即代表证书签发成功:
kubectl get certificates -A
此时再访问对应域名即可看到正常的Let's Encrypt正式证书。
内容的提问来源于stack exchange,提问作者Franco Tiveron
相关产品推荐
相关产品推荐

