目录

Ingress配置tls不生效

Kubernetes Ingress 证书不生效问题排查记录

问题背景

业务需要同时支持两种访问方式:

  • 内网:通过节点 IP + NodePort 直接访问(无需域名)
  • 公网:通过域名访问,需由 Ingress 直接处理 SSL 证书(原上游 Nginx 代理已移除) 配置了 tls 段并绑定了有效证书 Secret,但访问时始终返回 Kubernetes Ingress Controller Fake Certificate(默认假证书),浏览器提示“不安全”。

排查过程

1. 初步排查:证书有效性验证

  • 检查 Secret 状态:目标 Secret 为 kubernetes.io/tls 类型,包含完整的 tls.crttls.key
  • 验证证书有效期:证书未过期,SAN 包含通配符域名,完全匹配业务域名
  • 确认 Secret 已被 Ingress Controller 加载:控制器日志中可见 Adding secret to local store 相关记录 ✅ 结论:证书本身合法有效,Secret 加载无问题

2. 配置排查:Ingress 规则与 TLS 关联

  • 检查 Ingress spec.tls 配置:已正确指定域名(通配符/精确域名)和 Secret 名称
  • 检查 Ingress Controller 日志:未发现证书加载错误
  • 进入 Controller Pod 查看生成的 Nginx 配置:搜索不到业务域名的虚拟主机配置关键发现:证书已加载,但未生成对应 Nginx 配置,说明 Ingress 规则未与 TLS 配置关联

3. 根因定位:Ingress 规则设计缺陷

最初为了支持“任意 Host 来源请求”(内网 IP 访问 + 公网域名访问),Ingress 未配置 spec.rules[].host,仅保留了无 Host 的通用规则。 核心原理

  • Ingress Controller 仅会为配置了 host 的规则生成对应的 TLS 虚拟主机配置
  • host 的通用规则不会触发 TLS 配置写入,因此请求会 fallback 到默认假证书
  • 即便配置了 spec.tls 段,若没有匹配的 host 规则,证书也不会生效 ✅ 最终根因:未配置 host 的 Ingress 规则导致 TLS 证书无法关联生效

4. 额外干扰:端口冲突导致 Controller 无法调度

排查过程中曾因 ingress-nginx-controller Pod 配置了 hostPort: 80/443,导致节点端口占用,Pod 无法调度(Event 提示 FailedScheduling1 node(s) didn't have free ports for the requested pod ports),进一步影响了配置生效。 临时修复:移除 Pod 模板中的 hostPort 配置,仅保留 containerPort,通过 NodePort 对外暴露服务,解决调度问题。


解决方案

设计思路

通过双规则 Ingress同时满足内网 IP 访问和公网域名+证书访问:

  1. host 的规则:绑定域名和 TLS 证书,用于公网访问

  2. host 的规则:保持通用匹配,用于内网 IP 直接访问

    最终 Ingress 配置

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: minio
    namespace: minio
    annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false" # 避免强制跳转 HTTPS 影响内网访问
    spec:
    ingressClassName: nginx
    # TLS 配置:仅对带 host 的规则生效
    tls:
    - hosts:
    - <your-business-domain> # 替换为实际业务域名
    secretName: <your-tls-secret> # 替换为实际证书 Secret 名称
    # 双规则设计
    rules:
    # 规则1:公网域名访问(带证书)
    - host: <your-business-domain>
    http:
    paths:
    - path: /oss
    pathType: Prefix
    backend:
    service:
    name: minio
    port:
    name: minio-api
    # 规则2:内网IP访问(无host,无证书)
    - http:
    paths:
    - path: /oss
    pathType: Prefix
    backend:
    service:
    name: minio
    port:
    name: minio-api
    

验证结果

  1. 公网访问https://<your-business-domain>/oss/mall/index.html
    • 正常加载自定义证书
    • 浏览器不再提示“不安全”,访问正常
  2. 内网访问https://<node-ip>:<node-port>/oss/mall/index.html
    • 可正常访问,使用默认假证书(符合预期,内网访问无需证书验证)
  3. Nginx 配置验证
    • 进入 Ingress Controller Pod,可查询到业务域名对应的虚拟主机配置和证书路径

经验总结

  1. Ingress TLS 生效前提:必须为需要证书的域名配置host 的规则,否则 TLS 配置不会写入 Nginx
  2. 通用访问需求处理:若需同时支持域名和 IP 访问,应采用「带 host 规则 + 无 host 规则」的双规则设计,而非完全移除 host
  3. 端口配置注意:Ingress Controller 避免使用 hostPort,优先通过 NodePort/LoadBalancer 对外暴露服务,防止端口冲突导致 Pod 无法调度
  4. 排查优先级:证书不生效时,优先检查「Ingress 规则与 TLS 配置的关联」>「证书有效性」>「Controller 状态」

后续优化建议

  • 内网访问可考虑单独部署无 TLS 的 Ingress,避免与公网证书规则混淆
  • 引入 Cert-Manager 自动管理证书生命周期,减少手动维护成本
  • 为 Ingress 配置健康检查和访问日志,便于后续问题排查