cert-manager为域名签发免费证书

随着HTTPS不断普及,大多数网站开始由HTTP升级到HTTPS。使用HTTPS需要向权威机构申请证书,并且需要付出一定的成本,如果需求数量多,则开支也相对增加。cert-manager 是 Kubernetes 上的全能证书管理工具,支持利用 cert-manager 基于 ACME 协议与 Let’s Encrypt 签发免费证书并为证书自动续期,实现永久免费使用证书。

cert-manager支持许多dns provider,但不支持国内的dnspod,不过cert-manager提供了Webhook机制来扩展provider,社区也有dnspod的provider实现,下面我们在k8s中通过cert-manager和cert-manager-webhook-dnspod来为域名签发免费证书,

环境配置

  • k8s集群:这里我们用的腾讯云eks集群
  • 域名:腾讯云购买的域名,并用dnspod进行解析
  • dnspod-token:从https://console.dnspod.cn/account/token/apikey创建一个
  • nginx-ingress:需要在k8s中部署nginx-ingress,后续配置ingress验证证书

集群已经部署了nginx-ingress并且支持helm3部署应用到集群。

安装部署cert-manager

首先我们安装cert-manager到集群中,执行下面的命令部署既可

1
kubectl apply --validate=false -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/cert-manager.yaml

安装cert-manager-webhook-dnspod

cert-manager-webhook-dnspod通过helm安装,首先我们配置下dnspod-webhook的配置文件。

1
2
3
4
5
6
7
8
9
groupName: cert-manager.io

secrets:
apiID: xxxxx
apiToken: xxxxxx

clusterIssuer:
enabled: true
email: nwx_qdlg@163.com

这里groupname可以和我的保持一致,secret是之前从dnspod上创建获取,clusterIssuer设置为true,邮箱填写自己既可。下面我们helm安装下

1
2
# git clone --depth 1 https://github.com/qqshfox/cert-manager-webhook-dnspod.git
# helm upgrade --install -n cert-manager -f dnspod-webhook-values.yaml cert-manager-webhook-dnspod ./cert-manager-webhook-dnspod/deploy/cert-manager-webhook-dnspod

Certificate签发证书

创建一个Certificate来给我们的域名签发免费证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-manager-crt
namespace: default
spec:
secretName: cert-manager-crt-secret
issuerRef:
name: cert-manager-webhook-dnspod-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames:
- niewx.cn
- cert-manager.niewx.cn

这里cert-manager-webhook-dnspod-cluster-issuer是自动生成的,dnsname需要保证填写的域名是dnspod管理的,最终生成的证书会在cert-manager-crt-secret这个secret。

这里创建之后,等certificate的状态是true,则签发成功,如果为false,需要describe看下报错是什么原因。

1
2
3
[eks@VM-0-13-centos cert]$ kubectl get certificate
NAME READY SECRET AGE
cert-manager-crt True cert-manager-crt-secret 104m

创建ingress使用免费签发证书

这里已经预先部署了一个简单go的demo服务

1
2
3
[eks@VM-0-13-centos cert]$ kubectl get all | grep go
pod/go-test-6cb6889655-c2gkh 1/1 Running 0 156m
service/go-test ClusterIP 10.0.0.110 <none> 3000/TCP 221d

然后我们用ingress绑定域名cert-manager.niewx.cn到后端的go服务提供访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: go-ingress
namespace: default
spec:
rules:
- host: cert-manager.niewx.cn
http:
paths:
- backend:
serviceName: go-test
servicePort: 3000
path: /
tls:
- hosts:
- cert-manager.niewx.cn
secretName: cert-manager-crt-secret

ingress创建好之后,浏览器用https访问域名正常则说明证书签发成功

upload-image

创建ingress自动生成证书

如果想在创建ingress的时候自动生成证书挂载,可以在ingress的注解指定好cert-manager的ClusterIssuer,这样就会调ClusterIssuer自动生成certificates,从而生成tls证书挂载到ingress上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: cert-manager-webhook-dnspod-cluster-issuer
kubernetes.io/ingress.class: nginx
name: nginx
namespace: default
spec:
rules:
- host: nginx-test.eks.niewx.cn
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
tls:
- hosts:
- nginx-test.eks.niewx.cn
secretName: nginx-test.eks.niewx.cn

通过测试,ingress域名是可以通过https正常访问,说明自动创建tls证书成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[eks@VM-0-13-centos cert]$ kubectl get certificates | grep nginx-test.eks.niewx.cn
nginx-test.eks.niewx.cn True nginx-test.eks.niewx.cn 11m
[eks@VM-0-13-centos cert]$ kubectl get secret | grep nginx-test.eks.niewx.cn
nginx-test.eks.niewx.cn kubernetes.io/tls 2 10m
[eks@VM-0-13-centos cert]$ curl https://nginx-test.eks.niewx.cn
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

部署过程中遇到的问题

我这里是部署在腾讯云的tke集群上,在tke部署会遇到一个问题就是cert-manager一直报如下错,导致Certificate状态一直是false,对应的tls证书生成失败。

1
2021-12-10T12:43:05.808457627Z E1210 12:43:05.808145       1 controller.go:158] cert-manager/controller/CertificateKeyManager "msg"="re-queuing item due to error processing" "error"="Operation cannot be fulfilled on certificates.cert-manager.io \"nginx-test.tke.niewx.cn\": the object has been modified; please apply your changes to the latest version and try again" "key"="tke-test/nginx-test.tke.niewx.cn" 

这里报错是因为权威dns服务器不对导致,这里将pod的dns服务器改成用8.8.8.8和114.114.114.114即可,在yaml自定义下nameserver的配置。

1
2
3
4
5
dnsConfig:
nameservers:
- 8.8.8.8
- 114.114.114.114
dnsPolicy: None

cert-manager为域名签发免费证书
https://www.niewx.cn/2021/08/07/2021-08-07-cert-manager-issues-free-certificates-for-domain-names/
作者
VashonNie
发布于
2021年8月7日
许可协议