当前位置: 首页 > news >正文

cert-manager:Kubernetes 自动 TLS 证书管理

cert-manager:Kubernetes 自动 TLS 证书管理

在现代云原生应用中,HTTPS 已经是基本要求而非可选项。手动申请、续期、部署 TLS 证书不仅繁琐,更容易因为证书过期导致服务中断。cert-manager 是 Kubernetes 生态中事实标准的证书管理器,它通过与 Let’s Encrypt、Vault、Venafi 等 CA 对接,实现证书的全自动申请与续期,彻底解放运维人员的双手。本文将带你从零开始,在 K3s 集群上部署 cert-manager,配置 Let’s Encrypt 颁发机构,并为 Ingress 自动签发受信任的 HTTPS 证书。


服务器配置

本教程假设你已经有一个运行中的 K3s 集群。cert-manager 本身资源消耗较小,但需要为集群节点预留足够的资源。推荐配置如下:

组件规格
CPU2 核
内存4 GB
系统盘40 GB SSD
操作系统Ubuntu 22.04 LTS
网络公网 IP(HTTP01 challenge 必须)

如果你还没有合适的云服务器,可考虑雨云服务器 rainyun。注册填2026off领 5 折,2 核 4GB 机型完全满足 K3s 单节点集群的运行需求。

确认集群就绪:

kubectl get nodes# NAME STATUS ROLES AGE VERSION# k3s-master Ready control-plane,master 1d v1.29.0+k3s1

安装

添加 Helm 仓库

helm repoaddjetstack https://charts.jetstack.io helm repo update

安装 cert-manager

cert-manager 依赖多个 CRD(Custom Resource Definition),推荐使用--set installCRDs=true在安装时一并部署:

kubectl create namespace cert-manager helminstallcert-manager jetstack/cert-manager\--namespacecert-manager\--versionv1.14.0\--setinstallCRDs=true\--setglobal.leaderElection.namespace=cert-manager

验证安装

kubectl get pods-ncert-manager# NAME READY STATUS RESTARTS AGE# cert-manager-7d9f5b6b8-xk9pv 1/1 Running 0 2m# cert-manager-cainjector-6b9b4f9b8-lmn2p 1/1 Running 0 2m# cert-manager-webhook-5b97f97b4-qrs7t 1/1 Running 0 2m

三个 Pod 全部 Running 后即安装成功。


核心概念

cert-manager 通过以下几个 CRD 来管理证书生命周期:

ClusterIssuer / Issuer

Issuer是命名空间级别的证书颁发机构配置,ClusterIssuer是集群级别的,可跨命名空间使用。生产环境推荐使用 ClusterIssuer。

支持的颁发机构类型:

  • ACME(Let’s Encrypt):最常用,支持 HTTP01 和 DNS01 两种 challenge
  • CA:使用集群内部的 CA 证书签发
  • Vault:对接 HashiCorp Vault
  • Venafi:企业级证书管理

Certificate

Certificate资源描述了你想要的证书规格(域名、有效期、存储的 Secret 名称等),cert-manager 会根据此资源自动向颁发机构申请证书,并将结果存入指定的 Kubernetes Secret。

CertificateRequest

CertificateRequest是 cert-manager 内部创建的中间资源,代表一次具体的证书申请动作,通常不需要手动创建,由 Certificate 控制器自动管理。

Challenge / Order

ACME 协议中,cert-manager 会创建OrderChallenge资源来完成域名所有权验证。HTTP01 challenge 会在集群中临时创建一个 Pod 来响应 Let’s Encrypt 的验证请求;DNS01 challenge 则通过修改 DNS 记录来验证。


实战示例

1. 配置 ClusterIssuer(HTTP01 Challenge)

HTTP01 是最简单的验证方式,Let’s Encrypt 会向http://<your-domain>/.well-known/acme-challenge/<token>发起请求,要求集群能从公网访问。

