kubernetes 集群安装配置过程中,会使用各种证书,目的是为了加强集群安全性,但是会坑很多入门新手. ??前期如果手动部署集群, 想了解集群组件配合工作原理,各种不通,报很多奇葩的错,很多是证书配置错误导致的。 ?推荐报错时多看master节点和调试服务节点的日志. ?基本都能发现有用的错误日志,k8s打印的错误日志,指引的错误方向还是靠谱的. 为了少踩坑,个人简单梳理了一下集群配置过程中使用的证书信息,详细如下:
集群使用证书
etcd: ???????????????????????????????使用 ca.pem、server-key.pem、server.pem;kube-apiserver: ????????使用 ca.pem、server-key.pem、server.pem;kubelet: ????????????????????????使用 ca.pem;kube-proxy: ????????????????使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem;kubectl: ????????????????????使用 ca.pem、admin-key.pem、admin.pem;kube-controller-manager:使用 ca-key.pem、ca.pem
注意:
证书生成操作都可以在master节点主机上执行,证书只需要创建一次即可。然后将证书copy到新添加节点, ?
根据不同服务使用的证书的不同单独配置即可。
其它几个类证书文件
token.csv
该文件为一个用户的描述文件,基本格式为 Token,用户名,UID,用户组;这个文件在 apiserver 启动时被 apiserver 加载, ?然后就相当于在集群内创建了一个这个用户;接下来就可以用 RBAC 给他授权
bootstrap.kubeconfig
该文件中内置了 token.csv 中用户的 Token,以及 apiserver CA 证书;kubelet 首次启动会加载此文件, ?使用 apiserver CA 证书建立与 apiserver 的 TLS 通讯,使用其中的用户 Token 作为身份标识像 apiserver 发起 CSR 请求
生成证书过程简介
安装cfssl
CFSSL是CloudFlare开源的一款PKI/TLS工具。CFSSL 包含一个命令行工具和一个用于 签名,验证并且捆绑TLS证书的 HTTP API 服务. ?
使用Go语言编写。
CFSSL包括:
一组用于生成自定义 TLS PKI 的工具;cfssl程序,是CFSSL的命令行工具;multirootca程序是可以使用多个签名密钥的证书颁发机构服务器;mkbundle程序用于构建证书池;cfssljson程序,从cfssl和multirootca程序获取JSON输出,并将证书,密钥,CSR和bundle写入磁盘;PKI借助数字证书和公钥加密技术提供可信任的网络身份。通常,证书就是一个包含如下身份信息的文件:证书所有组织的信息公钥证书颁发组织的信息证书颁发组织授予的权限,如证书有效期、适用的主机名、用途等使用证书颁发组织私钥创建的数字签名
下载
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
安装
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64mv cfssl_linux-amd64 /usr/local/bin/cfsslmv cfssljson_linux-amd64 /usr/local/bin/cfssljsonmv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
证书生成过程演示
制作server ca证书
cat << EOF | tee ca-config.json{ ?"signing": { ???"default": { ?????"expiry": "87600h" ???}, ???"profiles": { ?????"server": { ????????"expiry": "87600h", ????????"usages": [ ???????????"signing", ???????????"key encipherment", ???????????"server auth", ???????????"client auth" ???????] ?????} ???} ?}}EOF字段说明:expiry : 87600h ?10 年ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;server auth:表示client可以用该 CA 对server提供的证书进行验证;client auth:表示server可以用该CA对client提供的证书进行验证;
cat << EOF | tee ca-csr.json{ ???"CN": "server", ???"key": { ???????"algo": "rsa", ???????"size": 2048 ???}, ???"names": [ ???????{ ???????????"C": "CN", ???????????"L": "Beijing", ???????????"ST": "Beijing", ???????????"O": "k8s", ???????????"OU": "System" ???????} ???]}EOF字段说明:"CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;"O":Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
生成CA证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
验证ca 证书
k8s-ssl]# lsca-config.jsonca-csr.jsonca.csrca-key.pemca.pem
制作server证书
cat << EOF | tee server-csr.json{ ???"CN": "server", ???"hosts": [ ?????"10.254.0.1", ?????"127.0.0.1", ?????"172.20.101.157", ?????"172.20.101.165", ?????"172.20.101.164", ?????"172.20.101.160", ?????"172.20.101.166", ?????"172.20.101.167", ?????"server", ?????"server.default", ?????"server.default.svc", ?????"server.default.svc.cluster", ?????"server.default.svc.cluster.local" ???], ???"key": { ???????"algo": "rsa", ???????"size": 2048 ???}, ???"names": [ ???????{ ???????????"C": "CN", ???????????"L": "Beijing", ???????????"ST": "Beijing", ???????????"O": "k8s", ???????????"OU": "System" ???????} ???]}EOF字段说明:如果hosts字段不为空则需要指定授权使用该证书的IP或域名列表,该证书后续被 etcd 集群和 kubernetes master 集群使用,上面分别指定了 etcd 集群: ?????"172.20.101.157", ?????"172.20.101.165", ?????"172.20.101.164",kubernetes master 集群的主机 IP: ?????"172.20.101.157", ?????"172.20.101.165", ?????"172.20.101.164",kubernetes node 节点 IP: ?????"172.20.101.160", ?????"172.20.101.166", ?????"172.20.101.167",service-cluster-ip-range 网段和第一个IP, ?????"10.254.0.1",也可以写物理节点的主机名。另外集群配置高可用使用vip的IP地址也填上。
生成 kubernetes 证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server
验证
ll server*server.csrserver-csr.jsonserver-key.pemserver.pem
制作kube-proxy证书
cat << EOF | tee kube-proxy-csr.json{ ?"CN": "system:kube-proxy", ?"hosts": [], ?"key": { ???"algo": "rsa", ???"size": 2048 ?}, ?"names": [ ???{ ?????"C": "CN", ?????"L": "Beijing", ?????"ST": "Beijing", ?????"O": "k8s", ?????"OU": "System" ???} ?]}EOF字段说明:CN 指定该证书的Use为system:kube-proxy;kube-apiserver 预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
创建 kube-proxy 证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server kube-proxy-csr.json | cfssljson -bare kube-proxy
验证
kube-*kube-proxy.csrkube-proxy-csr.jsonkube-proxy-key.pemkube-proxy.pem
创建 admin 证书
cat >admin-csr.json<<EOF{ ???"CN": "admin", ???"key": { ???????"algo": "rsa", ???????"size": 2048 ???}, ???"names": [ ???????{ ???????????"C": "CN", ???????????"ST": "BeiJing", ???????????"L": "BeiJing", ???????????"O": "system:masters", ???????????"OU": "System" ???????} ???]}EOF字段说明:O 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过, ?同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;
生成 admin ca
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server admin-csr.json | cfssljson -bare admin
验证
ll admin*admin.csradmin-csr.jsonadmin-key.pemadmin.pem
清理 csr srl
find . -name "*.csr" -o -name "*.srl"|xargs ?rm -f
验证证书:
使用 opsnssl 命令验证key内容
openssl x509 ?-noout -text -in ?server.pemcfssl-certinfo -cert server.pem后面的pem可以换成已生成key文件,然后核对key内容。
集群核对key信息
集群搭建完成,通过命令: kubectl get clusterrolebinding cluster-admin -o yaml ,查看 clusterrolebinding cluster-admin 的 subjects 的 kind 是 Group,name 是 system:masters。 roleRef 对象是 ClusterRole cluster-admin。即:system:masters Group 的 user 或者 serviceAccount 都拥有 cluster-admin 的角色。 因此在使用 kubectl 命令时候, ?才拥有整个集群的管理权限。可以使用 kubectl get clusterrolebinding cluster-admin -o yaml 来查看。
参考文档:
https://blog.51cto.com/lookingdream/2176846
https://jimmysong.io/kubernetes-handbook/practice/create-tls-and-secret-key.html
kubernetes ssl证书梳理
原文地址:https://blog.51cto.com/michaelkang/2364633