手把手教你使用 cert-manager 签发免费证书
概述
随着 HTTPS 不断普及,越来越多的网站都在从 HTTP 升级到 HTTPS,使用 HTTPS 就需要向权威机构申请证书,需要付出一定的成本,如果需求数量多,也是一笔不小的开支。cert-manager 是 Kubernetes 上的全能证书管理工具,如果对安全级别和证书功能要求不高,可以利用 cert-manager 基于 ACME 协议与 Let's Encrypt 来签发免费证书并自动续期,实现永久免费使用证书。
cert-manager 工作原理
cert-manager 部署到 Kubernetes 集群后,它会 watch 它所支持的 CRD 资源,我们通过创建 CRD 资源来指示 cert-manager 为我们签发证书并自动续期:
解释下几个关键的资源:
- Issuer/ClusterIssuer: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书。
- Certificate: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用。
免费证书签发原理
Let’s Encrypt 利用 ACME 协议来校验域名是否真的属于你,校验成功后就可以自动颁发免费证书,证书有效期只有 90 天,在到期前需要再校验一次来实现续期,幸运的是 cert-manager 可以自动续期,这样就可以使用永久免费的证书了。如何校验这个域名是否属于你呢?主流的两种校验方式是 HTTP-01 和 DNS-01,详细校验原理可参考 Let's Encrypt 的运作方式,下面将简单描述下。
HTTP-01 校验原理
HTTP-01 的校验原理是给你域名指向的 HTTP 服务增加一个临时 location ,Let’s Encrypt 会发送 http 请求到 http:///.well-known/acme-challenge/
,YOUR_DOMAIN
就是被校验的域名,TOKEN
是 ACME 协议的客户端负责放置的文件,在这里 ACME 客户端就是 cert-manager,它通过修改或创建 Ingress 规则来增加这个临时校验路径并指向提供 TOKEN
的服务。Let’s Encrypt 会对比 TOKEN
是否符合预期,校验成功后就会颁发证书。此方法仅适用于给使用 Ingress 暴露流量的服务颁发证书,并且不支持泛域名证书。
DNS-01 校验原理
DNS-01 的校验原理是利用 DNS 提供商的 API Key 拿到你的 DNS 控制权限, 在 Let’s Encrypt 为 ACME 客户端提供令牌后,ACME 客户端 (cert-manager) 将创建从该令牌和您的帐户密钥派生的 TXT 记录,并将该记录放在 _acme-challenge.
。 然后 Let’s Encrypt 将向 DNS 系统查询该记录,如果找到匹配项,就可以颁发证书。此方法不需要你的服务使用 Ingress,并且支持泛域名证书。
校验方式对比
HTTP-01 的校验方式的优点是: 配置简单通用,不管使用哪个 DNS 提供商都可以使用相同的配置方法;缺点是:需要依赖 Ingress,如果你的服务不是用 Ingress 暴露流量的就不适用,而且不支持泛域名证书。
DNS-01 的校验方式的优点是没有 HTTP-01 校验方式缺点,不依赖 Ingress,也支持泛域名;缺点就是不同 DNS 提供商的配置方式不一样,而且 DNS 提供商有很多,cert-manager 的 Issuer 不可能每个都去支持,不过有一些可以通过部署实现了 cert-manager 的 Webhook 的服务来扩展 Issuer 进行支持,比如 DNSPod 和 阿里 DNS,详细 Webhook 列表请参考: https://cert-manager.io/docs/configuration/acme/dns01/#webhook
选择哪种方式呢?条件允许的话,建议是尽量用 DNS-01
的方式,限制更少,功能更全。
操作步骤
安装 cert-manager
通常直接使用 yaml 方式一键安装 cert-manager 到集群,参考官网文档 Installing with regular manifests。
cert-manager 官方使用的镜像在 quay.io
,国内拉取可能比较慢,也可以使用下面命令一键安装(使用同步到国内 CCR 的镜像):
kubectl apply --validate=false -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/cert-manager/cert-manager.yaml
! 以上命令安装方式要求集群版本不低于 1.16。
配置 DNS
登录你的 DNS 提供商后台,配置域名的 DNS A 记录,指向你需要证书的后端服务对外暴露的 IP 地址,以 cloudflare 为例:
HTTP-01 校验方式签发证书
如果使用 HTTP-01 的校验方式,需要用到 Ingress 来配合校验。cert-manager 会通过自动修改 Ingress 规则或自动新增 Ingress 来实现对外暴露校验所需的临时 HTTP 路径,这个就是在给 Issuer 配置 http01 校验,指定 Ingress 的 name
或 class
的区别 (见下面的示例)。
TKE 自带的 Ingress 是每个 Ingress 资源都会对应一个 CLB,如果你使用 TKE 自带的 Ingress 暴露服务,并且使用 HTTP-01 方式校验,那么只能使用自动修改 Ingress 的方式,不能自动新增 Ingress,因为自动新增出来的 Ingress 会自动创建其它 CLB,对外的 IP 地址就与我们后端服务的 Ingress 不一致,Let's Encrypt 校验时就无法从我们服务的 Ingress 找到校验所需的临时路径,从而导致校验失败,无法签发证书。如果使用自建 Ingress,比如 在 TKE 上部署 Nginx Ingress,同一个 Ingress class 的 Ingress 共享同一个 CLB,这样就可以使用自动新增 Ingress 的方式。
下面给出一些示例。
如果你的服务使用 TKE 自带的 Ingress 暴露服务,不太适合用 cert-manager 签发管理免费证书,因为证书是要上传到 证书管理 来引用的,不在 K8S 中管理。
假设是 在 TKE 上部署 Nginx Ingress,且后端服务的 Ingress 是 prod/web
,创建 Issuer 示例:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-http01
namespace: prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-http01-account-key
solvers:
- http01:
ingress:
name: web # 指定被自动修改的 Ingress 名称
使用上面的 Issuer 签发证书,cert-manager 会自动修改 prod/web
这个 Ingress 资源,以暴露校验所需的临时路径,这是自动修改 Ingress 的方式,你可以使用自动新增 Ingress 的 方式,示例:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-http01
namespace: prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-http01-account-key
solvers:
- http01:
ingress:
class: nginx # 指定自动创建的 Ingress 的 ingress class
使用上面的 Issuer 签发证书,cert-manager 会自动创建 Ingress 资源,以暴露校验所需的临时路径。
有了 Issuer,接下来就可以创建 Certificate 并引用 Issuer 进行签发了,示例:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-mydomain-com
namespace: prod
spec:
dnsNames:
- test.mydomain.com # 要签发证书的域名
issuerRef:
kind: Issuer
name: letsencrypt-http01 # 引用 Issuer,指示采用 http01 方式进行校验
secretName: test-mydomain-com-tls # 最终签发出来的证书会保存在这个 Secret 里面
DNS-01 校验方式签发证书
如果使用 DNS-01 的校验方式,就需要看你使用的哪个 DNS 提供商了,cert-manager 内置了一些 DNS 提供商的支持,详细列表和用法请参考 Supported DNS01 providers,不过 cert-manager 不可能去支持所有的 DNS 提供商,如果没有你所使用的 DNS 提供商怎么办呢?有两种方案:
方案一:设置 Custom Nameserver。在你的 DNS 提供商后台设置 custom nameserver,指向像 cloudflare 这种可以管理其它 DNS 提供商域名的 nameserver 地址,具体地址可登录 cloudflare 后台查看:
下面是 namecheap 设置 custom nameserver 的示例:
最后配置 Issuer 指定 DNS-01 验证时,加上 cloudflare 的一些信息即可(见下文示例)。
方案二:使用 Webhook。使用 cert-manager 的 Webhook 来扩展 cert-manager 的 DNS-01 验证所支持的 DNS 提供商,已经有许多第三方实现,包括国内常用的 DNSPod 与阿里 DNS,详细列表参考: Webhook。
下面以 cloudflare 为例来签发证书:
登录 cloudflare,点到
My Profile > API Tokens > Create Token
来创建 Token:复制 Token 并妥善保管:
将 Token 保存到 Secret 中:
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: cert-manager
type: Opaque
stringData:
api-token: <API Token> # 粘贴 Token 到这里,不需要 base64 加密。
! 如果是要创建 ClusterIssuer,Secret 需要创建在 cert-manager 所在命名空间中,如果是 Issuer,那就创建在 Issuer 所在命名空间中。
创建 ClusterIssuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns01
spec:
acme:
privateKeySecretRef:
name: letsencrypt-dns01
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
cloudflare:
email: my-cloudflare-acc@example.com # 替换成你的 cloudflare 邮箱账号,API Token 方式认证非必需,API Keys 认证是必需
apiTokenSecretRef:
key: api-token
name: cloudflare-api-token-secret # 引用保存 cloudflare 认证信息的 Secret
创建 Certificate:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-mydomain-com
namespace: default
spec:
dnsNames:
- test.mydomain.com # 要签发证书的域名
issuerRef:
kind: ClusterIssuer
name: letsencrypt-dns01 # 引用 ClusterIssuer,指示采用 dns01 方式进行校验
secretName: test-mydomain-com-tls # 最终签发出来的证书会保存在这个 Secret 里面
获取和使用证书
创建好 Certificate 后,等一小会儿,我们可以 kubectl 查看是否签发成功:
$ kubectl get certificate -n prod
NAME READY SECRET AGE
test-mydomain-com True test-mydomain-com-tls 1m
如果 READY
为 False
表示失败,可以通过 describe 查看 event 来排查失败原因:
$ kubectl describe certificate test-mydomain-com -n prod
如果为 True
表示签发成功,证书就保存在我们所指定的 Secret 中 (上面的例子是 default/test-mydomain-com-tls
),可以通过 kubectl 查看:
$ kubectl get secret test-mydomain-com-tls -n default
...
data:
tls.crt: <cert>
tls.key: <private key>
其中 tls.crt
就是证书,tls.key
是密钥。
你可以将它们挂载到你需要证书的应用中,或者使用自建的 Ingress,可以直接在 Ingress 中引用 secret,示例:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/Ingress.class: nginx
spec:
rules:
- host: test.mydomain.com
http:
paths:
- path: /web
backend:
serviceName: web
servicePort: 80
tls:
hosts:
- test.mydomain.com
secretName: test-mydomain-com-tls
小结
本文介绍了 cert-manager 的工作原理,安装方法以及签发免费证书的两种校验方式 (HTTP-01 与 DNS-01) 的原理、对比以及操作方法。
参考资料
- cert-manager 官网: https://cert-manager.io/
- Let's Encrypt 的运作方式: https://letsencrypt.org/zh-cn/how-it-works/
- Issuer API 文档: https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Issuer
- Certificate API 文档: https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Certificate
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
手把手教你使用 cert-manager 签发免费证书的更多相关文章
- 免费证书https://lamp.sh/ssl.html
https(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的 http 通道,简单讲是 http 的安全版.即 ht ...
- 手把手教你如何利用 HeroKu 免费获取一个 Scrapyd 集群
手把手教你如何利用 HeroKu 免费获取一个 Scrapyd 集群 本文原始地址:https://sitoi.cn/posts/48724.html 准备环境 一个 GitHub 的账号 一个 He ...
- 手把手教你制作微信小程序,开源、免费、快速搞定
最近做了个"罗孚传车"的小程序 一时兴起,做了一个小程序,将个人收集的同汽车相关的行业资讯和学习资料,分享到小程序中,既作为历史资料保存,又提供给更多的人学习和了解,还能装一下:) ...
- 自动签发https证书工具 cert manager
最近cert manager进行升级,不再支持0.11以下的版本了,所以进行升级.但是发现不能直接通过更改镜像版本来升级,在Apps里的版本也是旧版本,部署后发现不支持,于是自已动手,根据文档整理了一 ...
- 手把手教你搭建FastDFS集群(下)
手把手教你搭建FastDFS集群(下) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u0 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置
前言 有朋友问了我关于博客系统搭建相关的问题,由于是做开发相关的工作,我给他推荐的是使用github的gh-pages服务搭建个人博客. 推荐理由: 免费:github提供gh-pages服务是免费的 ...
- 手把手教你接口自动化测试 – SoapUI & Groovy
手把手教你接口自动化测试 – SoapUI & Groovy http://www.cnblogs.com/wade-xu/p/4236295.html 关键词:SoapUI接口测试,接口自动 ...
- iOS 非ARC基本内存管理系列 -手把手教你ARC——iOS/Mac开发ARC入门和使用(转)
手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objective-c 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流 ...
- [原创]手把手教你写网络爬虫(4):Scrapy入门
手把手教你写网络爬虫(4) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 上期我们理性的分析了为什么要学习Scrapy,理由只有一个,那就是免费,一分钱都不用花! 咦?怎么有人扔西红柿 ...
随机推荐
- 永久激活(idea,pycharm等推荐使用)
二.永久激活(推荐使用)激活码激活总是过期,永久激活后,一劳永逸,不需要每次都在网上搜索激活码了. 1.下载激活插件:jetbrains-agent.jar(关注公号[吾非同]回复pycharm获取) ...
- 刷题[网鼎杯 2020 朱雀组]phpweb
解题思路 打开是一个蛮有意思的背景,众生皆懒狗,是自己没错了.源代码看一看,啥都没有.抓个包 诶,一看到func和p两个参数,想到了call_user_func(). 尝试着把date改成system ...
- Java8——Stream流式操作的一点小总结
我发现,自从我学了Stream流式操作之后,工作中使用到的频率还是挺高的,因为stream配合着lambda表达式或者双冒号(::)使用真的是优雅到了极致!今天就简单分(搬)享(运)一下我对strea ...
- Git的使用--码云
Git的使用--码云 进入码云官网:https://gitee.com/ 注册or登录账号进入gitee页面(页面结构大同小异). 点击右上角加号--新建仓库,用于存放项目代码 创建项目需要注意的选项 ...
- 【django】本地开发media用户上传文件访问路径找不到
当我们在本地开发的时候,会碰到static可以访问,但是用户上传的文件设置在media下不可访问怎么办?settings配置: 接着在你的urls文件添加: from . import setting ...
- 温故知新————c++ 多态
参考: 1. https://blog.csdn.net/weixin_42678507/article/details/89414998 (直接说明原理) 2 .https://www.cnblo ...
- 《C++primerplus》第9章练习题
1.(未使用原书例题)练习多文件组织.在一个头文件中定义一种学生的结构体,存储姓名和年龄,声明三个函数分别用于询问有多少个学生,输入学生的信息和展示学生的信息.在另一个源文件中给出所有函数的定义.在主 ...
- MySQL 复制表(表结构、表结构和数据)
MySQL 中使用 命令行 复制表结构及数据的方法主要有以下几种: 1.只复制表结构 CREATE TABLE new_table SELECT * FROM old_table WHERE 1=2: ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- mPDF的简单使用
1. 基本使用 安装 1 在项目下composer文件中 添加 "mpdf/mpdf":"~7.1.9" 测试环境为Yii项目 其他框架composer安装大 ...