Author:Arsen
Date:2024/07/04
一、现象描述
之前有篇文章《K8s Token 过期解决方案(Kubeadm)》提到了默认生成的 Token 有效期只有 24 小时,过期后 Token 将不可用,如果想新的 Node 节点加入 K8s 集群,则需重新生成新的 Token。
今天无意间打开我虚拟机部署的 K8s 集群(通过 kubeadm 方式部署),发现 CA 证书过期了(如下图):
kubectl get pods
于是查看我的 K8s 集群证书,显示证书都过期了(如下图):
# 查看证书过期时间 => k8s1.15+版本的查看方法
kubeadm certs check-expiration
字段说明:
字段 | 解释 |
---|---|
CERTIFICATE | 证书的名称 |
EXPIRES | 证书过期的时间点 |
RESIDUAL TIME | 当前时间距离证书过期的剩余时间 |
CERTIFICATE AUTHORITY | 证书的颁发机构 |
EXTERNALLY MANAGED | 证书是否由外部系统管理 |
证书字段详解:
CERTIFICATE | EXPIRES | RESIDUAL TIME | CERTIFICATE AUTHORITY | EXTERNALLY MANAGED | 备注 |
---|---|---|---|---|---|
admin.conf | Dec 12, 2023 03:36 UTC | ca | no | Kubeconfig 文件,包含集群访问的配置 | |
apiserver | Dec 12, 2023 03:36 UTC | ca | no | Kubernetes API 服务器的证书 | |
apiserver-etcd-client | Dec 12, 2023 03:36 UTC | etcd-ca | no | API 服务器与 ETCD 之间的客户端证书 | |
apiserver-kubelet-client | Dec 12, 2023 03:36 UTC | ca | no | API 服务器与 Kubelet 之间的客户端证书 | |
controller-manager.conf | Dec 12, 2023 03:36 UTC | ca | no | Kubernetes 控制器管理器的 Kubeconfig 文件 | |
etcd-healthcheck-client | Dec 12, 2023 03:36 UTC | etcd-ca | no | 用于 ETCD 健康检查的客户端证书 | |
etcd-peer | Dec 12, 2023 03:36 UTC | etcd-ca | no | ETCD 节点间的对等通信证书 | |
etcd-server | Dec 12, 2023 03:36 UTC | etcd-ca | no | ETCD 服务器的证书 | |
front-proxy-client | Dec 12, 2023 03:36 UTC | front-proxy-ca | no | 前端代理的客户端证书 | |
scheduler.conf | Dec 12, 2023 03:36 UTC | ca | no | Kubernetes 调度器的 Kubeconfig 文件 |
显然,上表中的这些证书在 2023 年 12 月 12 日 03:36 UTC
就已经过期,且剩余时间为<invalid>
,表示这些证书已过期(无效),需要重新生成。
证书颁发机构字段解释:
CERTIFICATE AUTHORITY | EXPIRES | RESIDUAL TIME | EXTERNALLY MANAGED | 备注 |
---|---|---|---|---|
ca | Dec 09, 2032 03:36 UTC | 8年 | no | Kubernetes 的主证书颁发机构 |
etcd-ca | Dec 09, 2032 03:36 UTC | 8年 | no | ETCD 的证书颁发机构 |
front-proxy-ca | Dec 09, 2032 03:36 UTC | 8年 | no | 前端代理的证书颁发机构 |
二、解决方案
1、对过期证书进行备份,并删除旧的证书
# 备份证书
cp -rp /etc/kubernetes /etc/kubernetes.bak
# 删除旧的证书(使用新版本的新命令生成证书时可以忽略这一步,即可以不用删除)
# rm -f /etc/kubernetes/pki/apiserver*
# rm -f /etc/kubernetes/pki/front-proxy-client.*
# rm -rf /etc/kubernetes/pki/etcd/healthcheck-client.*
# rm -rf /etc/kubernetes/pki/etcd/server.*
# rm -rf /etc/kubernetes/pki/etcd/peer.*
2、重新生成证书
# 新版本(1.15+) - - 使用该命令不用提前删除过期证书
kubeadm certs renew all
# 老版本
# kubeadm alpha certs renew all
3、备份旧的配置文件,并重新生成新的配置文件
mv /etc/kubernetes/*.conf /tmp/
# 新版本(1.15+)
kubeadm init phase kubeconfig all
# 老版本
# kubeadm alpha phase kubeconfig all
4、更新 kubectl 配置
# 备份配置文件
cp -rp ~/.kube/config ~/.kube/config.bak
# 更新配置文件
\cp /etc/kubernetes/admin.conf ~/.kube/config
# 修改权限
chown $(id -u):$(id -g) $HOME/.kube/config
5、证书过期时间确认
# 新版本(1.15+)查看方法
kubeadm certs check-expiration
# 单独查看(其他同理)
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep 'Not'
# 老版本查看方法
# kubeadm alpha certs check-expiration
CA 证书时间已经更新,
6、重启 kubelet
所有 work 节点执行,如果你的 master 节点也作为 work 节点使用,那 master 节点也需要执行重启 kubelet 的操作。
systemctl restart kubelet
systemctl status kubelet
7、查看集群节点状态
发现 work 节点不健康,这个时候我们需要重新将work 节点加入 k8s 集群:
1)先查看集群中是否有 Token
kubeadm token list
2)没有则重新生成 Token
# 生成默认 24 小时 Token(推荐)
kubeadm token create
# 生成永久有效 Token
# kubeadm token create --ttl 0
3)获取 CA 证书 Hash 值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
4)最后就是 work 节点加入 K8s 集群
以 work1 节点为例,work2 节点及其他 work 节点同理。
# 填入上图生成的 token、hash 值,并加入集群。
kubeadm join 192.168.56.160:6443 --token zlj5j5.3ezp1s8drj3jgept --discovery-token-ca-cert-hash sha256:3ed701329742f7549f73cb065a8677abe8b5b8a3e25bbca7bb26f317ffcf89d4
执行后报错:
报错原因:这些文件为旧文件(过期的文件),我们备份后清理即可
# 备份
cp -a /etc/kubernetes/kubelet.conf /tmp/kubelet.conf.back
cp -a /etc/kubernetes/pki/ca.crt /tmp/ca.crt.back
# 清理
rm -f /etc/kubernetes/kubelet.conf
rm -f /etc/kubernetes/pki/ca.crt
清理完成后,再次将 work 节点加入集群:
kubeadm join 192.168.56.160:6443 --token zlj5j5.3ezp1s8drj3jgept --discovery-token-ca-cert-hash sha256:3ed701329742f7549f73cb065a8677abe8b5b8a3e25bbca7bb26f317ffcf89d4
8、查看 k8s 集群节点健康状态
kubectl get nodes
9、最后再验证以下证书过期时间
kubeadm certs check-expiration
无误后,K8s 集群的 CA 证书更新完毕,此时打一个快照(因为我是虚拟机),方便后续实验所用。
三、集群验证
K8s 集群证书过期时间更新完毕后,且集群节点也是健康的状态,那接下来我们跑一个测试服务验证一下集群是否可用。
kubectl create deployment nginx --image=nginx # 创建单副本作为测试即可
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
浏览器访问验证:http://192.168.56.160:31122/
再看看 pod 所在 work 节点:调度也是没问题的。
至此,K8s 集群验证完毕!
—END