影响
- 既有服务仍会正常运行;
无法在集群上进行CRUD操作(x509: certificate has expired or is not yet valid);
问题起源
集群使用kubeadm(1.9.4)安装,其创建的apiserver、controller-manager、kubelet等证书默认只有一年的有效期。官方推荐一年之内至少用kubeadm upgrade更新一次kubernetes系统,更新时也会自动更新证书。不过,在生产环境或者无法连接外网的环境频繁更新kubernetes不太现实。
- 使用kubeadm alpha phase里的certs和kubeconfig命令。PS: k8s 1.9默认启用了kubelet client证书的自动轮换。
认识证书

| 证书 | 说明 | 是否更新 |
|---|---|---|
| front-proxy-client.key/front-proxy-client.crt | 代理端使用的客户端证书, 用作代用户与kube-apiserver认证 | 是 |
| apiserver.key/apiserver.crt | kube-apiserver组件持有的服务端证书 | 是 |
| apiserver-kubelet-client.key/apiserver-kubelet-client.crt | kubelet 组件持有的客户端证书 | 是 |
| sa.key/sa.pub | kube-proxy/kube-dns/flannel等pod直接使用service account与kube-apiserver进行认证。 | service account的密钥是以rsa密钥对形式生成,所以没有过期时间。 如无必要,千万不要生成重新生成sa密钥。因为sa密钥关联到一切系统pod内的进程访问api server时的认证。 如果更新了sa,则需要先重新生成这些pod加截的token,再删除这些pod之后,重新加载token文件。 |
| ca.crt/ca.key | 集群根证书 | 建议不要重新生成ca证书,因为更新了ca证书,集群节点就需要手工操作,才能让集群正常(会涉及重新join) |
| front-proxy-ca.key/front-proxy-ca.crt | 汇聚层(aggregator)根证书 | 不更新 |
Prometheus告警
默认告警规则中已存在类似告警,运维同学应重视。
查看证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep ' Not 'find /etc/kubernetes/pki/ -type f -name "*.crt" -print|egrep -v 'ca.crt$'|xargs -L 1 -t -i bash -c 'openssl x509 -noout -text -in {}|grep After'
更新证书
NOTE:在多个master均需执行;将advertiseAddress和nodeName替换为相应的值;
1. 获取集群配置
sudo kubeadm config view > cluster.yaml
2. 备份证书和配置
cd /etc/kubernetessudo mkdir ./pki_baksudo mkdir ./conf_baksudo mv pki/apiserver.crt ./pki_bak/sudo mv pki/apiserver.key ./pki_bak/sudo mv pki/front-proxy-client.* ./pki_bak/sudo mv pki/apiserver-kubelet-client.* ./pki_bak/sudo mv ./admin.conf ./conf_bak/sudo mv ./kubelet.conf ./conf_bak/sudo mv ./controller-manager.conf ./conf_bak/sudo mv ./scheduler.conf ./conf_bak/
3. 制作新证书
使用如下命令时,由于网络环境会报错
sudo kubeadm alpha phase certs apiserver --apiserver-advertise-address ${MASTER_API_SERVER_IP}unable to get URL "https://dl.k8s.io/release/stable-1.9.txt": connection timed out
故使用集群当前配置制作证书
sudo kubeadm alpha phase certs apiserver --config cluster.yamlsudo kubeadm alpha phase certs apiserver-kubelet-client --config cluster.yamlsudo kubeadm alpha phase certs front-proxy-client --config cluster.yaml
4. 制作新配置文件
sudo kubeadm alpha phase kubeconfig all --config cluster.yaml
5. 确认kubectl正在查找正确的配置文件路径
sudo mv $HOME/.kube/config $HOME/.kube/config.oldsudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configsudo chmod 777 $HOME/.kube/config
6. 重启容器
docker restart kube-apiserver/kube-controller/kube-scheduler
