Kubernetes集群实践(十三)使用cfssl生成集群内部使用的证书

本文主要介绍如何在Kubernetes中使用cfssl生成集群内部使用的证书。

关键词:k8s,证书

准备工作

项目地址:https://github.com/cloudflare/cfssl/

下载项目:cfssl、cfssljson

生成证书

通过证书请求文件,CSR参数生成CA证书和私钥,此步骤仅需进行一次,后续可以直接使用此步骤生成的文件,签发证书。

生成csr默认模板

1
cfssl print-defaults csr > ca-csr.json

修改配置文件模板的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"CN": "kubernetes",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "HangZhou",
"O": "k8s",
"OU": "System"
}
]
}

参数说明:

  • CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法

    ​ names的O表示Organization ,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)

  • C:Country, 国家

  • L:Locality,地区,城市

  • O:Organization Name,组织名称,公司名称

  • OU:Organization Unit Name,组织单位名称,公司部门

  • ST: State,州,省

生成CA证书和私钥

1
cfssl gencert -initca ca-csr.json | cfssljson -bare ca 

通过ca-config.json配置证书生成策略

容器的相关证书类型:

1
2
3
client certificate 用于服务端认证客户端, 例如etcdctl/etcd-proxy/fleetctl/docker客户端
server certificate 服务端使用,客户端用此验证服务端身份,如dockerd/kube-apiserver
peer certificate 双向证书,用于集群中etcd成员间进行通信

生成签发证书的配置文件模板

1
cfssl print-defaults config > ca-config.json

修改配置文件,分别配置针对三种不同证书类型的配置文件,有效期为43800h为5年

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
{
"signing": {
"default": {
"expiry": "43800h"
},
"profiles": { # ca-config.jso: 可以定义多个profiles, 分别指定不同的过期时间, 使用场景等参数,下面
"server": { # 这个字段名称任意,把server字段改成 aaa, bbb, ccc都可以,但是网上没有一篇博客有说这个字段任意
"expiry": "43800h",
"usages": [
"signing", # signing : 表示该证书可用于签名其它证书,生成的ca.pem证书中,CA=TRUE
"key encipherment",
"server auth" # server auth : 表示client可以使用该CA对server提供的证书进行验证
]
},
"client": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"client auth" # client auth : 表示server 可以用该CA对client提供的证书进行验证
]
},
"peer": {
"expiry": "43800h",
"usages": [
"signing",
"key encipherment",
"server auth", # server auth : 表示client可以使用该CA对server提供的证书进行验证
"client auth" # client auth : 表示server 可以用该CA对client提供的证书进行验证
]
}
}
}
}

证书生成

CFSSL提供了两个命令:gencert和sign。gencert将自动处理整个证书生成过程。该过程需要两个文件,一个告诉CFSSL本地客户端CA的位置以及如何验证请求,即config文件,另一个为CSR配置信息,用于填充CSR 即csr文件。

1
cfssl print-defaults csr > kubernetes-csr.json
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
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"10.116.137.196",
"10.116.82.28",
"10.116.36.57",
"10.254.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo":"rsa",
"size":2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
  • 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了etcd 集群、kubernetes master 集群的主机 IP和 kubernetes 服务的服务 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如10.254.0.1。
  • hosts 中的内容可以为空,即使按照上面的配置,向集群中增加新节点后也不需要重新生成证书。 执行下面命令, 生成 kubernetes.csr, kubernetes-key.pem, kubernetes.pem 文件
1
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

注:命令中的-profile参数要和ca-config.json中的profiles字段需要签名的证书一致