【Kubernetes硬核部署方式kubernetes-the-hard-way】02-生成证书
二、生成证书
0. 安装cfssl
cfssl是CA工具,用来生成证书和秘钥文件
# 返回node-1节点,保持与教程的同步
$ cd
[root@node-1 kubernetes-v1.21.0]# cd
[root@node-1 ~]#
# 下载
$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
# 修改为可执行权限
$ chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
# 验证
$ cfssl version
1. 根证书
根证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。
根证书配置文件
#创建一个单独的证书目录
$ mkdir pki && cd pki
$ cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "876000h"
}
}
}
}
EOF
$ cat > ca-csr.json <<EOF
{
"CN": "Kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "CA",
"ST": "Oregon"
}
]
}
EOF
生成证书和私钥
# 生成证书和私钥
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# 生成完成后会有以下文件(我们最终想要的就是ca-key.pem和ca.pem,一个秘钥,一个证书)
$ ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
2. admin客户端证书
admin客户端证书配置文件
$ cat > admin-csr.json <<EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "seven"
}
]
}
EOF
生成admin客户端证书和私钥
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
admin-csr.json | cfssljson -bare admin
3. kubelet客户端证书
Kubernetes使用一种称为Node Authorizer的专用授权模式来授权Kubelets发出的API请求。 Kubelet使用将其标识为system:nodes组中的凭据,其用户名为system:node:nodeName,接下里就给每个工作节点生成证书。
生成kubelet客户端证书和私钥
# 设置你的worker节点列表
$ WORKERS=(node-2 node-3)
$ WORKER_IPS=(192.168.31.71 192.168.31.72)
# 生成所有worker节点的证书配置
$ for ((i=0;i<${#WORKERS[@]};i++)); do
cat > ${WORKERS[$i]}-csr.json <<EOF
{
"CN": "system:node:${WORKERS[$i]}",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"O": "system:nodes",
"OU": "seven",
"ST": "Beijing"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=${WORKERS[$i]},${WORKER_IPS[$i]} \
-profile=kubernetes \
${WORKERS[$i]}-csr.json | cfssljson -bare ${WORKERS[$i]}
done
4. kube-controller-manager客户端证书
kube-controller-manager客户端证书配置文件
$ cat > kube-controller-manager-csr.json <<EOF
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:kube-controller-manager",
"OU": "seven"
}
]
}
EOF
生成kube-controller-manager客户端证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
5. kube-proxy客户端证书
kube-proxy客户端证书配置文件
$ cat > kube-proxy-csr.json <<EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "seven"
}
]
}
EOF
生成kube-proxy客户端证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare kube-proxy
6. kube-scheduler客户端证书
kube-scheduler客户端证书配置文件
$ cat > kube-scheduler-csr.json <<EOF
{
"CN": "system:kube-scheduler",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:kube-scheduler",
"OU": "seven"
}
]
}
EOF
生成kube-scheduler客户端证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-scheduler-csr.json | cfssljson -bare kube-scheduler
7. kube-apiserver服务端证书
kube-apiserver服务端证书配置文件
$ cat > kubernetes-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "seven"
}
]
}
EOF
生成kube-apiserver服务端证书
服务端证书与客户端略有不同,客户端需要通过一个名字或者一个ip去访问服务端,所以证书必须要包含客户端所访问的名字或ip,用以客户端验证。
注意:由于下面分发的证书即包含了etcd的证书也包含了k8s主节点的证书。
***所以 MASTER_IPS 中必须包含所有master
节点以及etcd
节点。***如果没有包含所有etcd节点的证书,需要重新定义,逗号分隔
# apiserver的service ip地址(一般是svc网段的第一个ip)
$ KUBERNETES_SVC_IP=10.233.0.1
# 所有的master内网ip,逗号分隔(云环境可以加上master公网ip以便支持公网ip访问)
# 接下来证书即包含了etcd的证书也包含了k8s主节点的证书MASTER_IPS 中必须包含所有 `master` 节点以及 `etcd` 节点
$ MASTER_IPS=192.168.31.70,192.168.31.71,192.168.31.72
# 生成证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=${KUBERNETES_SVC_IP},${MASTER_IPS},127.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local \
-profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes
8. Service Account证书
配置文件
$ cat > service-account-csr.json <<EOF
{
"CN": "service-accounts",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "seven"
}
]
}
EOF
生成证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
service-account-csr.json | cfssljson -bare service-account
9. proxy-client 证书
配置文件
$ cat > proxy-client-csr.json <<EOF
{
"CN": "aggregator",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "seven"
}
]
}
EOF
生成证书
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
proxy-client-csr.json | cfssljson -bare proxy-client
10. 分发客户端、服务端证书
分发worker节点需要的证书和私钥
for instance in ${WORKERS[@]}; do
scp ca.pem ${instance}-key.pem ${instance}.pem root@${instance}:~/
done
分发worker节点需要的证书和私钥过程中常出现的问题
解决方案:
#编辑本地host文件
vim /etc/hosts
#添加对应节点ip与结点名称关系
例:
192.168.31.70 node-1
192.168.31.71 node-2
192.168.31.72 node-3
分发master节点需要的证书和私钥
注意:由于下面分发的证书即包含了etcd的证书也包含了k8s主节点的证书。
***所以 MASTER_IPS 中必须包含所有master
节点以及etcd
节点。***如果没有包含所有etcd节点的证书,需要重新定义,逗号分隔
OIFS=$IFS
IFS=','
for instance in ${MASTER_IPS}; do
scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
service-account-key.pem service-account.pem proxy-client.pem proxy-client-key.pem root@${instance}:~/
done
IFS=$OIFS