这个问题,很多使用使用kubeadm的用户都会遇到。

网上也有类似的帖子,从源代码编译这种思路,

在生产环境,有些不现实。

还是使用kubeadm的命令操作,比较自然一点。

当然,自行生成一套证书,也是在新安装集群里,可以考虑的方案。

===============================================

 

 

.问题起源

 

kubeadm 是 kubernetes 提供的一个初始化集群的工具,使用起来非常方便。但是它创建的apiserver、controller-manager等证书默认只有一年的有效期,同时kubelet 证书也只有一年有效期,一年之后 kubernetes 将停止服务。

官方推荐一年之内至少用 kubeadm upgrade 更新一次 kubernetes 系统,更新时也会自动更新证书。不过,在产线环境或者无法连接外网的环境频繁更新 kubernetes 不太现实。

我们可以在过期之前或之后,使用kubeadm alpha phase里的certs和kubeconfig命令,同时配合kubelet证书自动轮换机制来解决这个问题。

 

.认识认书

 

使用kubeadm创建完Kubernetes集群后, 默认会在/etc/kubernetes/pki目录下存放集群中需要用到的证书文件, 整体结构如下图所示:

 

Kubernetes 集群根证书

/etc/kubernetes/pki/ca.crt

/etc/kubernetes/pki/ca.key

由此根证书签发的证书有:

1,kube-apiserver 组件持有的服务端证书

/etc/kubernetes/pki/apiserver.crt

/etc/kubernetes/pki/apiserver.key

2,kubelet 组件持有的客户端证书

/etc/kubernetes/pki/apiserver-kubelet-client.crt

/etc/kubernetes/pki/apiserver-kubelet-client.key

kubelet 上一般不会明确指定服务端证书, 而是只指定 ca 根证书, 让 kubelet 根据本地主机信息自动生成服务端证书并保存到配置的cert-dir文件夹中。

汇聚层(aggregator)证书

/etc/kubernetes/pki/front-proxy-ca.crt

/etc/kubernetes/pki/front-proxy-ca.key

由此根证书签发的证书只有一组:

1,代理端使用的客户端证书, 用作代用户与 kube-apiserver 认证

/etc/kubernetes/pki/front-proxy-client.crt

/etc/kubernetes/pki/front-proxy-client.key

etcd 集群根证书

/etc/kubernetes/pki/etcd/ca.crt

/etc/kubernetes/pki/etcd/ca.key

由此根证书签发机构签发的证书有:

1,etcd server 持有的服务端证书

/etc/kubernetes/pki/etcd/server.crt

/etc/kubernetes/pki/etcd/server.key

2,peer 集群中节点互相通信使用的客户端证书

/etc/kubernetes/pki/etcd/peer.crt

/etc/kubernetes/pki/etcd/peer.key

3,pod 中定义 Liveness 探针使用的客户端证书

/etc/kubernetes/pki/etcd/healthcheck-client.crt

/etc/kubernetes/pki/etcd/healthcheck-client.key

4,配置在 kube-apiserver 中用来与 etcd server 做双向认证的客户端证书

/etc/kubernetes/pki/apiserver-etcd-client.crt

/etc/kubernetes/pki/apiserver-etcd-client.key

Serveice Account秘钥

这组的密钥对儿仅提供给 kube-controller-manager 使用. kube-controller-manager 通过 sa.key 对 token 进行签名, master 节点通过公钥 sa.pub 进行签名的验证.

API Server的authenticating环节支持多种身份校验方式:client cert、bearer token、static password auth等,这些方式中有一种方式通过authenticating(Kubernetes API Server会逐个方式尝试),那么身份校验就会通过。一旦API Server发现client发起的request使用的是service account token的方式,API Server就会自动采用signed bearer token方式进行身份校验。而request就会使用携带的service account token参与验证。该token是API Server在创建service account时用API server启动参数:–service-account-key-file的值签署(sign)生成的。如果–service-account-key-file未传入任何值,那么将默认使用–tls-private-key-file的值,即API Server的私钥(server.key)。

通过authenticating后,API Server将根据Pod username所在的group:system:serviceaccounts和system:serviceaccounts:(NAMESPACE)的权限对其进行authority 和admission control两个环节的处理。在这两个环节中,cluster管理员可以对service account的权限进行细化设置。

 

/etc/kubernetes/pki/sa.key

/etc/kubernetes/pki/sa.pub

kubeadm 创建的集群, kube-proxy ,flannel,coreDNS是以 pod 形式运行的, 在 pod 中, 直接使用 service account 与 kube-apiserver 进行认证, 此时就不需要再单独为 kube-proxy 创建证书

 

.Kubeadm本地读取集群配置

 

正如默认的kubeadm 安装k8s集群时,会从外网拉取镜像。在kubeadm命令升级master证书时,它也会默认从网上读取一个stable.txt的文件。由于公司实际情况,这个问题得解决掉。

解决这个问题的办法,就是生成一个集群配置的yaml文件,然后,在运行命令时指定这个Yaml文件即可。

如何生居一个集群配置的yaml文件呢?命令如下:

kubeadm config view > cluster.yaml

其内容如下:

 

.重新生成master证书

 

一旦证书过期,使用kubectl时会出现如下提示:

Unable to connect to the server: x509: certificate has expired or is not yet valid

在此,我们使用kubeadm alpha phase certs系统命令,重新生成证书。

 

建议不要重新生成ca证书,因为更新了ca证书,集群节点就需要手工操作,才能让集群正常(会涉及重新join)。

操作之前,先将/etc/kubernetes/pki下的证书文件,mv到其它文件夹,作个临时备份,不要删除。

kubeadm alpha phase certs etcd-healthcheck-client --config cluster.yaml

kubeadm alpha phase certs etcd-peer --config cluster.yaml

kubeadm alpha phase certs etcd-server --config cluster.yaml

kubeadm alpha phase certs front-proxy-client--config cluster.yaml

kubeadm alpha phase certs apiserver-etcd-client --config cluster.yaml

kubeadm alpha phase certs apiserver-kubelet-client --config cluster.yaml

kubeadm alpha phase certs apiserver --config cluster.yaml

kubeadm alpha phase certs sa --config cluster.yaml

 

.重新生成kubeconfig配置文件

 

在生成这些新的证书文件之后,再需要kubeadm alpha phase config命令,重新生成新的kubeconfig文件。

 

操作之前,先将/etc/kubernetes/下的kubeconfig,mv到其它文件夹,作个临时备份,不要删除。

kubeadm alpha phase kubeconfig all --config cluster.yaml

所有的kubeconfig重新生成以后,替换到kubectl使用的config文件之后(默认位置为~.kube/config),即可正常操作kubectl命令了。

 

.Kubelet证书自动轮换

 

kubelet证书分为server和client两种, k8s 1.10默认启用了client证书的自动轮换,但server证书自动轮换需要用户开启。

 

.Service Account密钥更新

 

由于service account的密钥是以rsa密钥对形式生成,所以没有过期时间。

如无必要,千万不要生成重新生成sa密钥。因为sa密钥关联到一切系统pod内的进程访问api server时的认证。

如果更新了sa,则需要先重新生成这些pod加截的token,再删除这些pod之后,重新加载token文件。

经过测试,这些系统级pod包括但不限于kube-proxy,flannel,kubenetes-dashboard, kube-stat-metricst等所有用到sa认证的pod。

 

 

转载于:https://www.cnblogs.com/aguncn/p/10488130.html

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