You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AKS中统一Helm Chart部署Cert-Manager与Nginx证书签发失败

问题背景

本人接触Kubernetes约1个月,目前正在将业务从Azure App Service迁移至AKS,遇到Nginx Ingress Controller与cert-manager协同异常、HTTP-01挑战持续失败导致证书无法签发的问题,怀疑故障与DNS记录切换时机、组件安装方式有关。
部署架构分为两类Helm Chart:

  • networking Chart:作为集群基础网络组件,仅需部署1个实例
  • application Chart:对应业务应用,可部署多个实例分别承载staging、QA、生产等多环境
现有配置

networking Chart配置

该Chart无自定义模板文件,相关配置如下:

Chart.yaml

apiVersion: v2
name: networking
description: A Helm chart for Kubernetes
type: application
version: 0.0.1
appVersion: "1.1.0"
icon: <<自有图标地址>>

dependencies:
  - name: nginx-ingress
    version: 0.14.0
    repository: https://helm.nginx.com/stable
    alias: nginx-ingress
  - name: cert-manager
    version: 1.8.2
    repository: https://charts.jetstack.io

values.yaml

replicaCount: 1

cert-manager:
  installCRDs: true

nginx-ingress:
  controller:
    service:
      annotations: 
        "service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path": /healthz

application Chart配置

application Chart按部署环境配置对应命名空间的Issuer与Ingress资源,配置如下:

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  {{ if eq .Values.environment "Release" }}
  namespace: release
  {{ else if eq .Values.environment "ReleaseQA" }}
  namespace: release-qa
  {{ else if eq .Values.environment "ReleaseProd" }}
  namespace: release-prod
  {{ else }}
  {{ required "value for .Values.environment is not as expected" .Values.environment }}
  {{ end }}
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    # ingress.kubernetes.io/ssl-redirect: "false" # 已尝试过该配置项
    cert-manager.io/issuer: letsencrypt-nginx
    # acme.cert-manager.io/http01-ingress-class: "nginx-cert-controller" # 已尝试过该配置项
spec:
  tls:
    {{ if eq .Values.environment "Release" }}
    - hosts:
        - core.staging.foo.com
      secretName: core-cert-nginx
    - hosts:
        - portal.staging.foo.com
      secretName: portal-cert-nginx
    - hosts:
# 其余环境的TLS定义省略
# 后续为路由规则配置
  ingressClassName: nginx
  rules:
    {{ if eq .Values.environment "Release" }}
    - host: core.staging.foo.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: core-service
                port: 
                  number: 80
    - host: portal.staging.foo.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: portal-service
                port: 
                  number: 80

issuer.yaml

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-nginx
  {{ if eq .Values.environment "Release" }}
  namespace: release
  {{ else if eq .Values.environment "ReleaseQA" }}
  namespace: release-qa
  {{ else if eq .Values.environment "ReleaseProd" }}
  namespace: release-prod
  {{ else }}
  {{ required "value for .Values.environment is not as expected" .Values.environment }}
  {{ end }}
spec: 
  acme:
    email: <<有效ACME注册邮箱>>
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-nginx-private-key
    solvers:
      # 使用HTTP-01挑战提供者
      - http01:
          ingress:
            class: nginx
故障现象

当前集群内所有内部服务、应用Pod均已创建且运行健康,故障表现如下:

  • HTTP-01挑战持续失败,通过kubectl describe查看Challenge资源,发现cert-manager创建的挑战端点无法访问,切换不同配置时会返回302、404、502状态码,或请求被直接路由到业务应用
  • 存在偶发现象:如果首次挑战未触发失败,则可正常完成签发,后续也可通过cert-manager kubectl插件正常续期
  • 操作背景:使用外部域名服务商,为尽可能降低流量切换的停机时间,在域名解析记录切换到AKS负载均衡新IP、DNS传播未完全完成时就会触发证书签发,此阶段挑战可能会多次失败
环境信息
  • 平台:Azure AKS
  • Kubernetes版本:1.23.5
  • nginx-ingress Chart版本:0.14.0
  • cert-manager Chart版本:1.8.2
  • 业务负载:2个静态React网站、4个.NET Core后端API及其他类型服务
排查与修复方向

1. 解决rewrite-target全局注解导致的路由错误

你在业务Ingress上全局配置了nginx.ingress.kubernetes.io/rewrite-target: /,cert-manager生成的临时挑战Ingress和业务Ingress共享同域名路由规则时,/.well-known/acme-challenge/开头的挑战请求会被直接重写到业务服务根路径,打到React或者.NET服务上,自然返回404、业务首页响应等错误,这是请求被路由到业务应用的核心原因。
修复方式:修改Issuer的solver配置,给cert-manager自动生成的临时挑战Ingress单独注入注解,覆盖rewrite规则:

solvers:
  - http01:
      ingress:
        class: nginx
        annotations:
          nginx.ingress.kubernetes.io/rewrite-target: "/.well-known/acme-challenge/"
          nginx.ingress.kubernetes.io/ssl-redirect: "false"

更彻底的修复是把业务侧的rewrite-target从Ingress全局注解移到具体路径的配置项里,不要对所有路径生效,仅对需要重写的业务路径配置规则。

2. 调整DNS切换与证书签发的顺序

你提到的“首次挑战成功后续续期正常”现象,完全是DNS切换时机不对导致的:

  • HTTP-01挑战由Let's Encrypt从全球多个边缘节点发起请求,你在DNS记录刚修改、全球传播未完成时触发签发,部分区域的请求会解析到旧的Azure App Service地址,旧地址没有对应的挑战响应路径,必然返回失败
  • cert-manager默认的重试逻辑在连续多次失败后会拉长重试间隔,很容易卡在持续失败的状态,而首次签发成功后,后续续期时证书对应的Secret已经存在,Ingress路由规则长期生效,不会再受DNS切换过程的影响
    正确操作流程:
  • 提前将AKS负载均衡IP配置到临时测试域名,先完成所有证书的首次签发,确认证书Secret正常生成
  • 正式切换业务域名前,把域名TTL调到60秒,等原有TTL过期后再把记录指向AKS负载均衡IP
  • 切换后等待10-15分钟全球DNS传播完成,再做业务可用性校验,不要在传播过程中触发首次签发

3. 校验Ingress类与LB健康状态

  • 执行kubectl get ingressclass确认集群内只有一个名为nginx的IngressClass对应你部署的Nginx Ingress Controller,避免其他Ingress控制器(比如AKS自带的应用网关Ingress)抢占路由
  • 在Azure门户查看负载均衡的后端池健康状态,确认你配置的/healthz探针可以正常访问Nginx Ingress的80端口,后端实例不健康时LB会直接返回502,请求到不了Ingress控制器
  • 检查Nginx Ingress Controller的全局配置,确认没有配置全局强制HTTPS跳转规则拦截80端口的挑战请求,如果开启了全局HTTPS跳转,要把/.well-known/acme-challenge/路径加入跳转白名单

内容的提问来源于stack exchange,提问作者Márton Péntek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:45:31