Cert Manager 简介
随着 HTTPS 不断普及,越来越多的网站都在从 HTTP 升级到 HTTPS,使用 HTTPS 就需要向权威机构申请证书,需要付出一定的成本,如果需求数量多,也是一笔不小的开支。cert-manager 是 Kubernetes 上的全能证书管理工具,如果对安全级别和证书功能要求不高,可以利用 cert-manager 基于 ACME 协议与 Let’s Encrypt 来签发免费证书并自动续期,实现永久免费使用证书。
Cert-Manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt / HashiCorp / Vault 这些免费证书的签发。在 Kubernetes 中,可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。
1 架构原理
解释下几个关键的资源:
- Issuer/ClusterIssuer: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书。
- Certificate: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用。
备注: 通过 helm3 安装并配置 Cert-Manager。
认证系统
1 环境依赖
底座环境: K8s/K3s 环境 (K8s1.15+)
组件依赖: Helm3 & Git & treafik
2 安装 Cert-Manager
# 创建 CustomResourceDefinition 用户自定义资源
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml
# 创建命名空间
kubectl create namespace cluster-service
# 添加 Jetstack Helm 仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update
# helm 部署 Cert Manager
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.15.0
3 Issuer 或 Clusterissuer 配置
Issuer 与 ClusterIssuer 的区别是 ClusterIssuer 可跨命名空间使用,而 Issuer 需在每个命名空间下配置后才可使用。我在此使用 ClusterIssuer,其类型选择 Let‘s Encrypt
# 配置 staging 环境使用的 Let‘s Encrypt ClusterIssuer,并创建:
$cat cluster-issuer-letsencrypt-staging.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# 务必将此处替换为你自己的邮箱, 否则会配置失败。当证书快过期时 Let's Encrypt 会与你联系
email: user@example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# 将用来存储 Private Key 的 Secret 资源
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
$ kubectl create -f cluster-issuer-letsencrypt-staging.yaml
# 配置 production 环境使用的 Let‘s Encrypt ClusterIssuer,并创建:
$cat cluster-issuer-letsencrypt-prod.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: user@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
$ kubectl create -f cluster-issuer-letsencrypt-prod.yaml
4 资源核查
[root@iZbp1dnzy9ygt2oosvzzzcZ cert-manager]# kubectl get clusterissuer
NAME READY AGE
letsencrypt-prod True 31m
letsencrypt-staging True 27m
这里分别配置了测试环境与生产环境两个 ClusterIssuer, 原因是 Let’s Encrypt 的生产环境有着非常严格的接口调用限制,最好是在测试环境测试通过后,再切换为生产环境。
测试验证
假设已安装好 Nginx Ingress Controller 或者 Treafik 并已存在一个 Ingress 对象,现在为它开启 TLS 选项:
# quickstart-example.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kuard
annotations:
# 务必添加以下两个注解, 指定 ingress 类型及使用哪个 cluster-issuer
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer:"letsencrypt-staging"
# 如果你使用 issuer, 使用以下注解
# cert-manager.io/issuer: "letsencrypt-staging"
spec:
tls:
- hosts:
- example.example.com # TLS 域名
secretName: quickstart-example-tls # 用于存储证书的 Secret 对象名字
rules:
- host: example.example.com
http:
paths:
- path: /
backend:
serviceName: kuard
servicePort: 80
# 更新应用
kubectl create -f quickstart-example.yaml
# Cert-manager 会读取注解并创建证书,使用以下命令查看
kubectl get certificate -A
# 当 Ready 为 True 时代表证书安装成功若出现问题可使用 descirbe 命令查看具体出错原因:
kubectl describe certificate -A
环境证书切换
当一切就绪后,将 Ingress 对象中的 cluster-issuer 注解改为 Let’s Encrypt 生产环境
# quickstart-example.yaml
cert-manager.io/cluster-issuer: "letsencrypt-prod"
更新 Ingress 后访问你的网站,应该可以看到 HTTPS 证书配置
说明: 配置域名,然后进行服务访问;
拓展阅读
系统自签名证书的生效,需要多关注下证书的部署版本信息,千万不要随便跟着互联网的一些教程进行上手操作,可能会搞出来好多的乌龙呦!