查看原文
其他

K8S Master 误执行 reset,雪崩解决过程

Ace Linux云计算网络 2021-12-21

来源:K8S中文社区

概述:由于不小心在K8S唯一的master上误执行kubeadm reset产生的一系列问题。


背景:

公司准备迁移一个K8S集群,当前集群是kubeadm+外部etcd的架构,准备把若干原来的虚拟机节点和etcd,移到新买的高配物理机上。


首先:迁移etcd

由于没有足够的机器,打算用恢复快照的方式起新etcd。迁移并不顺利,用恢复快照的方式发现配置项kubeadmin-config数据有误,(时间紧迫没有深追原因)只好通过把整个文件/var/lib/etcd拷贝还有证书(server、server-key、ca)到新机器上,然后在启动选项中加入--initial-cluster-state=new强行启动etcd服务。


第二:把旧master的etcd指向新etcd

发现仅在配置中更换etcd的地址不能成功,因为原etcd自签证书并不包括新机器IP,所以重签证书,然后下发到旧master上,然后修改/etc/kubernetes/manifests/kube-apiserver.yaml中etcd地址为新IP


第三:添加新master到现有集群

join master的方式
首先在旧master上生成token、cert和它们的hash值
kubeadm init phase upload-certs --upload-certs
得到--certificate-key的hash值


kubeadm token create --print-join-command
得到token和 --discovery-token-ca-cert-hash值


完整命令


kubeadm join <API_HA_IP:6443> --token <TOKEN> --discovery-token-ca-cert-hash <TOKEN-HASH> --certificate-key <certificate-key> control-plane



(以上操作其实失败,还在摸索原因)


中间在执行的过程中,出了几次麻烦,所以会时不时执行kubeadm reset操作重置节点。突然不小心在旧master上执行了reset,崩溃!这下新master还没进来,唯一的旧master被重置,apiserver失去通讯。。。整个k8s相当于挂了。


紧急补救措施:
所幸etcd在外部,并且正常运行,这意味着只要恢复master和apiserver,那集群的数据应该还在


首先,在旧master所在的机器上重新初始化
可是初始化后,kubectl get node 发下只有master在线,其他节点全部notready


分析半天日志发现是flannel认证失败
把已有的flannel相关资源全部删除(serviceaccount、configmap、daemonsets)
用官方的yaml文件重新生成flannel


然后,每个旧worker节点执行reset并再次join到集群,这波操作后貌似正常了


但是第二天发现所有proxy、coredns、flannel都crash,集群还是垮的


这时发现新情况如下:
flannel报连接:10.0.96.1 time out
1.说明apiserver的service访问超时
2.apiserver由kube-proxy创建的endpoint不存在
3.kube-proxy报认证失败 Failed to list *v1.Service: Unauthorized


认证失败的原因是:etcd保存的serviceaccount产生的secret数据是旧master的ca,而新master的ca已经变化,所以认证失败


解决办法:

1.删除所有现有proxy、cordns的serviceaccount
kubectl get sa -n kube-system|grep -E "kube-proxy|coredns"|awk '{print "kubectl delete sa",$1,"-n kube-system"}'|/bin/bash


2.重新初始化master,让K8S自动生成和ca匹配的serviceaccount和secret,该secret是proxy的认证依据。
yes|kubeadm reset
kubeadm init --config <yourconfig.yaml>


3.删除所有旧flannel资源
kubectl delete -f   <kube-fannel.yaml>


4.重新生成flannel
kubectl applay -f   <kube-fannel.yaml>


5.重新reset其他节点再jion
yes|kubeadm reset
kubeadm join <API_HA_IP:6443> --token <TOKEN>  --discovery-token-ca-cert-hash <CERT-HASH>


全部操作后,proxy、coredns、flannel均正常运行了,继续观察中


其中有个statefulset一直报错,查看日志,发现还是认证失败

经查,也是因为启用了serviceaccount导致etcd保存的secret还是旧值,删除该secret
该pod终于正常了


kubect get pod -A -o wide | more
检查所有pod全部正常


以上,集群终于全部恢复


结语:这次故障最万幸的是采取了外部etcd,并且etcd正常迁移了。如果是默认kubeadm捆绑式etcd,那master被reset后,重新搭建集群事小,关键是所有配置还得重新建立,损失就大了.




后台回复“加群”,带你进入高手如云交流群


推荐阅读:

一次成功的ARP黑客欺骗攻击

几个使用GitHub的正确姿势

从理论到实践,全方位认识 DNS

浅谈互联网那些防不胜防的人肉搜索技巧

阿里双11,亿级流量高并发是怎么抗住的?

9 个问题进一步熟悉 HTTPS

一文看懂DevOps,再不懂来打我

Linux 下 4 种实时监控日志文件的方法

一文理解TCP、UDP协议及两者的区别

为什么 TCP 建立连接需要三次握手


喜欢,就给我一个“在看”



10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存