# cluster-issuer-http01.yamlapiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-prodspec:acme:# Let's Encrypt 生产环境server:https://acme-v02.api.letsencrypt.org/directoryemail:your-email@example.comprivateKeySecretRef:name:letsencrypt-prod-account-keysolvers:-http01:ingress:class:traefik# K3s 默认使用 Traefik,nginx 集群改为 nginx
kubectl apply-fcluster-issuer-http01.yaml# 验证状态kubectl get clusterissuer letsencrypt-prod# NAME READY AGE# letsencrypt-prod True 30s

2. 配置 ClusterIssuer(DNS01 Challenge with Cloudflare)

DNS01 适合通配符证书或无法从公网访问的内网集群:

# cluster-issuer-dns01.yamlapiVersion:cert-manager.io/v1kind:ClusterIssuermetadata:name:letsencrypt-dns01spec:acme:server:https://acme-v02.api.letsencrypt.org/directoryemail:your-email@example.comprivateKeySecretRef:name:letsencrypt-dns01-account-keysolvers:-dns01:cloudflare:email:your-cloudflare-email@example.comapiTokenSecretRef:name:cloudflare-api-token-secretkey:api-token

首先创建 Cloudflare API Token Secret:

# 在 Cloudflare 控制台创建具有 Zone:DNS:Edit 权限的 API Tokenkubectl create secret generic cloudflare-api-token-secret\--namespacecert-manager\--from-literal=api-token=YOUR_CLOUDFLARE_API_TOKEN
kubectl apply-fcluster-issuer-dns01.yaml

3. 手动创建 Certificate 资源

# my-app-certificate.yamlapiVersion:cert-manager.io/v1kind:Certificatemetadata:name:my-app-tlsnamespace:defaultspec:secretName:my-app-tls-secret# cert-manager 将证书存入此 SecretissuerRef:name:letsencrypt-prodkind:ClusterIssuercommonName:app.example.comdnsNames:-app.example.com-www.app.example.comduration:2160h# 90 天renewBefore:360h# 提前 15 天续期
kubectl apply-fmy-app-certificate.yaml# 观察证书申请过程kubectl describe certificate my-app-tls-ndefault kubectl get certificaterequest-ndefault

4. 通过 Ingress 注解自动签发证书

这是最常用的方式,只需在 Ingress 上加一个注解,cert-manager 会自动创建 Certificate 资源:

# my-app-ingress.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:my-app-ingressnamespace:defaultannotations:cert-manager.io/cluster-issuer:letsencrypt-prod# 指定 ClusterIssuer# 如果使用命名空间级别的 Issuer:# cert-manager.io/issuer: letsencrypt-prodspec:ingressClassName:traefiktls:-hosts:-app.example.comsecretName:my-app-tls-secret# cert-manager 会自动填充此 Secretrules:-host:app.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:my-app-serviceport:number:80
kubectl apply-fmy-app-ingress.yaml

常用命令

查看证书状态

# 列出所有命名空间的证书kubectl get certificate-A# 查看某个证书详情(包含事件和状态)kubectl describe certificate my-app-tls-ndefault# 查看证书实际内容(过期时间等)kubectl get secret my-app-tls-secret-ndefault-ojsonpath='{.data.tls\.crt}'|base64-d|openssl x509-noout-dates

排查申请失败问题

# 查看 CertificateRequest 状态kubectl get certificaterequest-ndefault kubectl describe certificaterequest my-app-tls-xxxxx-ndefault# 查看 ACME Order 状态kubectl get order-ndefault kubectl describe order my-app-tls-xxxxx-ndefault# 查看 Challenge 状态kubectl get challenge-ndefault kubectl describe challenge my-app-tls-xxxxx-ndefault# 查看 cert-manager 控制器日志kubectl logs-ncert-manager deploy/cert-manager-f# 查看 webhook 日志kubectl logs-ncert-manager deploy/cert-manager-webhook-f

手动触发证书续期

# 方法1:删除 CertificateRequest,cert-manager 会自动重新申请kubectl delete certificaterequest my-app-tls-xxxxx-ndefault# 方法2:使用 cmctl 工具强制续期cmctl renew my-app-tls-ndefault

安装 cmctl(cert-manager CLI)

