文档中心>容器服务>动态与公告>公告>apiserver loopback 证书过期问题解决方案

apiserver loopback 证书过期问题解决方案

最近更新时间:2025-03-21 10:13:22

我的收藏

背景

apiserver 启动时会签发 loopback 证书,用于访问自身的 API。社区版本的证书有效期为1年,而 TKE 在新版本中支持了5年有效期。当证书过期时,apiserver 请求自身时会失效,但不会立即触发问题,需要满足特定条件。一旦触发,会影响正常的客户端请求,如负载创建、滚动更新等。触发该问题时,业务请求会显示 certificate expired 错误。

Kubernetes 社区将证书有效期设置为1年的主要原因是社区一个版本支持周期为9个月,详情请参见社区 描述

问题触发条件

影响正常的客户请求有3个条件:
1. 证书过期,此时 apiserver 对自身发起的请求会失败。
2. 客户端的请求会引发 apiserver 查询其他资源,此时可能对自身发起请求,如 pod 资源创建时需要检查是否满足 resource quota。
2.1 每次 pod 创建时需要检查 resource quota,此时会先从缓存中获取,如果没有的话,会重新发起 list 请求,apiserver 需要访问自身,此时会因为证书过期失败,导致 pod 创建请求失败。
2.2 同理,针对 limit range 资源,每次 pod 创建进行 admit 时也会检查,当 informer,或者缓存中没有时也会触发直接 list apiserver 自身。
3. apiserver 对自身请求资源的长连接中断,如 informer,此时 apiserver 无法从缓存获取新数据,会重新发起请求。

业务影响

请求所有有其他依赖的资源时都会失败,典型的如 pod 资源依赖 resource quota,问题触发时会导致集群负载无法创建、滚动更新、扩容,暂时不影响存量 pod,但是控制面会处于不可用状态。如果业务依赖控制面,则会直接影响业务。

解决方案

方案一:升级集群版本(推荐)

适用集群类型:TKE 标准集群、TKE 标准集群(Master 自维护)
操作方式:升级集群 Master 至目标小版本或执行大版本升级,升级后证书变为5年有效期,集群一般会在5年时间升级或重启 apiserver,风险大大降低。
证书有效期与版本参照下表:
版本
判断标准
1.28及以上
所有小版本都是5年
v1.26.1-tke.x
从 tke.2 起是5年,之前是1年
v1.24.4-tke.x
从 tke.10 起是5年,之前是1年
v1.22.5-tke.x
从 tke.20 起是5年,之前是1年
v1.20.6-tke.x
从 tke.39 起是5年,之前是1年
v1.18.4-tke.x
从 tke.49 起是5年,之前是1年
v1.16.3-tke.x
从 tke.42 起是5年,之前是1年
v1.14.3-tke.x
从 tke.33 起是5年,之前是1年

方案二:控制面重启

注意:
建议业务低峰期进行操作,操作前观察 master 负载,高负载时请勿操作!
适用集群类型:TKE 标准集群(Master 自维护)
操作方式:检测 apiserver 版本,确认是1年过期还是5年过期,当 apiserver 进程启动时间接近过期时间时,需要重启 apiserver 进程。建议每个控制面节点间隔5分钟进行 apiserver 重启,请勿同步重启。
重启方法(下面方法二选一)
1. 根据运行时 docker/containerd 重启容器。
运行时为 docker
运行时为 containerd
# 1. 执行重启
docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs -I {} docker restart {}

# 2. 检查容器是否恢复,运行时间是刚启动
docker ps | grep apiserver
# 1. 执行重启
crictl ps | grep kube-apiserver | awk '{print $1}' | xargs -I {} crictl rm -f {}

# 2. 检查容器是否恢复,运行时间是刚启动
crictl ps | grep kube-apiserver
2. apiserver 的静态 pod 文件 /etc/kubernetes/manifests/kube-apiserver.yaml 从目录中移出然后移入,完成后需要检查 pod 是否重启。
mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/
mv /etc/kube-apiserver.yaml /etc/kubernetes/manifests/
# 检查apiserver pod创建时间
kubectl -n kube-system get pod | grep kube-apiserver
# 如果没有重启,执行以下命令重启kubelet
systemctl restart kubelet