Files
Kubernetes/Helm/Helm部署Cert-Manager.md
2025-08-25 17:53:08 +08:00

6.7 KiB
Raw Permalink Blame History

本文作者:丁辉

Helm部署Cert-Manager

Github仓库 Helm仓库 官网文档

介绍

cert-manager是一个在Kubernetes环境中用于管理SSL证书的开源工具。随着互联网安全意识的提升HTTPS协议的使用变得越来越广泛这就需要为网站配置安全的SSL证书。传统的证书管理方式需要人工参与且当证书数量众多时管理工作将变得异常繁琐。cert-manager的出现极大地简化了这一过程尤其是在自动化和简化证书获取、续期方面表现出色。

开始部署

  1. 添加 Helm 仓库

    helm repo add jetstack https://charts.jetstack.io
    helm repo update
    
  2. 编辑 values.yaml

    vi cert-manager-values.yaml
    

    内容如下

    crds:
      enabled: true
    
    # 开启监控
    prometheus:
      enabled: true
      servicemonitor:
        enabled: true
    
  3. 部署

    helm install \
      cert-manager jetstack/cert-manager \
      --namespace cert-manager \
      --create-namespace \
      -f cert-manager-values.yaml
    
  4. 验证

    安装 GO 工具

    • Centos

      yum -y install go
      
    • Ubuntu

      apt -y install golang
      

    安装 Cmctl

    OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -fsSL -o cmctl https://github.com/cert-manager/cmctl/releases/latest/download/cmctl_${OS}_${ARCH}
    chmod +x cmctl
    sudo mv cmctl /usr/local/bin
    

    执行命令验证安装

    cmctl check api
    

    正常返回为:The cert-manager API is ready

卸载

  1. 卸载 cert-manager

    helm uninstall cert-manager -n cert-manager
    
  2. 删除命名空间

    kubectl delete ns cert-manager
    
  3. 删除资源

    kubectl delete apiservice v1beta1.webhook.cert-manager.io
    

使用方法(HTTP01)

Cert-Manager 搭配 Let's Encrypt 实现证书自动签发

官方文档

Let's Encrypt

介绍

cert-manager 中,IssuerClusterIssuer 是用来配置和管理证书颁发的 Kubernetes 资源。这两种资源类型都用于定义如何颁发证书,但它们的作用域和使用场景有所不同:

Issuer

  • 作用域Issuer 的作用域限定在单个 Kubernetes 命名空间内。这意味着 Issuer 只能为在同一命名空间内的证书资源管理和颁发证书。
  • 用途:当你需要在特定命名空间内独立管理证书颁发策略时使用。例如,不同的团队或项目可能在各自的命名空间内使用不同的 Issuer 来满足特定的安全或配置需求。
  • 配置Issuer 可以配置多种类型的证书颁发者,包括 ACME (如 Let's Encrypt)CA (自签名或内部 CA),或 Vault 等。

ClusterIssuer

  • 作用域ClusterIssuer 的作用域是整个 Kubernetes 集群。它可以在任何命名空间中为证书资源颁发证书。
  • 用途:当你想要一个统一的证书颁发策略,适用于整个 Kubernetes 集群时使用。这对于维护一致的证书管理策略非常有用,尤其是在需要跨多个命名空间统一管理 SSL/TLS 证书时。
  • 配置:与 Issuer 类似,ClusterIssuer 也可以配置为使用 ACME、CA、Vault 等多种类型的证书颁发者。

Let's Encrypt Server 参数区分

  • https://acme-staging-v02.api.letsencrypt.org/directory (用于测试环境)
  • https://acme-v02.api.letsencrypt.org/directory (用于生产环境)

配置 Issuer 方法

  • 测试

    1. ingress 资源配置 annotations

      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-staging"
      
    2. 部署 Yaml

      kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/staging-issuer.yaml
      
  • 生产

    1. ingress 资源配置 annotations

      annotations:
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
      
    2. 部署 Yaml

      kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/production-issuer.yaml
      

配置 ClusterIssuer 方法

  1. ingress 资源配置 annotations

    annotations:
      cert-manager.io/cluster-issuer: "letsencrypt-prod"
    
  2. 部署 Yaml

    kubectl create --edit -f https://gitee.com/offends/Kubernetes/raw/main/File/Yaml/cluster-issuer.yaml
    
  3. 检查 Certificate 资源是否创建

    kubectl get Certificate -A
    

使用方法(NDS01)

外部DNS 提供商列表

问题记录

2025-08-24日重新安装 Nginx-Ingress 和 Cert-Manager 时发现无法正常签发证书

根本原因

  • cert-manager 在使用 HTTP-01 验证时,会临时创建一个 /.well-known/acme-challenge/<token> 的 Ingress。
  • 集群中启用了 ingress-nginx-admissionValidatingWebhookConfiguration它默认拦截所有命名空间的 Ingress 创建。
  • ingress-nginx-admission 误判或不允许 cert-manager 创建的临时 Ingress其验证逻辑认为路径不合法
  • 导致 cert-manager 的临时 Ingress 在创建阶段就被 Admission Webhook 拒绝,证书申请失败。

解决思路

  1. 根本问题是 Admission Webhook 拦截了 cert-manager,而不是 cert-manager 本身配置错误。
  2. 有两种主要解决方式:
    • 临时删除 Admission Webhook(快速见效,但失去 Ingress 配置校验功能)。
    • 修改 Admission Webhook 的 namespaceSelector,跳过 cert-manager 命名空间(推荐,安全且长期可用)。

最终解决方案

  • 确认 Admission Webhook 名称是 ingress-nginx-admission

  • 使用 kubectl patch 修改其 namespaceSelector,忽略 cert-manager

    kubectl patch validatingwebhookconfiguration ingress-nginx-admission \
      --type='json' \
      -p='[{"op": "replace", "path": "/webhooks/0/namespaceSelector", "value": {"matchExpressions":[{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["cert-manager","kube-system"]}]}}]'
    
  • 删除旧的 Challenge/Ordercert-manager 重新申请证书。

  • 问题解决后,cert-manager 可以正常申请并自动续签证书,同时其他命名空间的 Ingress 仍然有 Admission 验证保护。