curl-L-ocmctl https://github.com/cert-manager/cmctl/releases/latest/download/cmctl_linux_amd64chmod+x cmctlsudomvcmctl /usr/local/bin/# 检查 cert-manager 健康状态cmctl check api cmctl status certificate my-app-tls-ndefault

常见故障排查

# Challenge 一直处于 pending 状态:检查 Ingress/DNS 是否可公网访问kubectl get challenge-ndefault-owide# 证书 READY=False:查看 conditions 字段kubectl get certificate my-app-tls-ndefault-oyaml|grep-A10conditions# 速率限制:Let's Encrypt 有每域名每周 5 次的证书申请限制,测试时使用 staging 环境# staging server: https://acme-staging-v02.api.letsencrypt.org/directory

cert-manager 将繁琐的 TLS 证书运维工作完全自动化,是 Kubernetes 生产集群不可或缺的组件。配合 Let’s Encrypt 的免费证书,你可以零成本实现全站 HTTPS,且无需担心证书过期问题。

http://www.cnnetsun.cn/news/2459604.html

相关文章:

  • 【Perplexity设计灵感查询实战指南】:20年架构师亲授3大反直觉设计哲学与5个落地场景
  • 从LCD屏幕到车载摄像头:聊聊LVDS接口在你身边那些‘看不见’的应用
  • NGSIM数据集:如何成为自动驾驶算法开发的‘黄金标准’测试集?
  • 从YOLOv5到Mask R-CNN:深入浅出聊聊FPN特征金字塔是如何成为CV模型‘标配’的
  • C语言printf保留小数输出,你真的以为它会四舍五入吗?一个测试让你看清真相
  • ARM ETM10硬件追踪系统设计与信号完整性优化
  • 32位寄存器全解析:逆向分析与系统底层开发的基石
  • 用C语言手把手实现二维FFT:从图像处理小白到能跑通代码(附完整源码)
  • 强化学习入门:用Python实现Q-Learning算法
  • 避坑指南:UCIe链路初始化时,MBINIT和MBTRAIN阶段的Lane Repair有何不同?
  • OBS多平台直播插件终极指南:3步实现一键同步推流
  • MoneyPrinterPlus:AI视频生成神器,3分钟批量创作10个爆款短视频
  • Spring Validation嵌套校验踩坑实录:用@Valid搞定订单里商品列表的深度验证
  • 无人机机械臂系统MPC控制与轨迹跟踪优化
  • UniApp安卓NFC读取身份证/门禁卡实战:从权限配置到数据解析的完整避坑指南
  • 借助Footprint Expert PRO 高效构建AD标准封装库
  • 别再只用K-Means了!用DBSCAN搞定非球形数据聚类(附Python代码实战)
  • uniapp监听PDA扫码,除了广播还能怎么玩?聊聊H5+扩展与原生插件的选择
  • 告别Curve4!用Curve+ 5.0.2搞定G7+校准,一次印刷搞定多纸种配置
  • 从BERT到Llama-3,Perplexity算法演进史(附12个开源模型实测对比数据)
  • 如何用MOOTDX轻松获取股票数据?3个核心功能帮你快速入门量化投资
  • 独立开发者如何借助Taotoken透明计费精细控制多个副业项目成本
  • 想把脚本变成命令行工具?用argparse+装饰器10分钟搞定
  • AI炒股教学:DeepSeek+大模型辅助股票分析与复盘完整指南(2026版)
  • 影刀RPA跨境电商实战:Python协同容器化调度与多节点边缘运维架构
  • 影刀RPA跨境电商实战:Python协同高并发任务调度与多账号容器化隔离架构
  • 别再只用.mean()了!Pandas rolling的5个高阶用法,让你的时间序列分析更专业
  • 制造业工厂排班智能化,未来有哪些核心技术突破点?实在Agent端到端智能调度方案
  • 3分钟上手Upscayl:免费AI图像放大工具的终极使用指南
  • 别再手动敲BibTeX了!用Zotero一键搞定IEEE参考文献格式(附期刊/会议/书籍模板)