cert-manager自动签发Lets Encrypt
# 前言
因为不想花钱,还有懒...,参考 (opens new window)
# 一、cert-manager介绍
# 1.1 关于cert-manager
1、创建ClusterIssuer或者Issuer资源用于创建颁发者,决定cert-manager签发证书的方式,然后会在cert-manager上的namespace下生成该颁发者的secret用于证书申请的准备。
2、通过创建Certificate资源来告知cert-manager :在哪个namespace生成证书、需要签发的域名的证书名称,域名对应的secret资源,以及的引用ClusterIssuer或者Issuer资源等等信息。
3、cert-manager拿着创建好的Certificate资源与ClusterIssuer或者Issuer资源的secret通过内部或外部的webhook向所支持的域名服务提供商对域名进行解析,这里会发起certificaterequests与challenges动作。
4、解析通过acme校验后将证书返回至cert-manager,certificatere对应项会变成True验证通过状态,再将证书转换到对应namespace下的secret资源做证书引用准备。
5、在Ingress-controller上生成ingress资源引用该证书secret即可实现https可信访问。
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 1.2 自动化HTTPS
Let's Encrypt 使用 ACME 协议来校验域名是否真的属于你,校验成功后就可以自动颁发免费证书,证书有效期只有 90 天,在到期前需要再校验一次来实现续期,而 cert-manager 是可以自动续期的,所以事实上并不用担心证书过期的问题。目前主要有 HTTP 和 DNS 两种校验方式
1
# 1.3 部署cert-manager (opens new window)
[root@k8s-uat-manager ~]# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml
1
# 1.4 导入阿里云的AKSK(管理DNS的权限)
[root@k8s-uat-manager cert-manager]# cat alidns-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: alidns-secret
namespace: cert-manager
stringData:
access-key-id: "LTAI5tFTExxxx" #申请一个ak账号管理DNS的权限
access-key-secret: "uQsS6KDnCxxx"
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 1.5 部署alidns-webhook (opens new window)
[root@k8s-uat-manager cert-manager]# helm upgrade --install alidns-webhook alidns-webhook \
--repo https://wjiec.github.io/alidns-webhook \
--namespace cert-manager --create-namespace \
--set groupName=acme.yourcompany.com \
--set image.repository=registry.cn-shenzhen.aliyuncs.com/starsl/alidns-webhook \
--set image.tag=v1.0.0
---------------------------------------------------------------------------------------------------------
[root@k8s-uat-manager cert-manager]# kubectl get pod -n cert-manager
NAME READY STATUS RESTARTS AGE
alidns-webhook-86744f579f-b6m8k 1/1 Running 0 3h8m
cert-manager-cainjector-6cb95dcccd-dx748 1/1 Running 0 3h12m
cert-manager-fd78d9458-qz9bk 1/1 Running 0 3h12m
cert-manager-webhook-5547d559c6-5fpfg 1/1 Running 0 3h12m
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 1.6 创建证书颁发机构
[root@k8s-uat-manager cert-manager]# cat ClusterIssuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: example-acme
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: xxx@xxxx.com # 填写邮箱名称
privateKeySecretRef:
name: example-acme # 用于存储 ACME 帐户私钥的密钥名称(可自定义名称)
solvers:
- dns01:
webhook:
groupName: acme.yourcompany.com # 要和安装时的groupName一致
solverName: alidns
config:
region: "cn-hangzhou" # 不用修改
accessKeyIdRef:
name: alidns-secret
key: access-key-id
accessKeySecretRef:
name: alidns-secret
key: access-key-secret
---------------------------------------------------------------------------------------------------------
注意:
1、email处可以填写为自己的企业邮箱,主要用于证书过期时候的提醒
2、这里我声明的是ClusterIssuer,这样意味着这个机构对kubernetes的全局命名空间都生效;
此外privateKeySecretRef一定要与name值相同,这样确保后续生成的secret资源绑定。
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
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
# 1.7 创建证书
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: star-example-com
namespace: cert-manager # 这个指定证书存在哪个namespace,比如我生产要用 可以改成prod
spec:
secretName: star-example-com-tls #生成证书文件的名称
dnsNames: # 需要签发证书的域名
- "jiang.xxxx.com"
issuerRef:
name: example-acme # 上一步生成的ClusterIssuer的名称
kind: ClusterIssuer
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 1.8 查看alidns-webhook的日志
[root@k8s-uat-manager cert-manager]# kubectl logs -f -n cert-manager alidns-webhook-86744f579f-b6m8k
1
# 1.9 观察certificate资源是否成功
[root@k8s-uat-manager cert-manager]# kubectl get certificate -n cert-manager
1
# 1.10 验证,注: 域名需要在dns解析
[root@k8s-uat-manager cert-manager]# cat demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: cert-manager
spec:
replicas: 1
selector:
matchLabels:
app: demo
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: demo
spec:
containers:
- image: nginx
name: demo
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo
namespace: cert-manager
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: demo
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: cert-manager
annotations:
cert-manager.io/cluster-issuer: "example-acme" # 引用clusterissuer
spec:
# 配置tls证书
tls:
- hosts:
- jiang.xxxx.com
# 写入创建Certificate定义的“secretName”
secretName: star-example-com-tls
ingressClassName: nginx
rules:
- host: jiang.xxx.com
http:
paths:
- backend:
service:
name: demo
port:
number: 80
path: /
pathType: Prefix
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 二、基于http的验证
# 2.1 创建证书颁发机构
[root@k8s-uat-manager http]# cat clusterIssuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
#server: https://acme-staging-v02.api.letsencrypt.org/directory #https测试证书生成,https会跳出警告
server: https://acme-v02.api.letsencrypt.org/directory
email: xxxx@foxmail.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- selector: {}
http01:
ingress:
ingressClassName: nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2.2 查看 clusterIssuer
[root@k8s-uat-manager http]# kubectl get clusterissuers.cert-manager.io
NAME READY AGE
letsencrypt-staging True 5m53s
1
2
3
2
3
2.3 验证
[root@k8s-uat-manager cert-manager]# cat demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: cert-manager
spec:
replicas: 1
selector:
matchLabels:
app: demo
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: demo
spec:
containers:
- image: nginx
name: demo
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: demo
namespace: cert-manager
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: demo
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: cert-manager
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-stagin" # 引用clusterissuer
spec:
# 配置tls证书
tls:
- hosts:
- jiang.xxxx.com
# 写入创建Certificate定义的"secretName"
secretName: jiang-tls
ingressClassName: nginx
rules:
- host: jiang.xxx.com
http:
paths:
- backend:
service:
name: demo
port:
number: 80
path: /
pathType: Prefix
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 2.4 查看tls
[root@k8s-uat-manager http]# kubectl apply -f demo.yaml
deployment.apps/test-end created
service/test-end created
ingress.networking.k8s.io/test-end created
[root@k8s-uat-manager http]# kubectl get secrets -n pre
NAME TYPE DATA AGE
default-token-vdzld kubernetes.io/service-account-token 3 709d
jiang-tls kubernetes.io/tls 2 8s
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
注意: https://acme-staging-v02.api.letsencrypt.org/directory url生成证书用于测试环境,浏览器访问会有安全警告(可以https方式)
编辑 (opens new window)
上次更新: 2024/09/05, 15:02:00