使用 cert-manager 自动签发证书
1. 安装 cert-manager
shell
kubectl create namespace cattle-system
版本下载地址:https://github.com/cert-manager/cert-manager/releases/
shell
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/<VERSION>/cert-manager.crds.yaml
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace
shell
kubectl get crd -o wide
2. 创建 ClusterIssuer
cert-manager 会创建 ClusterIssuer 自定义资源,ClusterIssuer 会向 Let's Encrypt 机构申请证书和续约证书。
工作原理: 用户向 ClusterIssuer 提出申请证书请求 → ClusterIssuer 向 Let's Encrypt 机构申请证书 → Let's Encrypt 机构进行审核
审核方式:
- HTTP01 方式:Let's Encrypt 机构会访问你的域名验证站点所有权。内网环境无法使用此方式。
- DNS01 方式:通过 DNS 服务器 API token 验证域名控制权,推荐使用。
ClusterIssuer 是全局生效的资源,不受命名空间限制。
yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: pursue_c@163.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
3. 创建 Certificate
shell
kubectl apply -f certificate.yaml
yaml
# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: task-pursue-pub
namespace: outsourcing
spec:
dnsNames:
- "task.pursue.pub"
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod
secretName: task-letsencrypt-tls
注意事项: Let's Encrypt 一个星期内只为同一个域名颁发 5 次证书,todoit.tech
和 whoami.todoit.tech
被视为不同的域名。
4. 修改 Ingress 配置
yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: task-ingress
namespace: outsourcing
creationTimestamp: '2025-07-15T09:24:22Z'
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'false'
spec:
ingressClassName: kubesphere-router-cluster
tls:
- hosts:
- task.pursue.pub
secretName: task-letsencrypt-tls # 对应 certificate.yaml 的 secretName
rules:
- host: task.pursue.pub
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: task-service
port:
number: 8088
5. 自动创建证书(推荐方式)
如果上述配置正常,可以让 Ingress 自动创建 Certificate,只需增加注解 cert-manager.io/cluster-issuer: letsencrypt-prod
再配置tls即可
yaml
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: zfile
namespace: infra
creationTimestamp: '2025-07-28T08:54:50Z'
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubesphere.io/creator: chan
nginx.ingress.kubernetes.io/proxy-body-size: 100G
spec:
ingressClassName: kubesphere-router-cluster
tls:
- hosts:
- zfile.pursue.pub
secretName: cert-zfile-pursue-pub
rules:
- host: zfile.pursue.pub
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: zfile
port:
number: 8080