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

225 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> 本文作者:丁辉
# 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/<token>` 的 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 验证保护。