> 本文作者:丁辉 # Helm部署Cert-Manager [Github仓库](https://github.com/cert-manager/cert-manager/tree/master) [Helm仓库](https://artifacthub.io/packages/helm/cert-manager/cert-manager) [官网文档](https://cert-manager.io/docs/installation/helm/) ## 介绍 **cert-manager是一个在Kubernetes环境中用于管理SSL证书的开源工具**。随着互联网安全意识的提升,HTTPS协议的使用变得越来越广泛,这就需要为网站配置安全的SSL证书。传统的证书管理方式需要人工参与,且当证书数量众多时,管理工作将变得异常繁琐。cert-manager的出现极大地简化了这一过程,尤其是在自动化和简化证书获取、续期方面表现出色。 ## 开始部署 1. 添加 Helm 仓库 ```bash helm repo add jetstack https://charts.jetstack.io helm repo update ``` 2. 编辑 values.yaml ```bash vi cert-manager-values.yaml ``` 内容如下 ```yaml crds: enabled: true # 开启监控 prometheus: enabled: true servicemonitor: enabled: true ``` 3. 部署 ```bash helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ -f cert-manager-values.yaml ``` 4. 验证 **安装 GO 工具** - Centos ```bash yum -y install go ``` - Ubuntu ```bash apt -y install golang ``` **安装 Cmctl** ```bash 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 ``` **执行命令验证安装** ```bash cmctl check api ``` > 正常返回为:`The cert-manager API is ready` ## 卸载 1. 卸载 cert-manager ```bash helm uninstall cert-manager -n cert-manager ``` 2. 删除命名空间 ```bash kubectl delete ns cert-manager ``` 3. 删除资源 ```bash kubectl delete apiservice v1beta1.webhook.cert-manager.io ``` # 使用方法(HTTP01) > Cert-Manager 搭配 Let's Encrypt 实现证书自动签发 [官方文档](https://cert-manager.io/docs/tutorials/acme/nginx-ingress/#step-6---configure-a-lets-encrypt-issuer) [Let's Encrypt](https://letsencrypt.org/zh-cn/getting-started/) ## 介绍 在 `cert-manager` 中,`Issuer` 和 `ClusterIssuer` 是用来配置和管理证书颁发的 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 ```bash annotations: cert-manager.io/cluster-issuer: "letsencrypt-staging" ``` 2. 部署 Yaml ```bash 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 ```bash kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/production-issuer.yaml ``` ## 配置 ClusterIssuer 方法 1. ingress 资源配置 annotations ```yaml annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" ``` 2. 部署 Yaml ```bash kubectl create --edit -f https://gitee.com/offends/Kubernetes/raw/main/File/Yaml/cluster-issuer.yaml ``` 3. 检查 Certificate 资源是否创建 ```bash kubectl get Certificate -A ``` # 使用方法(NDS01) [外部DNS 提供商列表](https://cert-manager.io/docs/configuration/acme/dns01/#webhook) # 问题记录 > 2025-08-24日重新安装 Nginx-Ingress 和 Cert-Manager 时发现无法正常签发证书 ## 根本原因 - `cert-manager` 在使用 HTTP-01 验证时,会临时创建一个 `/.well-known/acme-challenge/` 的 Ingress。 - 集群中启用了 `ingress-nginx-admission`(ValidatingWebhookConfiguration),它默认拦截所有命名空间的 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`: ```bash 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/Order,让 `cert-manager` 重新申请证书。 - 问题解决后,`cert-manager` 可以正常申请并自动续签证书,同时其他命名空间的 Ingress 仍然有 Admission 验证保护。