写点什么

kubelet 1.14 升级 kubelet 1.20 容器重启问题

用户头像
Geek_f24c45
关注
发布于: 2021 年 08 月 26 日

在 kubelet 1.14 升级 kubelet 1.20 的时候, apiserver 等 master 组件率先升级后,直接替换升级 kubelet 二进制重启即可!


理论上,POD 无影响, 容器无影响,即无感! 1.18 升级 1.20 过程中 确实如此!


在 1.14 升级 1.20 过程中,却出现了 容器发生了重启的现象!


翻翻代码, 1.17 的时候,HashContainer 的方法做过调整,导致 container config 的 Hash 值全部都会变化,在 kubelet 重启时,认为容器不再是同一个,需要重建,所以发生了重启!


那么我们怎么破解这个升级的无感问题那?


容器的 hash 值 是记录在 容器的 labels 中的, 我们将该值 修改 同 新 hash 算法得出的一致,kubelet 就认不出差异了,,


那么怎么修改 docker 的 labels 那? docker 似乎没有相应的 API 更新 label


  1. config.v2.json 我们修改 docker 对应容器的配置文件,

  2. 利用 etcd 的 container config 计算出新 hash,替换 config.v2.json 中的 hash label

  3. 重启 dockerd, inspect 会发现 docker 的 label 已经修改


容器不会被重启,替换 kubelet 到新版,重启 kubelet , 容器也不会再重启!


有一个疑问, kubelet pleg 会一直 inspect 容器的状态,产生 event,触发 container 更新的对比,为什么我们修改了 docker 容器的配置,没有触发 kubelet (旧版)对比更新那?


func computeEvents(oldPod, newPod *kubecontainer.Pod, cid *kubecontainer.ContainerID) []*PodLifecycleEvent {	var pid types.UID	if oldPod != nil {		pid = oldPod.ID	} else if newPod != nil {		pid = newPod.ID	}	oldState := getContainerState(oldPod, cid)	newState := getContainerState(newPod, cid)	return generateEvents(pid, cid.ID, oldState, newState)}
func getContainerState(pod *kubecontainer.Pod, cid *kubecontainer.ContainerID) plegContainerState { // Default to the non-existent state. state := plegContainerNonExistent if pod == nil { return state } c := pod.FindContainerByID(*cid) if c != nil { return convertState(c.State) } // Search through sandboxes too. c = pod.FindSandboxByID(*cid) if c != nil { return convertState(c.State) }
return state}
复制代码


从代码处可见,pleg 触发 event 检查的是 container state 状态的变化,我们 “偷偷的改变 label”, 他是察觉不到的,,


这样我们解决了无感升级的问题!

用户头像

Geek_f24c45

关注

还未添加个人签名 2018.03.24 加入

还未添加个人简介

评论

发布
暂无评论
kubelet 1.14 升级 kubelet 1.20 容器重启问题