相信很多小伙伴对于 Cert Manager 不陌生,Cert Manager 是 Kubernetes 上的证书管理工具,基于 [ACME](https://tools.ietf.org/html/rfc8555) 协议与 [Let's Encrypt](https://letsencrypt.org/) 签发免费证书并为证书自动续期,实现免费使用证书。
本文将介绍如何使用 Cert Manager 实现自动签发证书并与 Rainbond 结合使用。
## Cert Manager 概述
### 工作机制概述
在将 Cert Manager 部署到 Kubernetes 集群后,可以通过创建支持的自定义资源 CRD 来实现证书的签发和自动续期功能。以下是 Cert Manager 的工作机制概览:

`Issuer` 是 Cert Manager 用于定义证书签发方式的资源类型。它支持以下多种证书颁发机构:
- Let's Encrypt:广泛使用的免费证书颁发机构,支持 ACME 协议。
- HashiCorp Vault:适用于企业级密钥管理和证书签发。
- Venafi:支持企业环境中更复杂的证书管理需求。
- 自签发证书:适合内部使用场景。
`Certificate` 是 Cert Manager 的核心资源之一,用于定义需要签发的域名证书及其相关配置。它包含以下关键信息:
- 域名信息:需要绑定证书的具体域名。
- 配置参数:指定签发证书所需的额外信息,例如有效期、密钥长度等。
- Issuer 的引用:关联到某个具体的 `Issuer` 或 `ClusterIssuer`。
`Secrets` 是 Kubernetes 的资源对象,签发完成的证书最终会存储在 `Secrets` 中,供其他组件引用。
### 证书签发概述
本文使用 Let’s Encrypt 作为证书颁发机构,Let’s Encrypt 利用 ACME 协议校验域名的归属,校验成功后可以自动颁发免费证书。免费证书有效期只有90天,默认情况下 Cert Manager 会在证书到期前30天自动续期,即实现使用免费证书。校验域名归属的两种方式分别是 `HTTP-01` 和 `DNS-01`。
**HTTP-01**:通过向域名的 HTTP 服务发送请求验证域名归属,适用于使用 Ingress 暴露流量的服务,但不支持泛域名证书。Cert Manager 会动态创建或修改 Ingress 规则,添加临时路径以响应 Let’s Encrypt 的验证请求。验证通过后颁发证书。
**DNS-01**:通过在 DNS 提供商处添加 TXT 记录验证域名归属,支持泛域名证书且无需 Ingress。Cert Manager 使用 DNS 提供商的 API 自动更新记录。Let’s Encrypt 查询 TXT 记录后完成验证并颁发证书。
### 校验方式对比
| 特性 | HTTP-01 | DNS-01 |
| ---------------- | --------------------------- | ------------------------------------ |
| 是否依赖 Ingress | 是 | 否 |
| 是否支持泛域名 | 否 | 是 |
| 配置难度 | 简单,适用于所有 DNS 提供商 | 配置复杂,依赖 DNS 提供商的 API 支持 |
| 典型适用场景 | 仅服务通过 Ingress 暴露流量 | 需要泛域名证书或无 Ingress 的服务 |
## 部署 Cert Manager 和 Rainbond
使用 Helm 安装 Cert Manager,更多请参考[Cert Manager 部署文档](https://cert-manager.io/docs/installation/)。
```bash
$ helm repo add jetstack https://charts.jetstack.io
$ helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.16.2 \
--set crds.enabled=true
```
执行以下命令,[快速安装 Rainbond](http://localhost:3000/docs/quick-start/quick-install)。
```bash
curl -o install.sh https://get.rainbond.com && bash ./install.sh
```
### 创建 Issuer
[Issuer](https://cert-manager.io/docs/configuration/acme/http01/) 是 Cert Manager 的核心资源,用于定义证书的签发方式和配置。以下是一个示例,使用 **HTTP-01** 校验方式结合 `Ingress` 签发证书。
```yaml
$ kubectl apply -f issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer # Issuer 的名称
namespace: default # 所在的命名空间
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory # Let's Encrypt 的生产环境 ACME 服务地址
privateKeySecretRef:
name: issuer-account-key # 保存 ACME 私钥的 Kubernetes Secret
solvers: # 域名校验方式
- http01:
ingress:
ingressClassName: apisix # 使用 APISIX 作为 Ingress 控制器
```
### 创建 Certificate
[Certificate](https://cert-manager.io/docs/usage/certificate/) 是 Cert Manager 的核心资源之一,用于指定需要签发的域名证书及其相关配置。以下是一个完整的配置示例,结合前面创建的 `Issuer`,为指定域名自动签发和续期证书。
以下 YAML 文件创建了一个 `Certificate` 资源,为域名 `test.rainbond.com` 签发证书:
```yaml
$ kubectl apply -f certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-rainbond-com # Certificate 资源的名称
namespace: default # 所在的命名空间
spec:
dnsNames:
- test.rainbond.com # 需要绑定证书的域名
issuerRef:
kind: Issuer # 引用的 Issuer 类型
name: issuer # 引用的 Issuer 名称
secretName: test-rainbond-com-tls # 存储签发的证书和私钥的 Secret 名称
```
### 获取和查看证书
创建 `Certificate` 后,可以通过以下步骤检查签发状态并获取证书内容:
1. 检查 Certificate 签发状态,使用 `kubectl get certificate` 命令查看 Certificate 的状态:
```bash
$ kubectl get certificate -n default
NAME READY SECRET AGE
test-rainbond-com True test-rainbond-com-tls 1m
```
- READY 为 `True`:表示证书签发成功。证书已保存在指定的 `Secret` 中。
- READY 为 `False`:表示签发失败。需要进一步排查原因。
2. 排查签发失败原因,如果 `READY` 状态为 `False`,可以使用以下命令查看详细事件日志:
```bash
kubectl describe certificate test-rainbond-com -n default
```
日志中会显示失败的原因,例如域名校验失败、配置错误或 Issuer 不可用。
3. 查看生成的 Secret,当 `READY` 状态为 `True` 时,证书和密钥将保存在指定的 Secret 中。可以通过以下命令查看:
```bash
$ kubectl get secret test-rainbond-com-tls -n default
NAME TYPE DATA AGE
test-rainbond-com-tls kubernetes.io/tls 2 1m
```
- `tls.crt`: 证书内容。
- `tls.key`: 证书对应的私钥。
4. 获取具体证书和密钥内容,使用以下命令查看或提取证书和私钥内容:
```
$ kubectl get secret test-rainbond-com-tls -n default -o yaml
apiVersion: v1
kind: Secret
metadata:
name: test-rainbond-com-tls
namespace: default
data:
tls.crt: <base64 encoded certificate>
tls.key: <base64 encoded private key>
```
可以使用 `base64` 解码证书内容:
```bash
echo "<base64 encoded certificate>" | base64 -d
```
## 在 Rainbond 中使用证书
Rainbond v6 版本采用 APISIX 作为默认的 Ingress 控制器,通过配置 `ApisixTls` 资源即可轻松绑定证书,APISIX 会根据网关中的域名自动匹配对应的证书。
```yaml
$ kubectl apply -f tls.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
name: test-rainbond-com # 资源名称
namespace: default # 所在命名空间
spec:
hosts:
- test.rainbond.com # 绑定的域名
ingressClassName: apisix # 指定 Ingress 类名
secret:
name: test-rainbond-com-tls # 引用存储证书的 Secret 名称
namespace: default # 引用的 Secret 所在命名空间
```
### 添加路由
在 Rainbond 页面上添加网关路由。进入网关管理 > 路由设置,创建一个新的路由,填写域名(如 `test.rainbond.com`)并完成路由配置。
Rainbond 会自动检测网关路由的域名是否与 `ApisixTls` 中的 `hosts` 匹配。如果匹配成功,将自动为该域名启用 HTTPS,并绑定对应的证书。
## 最后
通过本文的介绍,我们详细了解了如何使用 Cert Manager 在 Kubernetes 中实现证书的自动签发与续期,并将其与 Rainbond 集成。Cert Manager 的灵活性与 Rainbond 的易用性结合,可以大大简化 HTTPS 的部署流程,为服务提供安全性保障。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70008902/viewspace-3062790/ ,如需转载,请注明出处,否则将追究法律责任。