【故障公告】k8s 开船记:增加控制舱(control-plane)造成的翻船
春节期间我们更换了 kubernetes 生产集群,旧集群的 kubernetes 版本是 1.17.0,新集群版本是 1.23.3,新集群上部署了 dapr,最近准备将更多独立部署的服务器部署到 k8s 集群上,比如 redis, memcached, mongodb。
新集群和旧集群一样都是高可用集群,但新集群开始只用了 1 个 control-plane 节点,今天本来的任务是给新集群再增加 2 个 control-plane 节点,实现高可用。
如何加入 control-plane 节点呢? k8s 没有直接提供生成 join 命令的命令,下面的命令只能用于加入 worker 节点。
kubeadm token create --print-join-command
之前我们是在创建集群的时候,在执行 kubeadm init 命令之后就操作加入 control-plane 节点,kubeadm init 会生成加入命令
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join k8s-api:6443 --token ****** \
--discovery-token-ca-cert-hash ****** \
--control-plane --certificate-key ******
上面的命令实际上就是 token create --print-join-command
的输出加上 --control-plane
与 --certificate-key
,但之前使用的 certificate-key 已经过期。
开始我们用下面的命令生成 certificate-key 加入集群
kubeadm certs certificate-key
但加入失败,报错信息如下
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
error execution phase control-plane-prepare/download-certs: error downloading certs: error downloading the secret: Secret "kubeadm-certs" was not found in the "kube-system" Namespace. This Secret might have expired. Please, runkubeadm init phase upload-certs --upload-certs
on a control plane to generate a new one
于是改用 upload-certs 命令
$ kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
*****
将 upload-certs 命令生成的 certificate-key 用于 kubeadm join 命令,这个 key 果然可以,但是在加入过程中卡在了下面的地方
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
[kubelet-check] Initial timeout of 40s passed.
本以为新 control-plane 节点加入不了不会影响现有集群的正常运行,但一个残酷的现实突然而至 —— 已有且仅有的那台 control-plane 上 api-server 容器突然无法启动了,syslog 中的其中一条错误信息如下
"Unable to authenticate the request due to an error" err="Post "https://k8s-api:6443/apis/authentication.k8s.io/v1/tokenreviews": dial tcp 10.0.9.171:6443: connect: connection refused"
这时虽然 api-server 不能正常工作,但 worker 节点上的 pod 都正常运行,应用暂时没有受影响。
面对这样如履薄冰的场景,我们首先想到的是先恢复旧集群,将负载切换到旧集群,然后从容地处理新集群的问题,但故障如此会开玩笑,旧集群的 api-server 竟然也无法正常启动。
CONTAINER ID IMAGE COMMAND CREATED STATUS
0f30ff71a13d 0cae8d5cc64c "kube-apiserver --ad…" 5 seconds ago Up 3 seconds
命运会作弄人,故障也学会了。
面对如履薄冰与故障的作弄,我们做出了一个铤而走险的决定 —— 更新所有证书,之前成功操作过,但当时集群中没有负载。
用下面的命令三下五除二地完成了证书更新
$ cd /etc/kubernetes/pki/
$ mv {apiserver.crt,apiserver-etcd-client.key,apiserver-kubelet-client.crt,front-proxy-ca.crt,front-proxy-client.crt,front-proxy-client.key,front-proxy-ca.key,apiserver-kubelet-client.key,apiserver.key,apiserver-etcd-client.crt} ~/
$ kubeadm init phase certs all --control-plane-endpoint "k8s-api:6443"
$ cd /etc/kubernetes/
$ mv {admin.conf,controller-manager.conf,kubelet.conf,scheduler.conf} ~/
$ kubeadm init phase kubeconfig all --control-plane-endpoint "k8s-api:6443"
接下来就是重启 control-plane 节点服务器使用更新的证书。
重启的结局却是 —— 满园尽是502
走险失败后立即进入紧急抢险,用当前 control-plane 节点今天凌晨的快照创建镜像,用镜像重置整个系统。
重置后的 control-plane 节点成功启动后,从 control-plane 节点上看集群应该恢复了正常,worker 节点都处于 ready 状态,绝大多数 pod 都处于 running 状态,但是 pod 中的应用却不能正常工作,比如连不上其他服务、ingress 规则失效等。
开始以为要将所有 worker node 退出并重新加入集群才能恢复,但是在第1个 worker node 上操作退出,却卡在下面的地方
$ kubeadm reset
[reset] Unmounting mounted directories in "/var/lib/kubelet"
后来想到重启所有 worker node 试试,越是关键时候越是不能忽略简单方法,都重启后一切恢复了正常。
非常抱歉,今天 19:10~19:50 期间由于 k8s 集群操作引发全站全站故障,由此给您带来很大的麻烦,请您谅解。
【故障公告】k8s 开船记:增加控制舱(control-plane)造成的翻船的更多相关文章
- k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船
非常非常抱歉,新年上班第一天, 在今天阿里云上气候突变情况下,由于我们开船技术差,在今天 10:15~12:00 左右的访问高峰,我们竟然把船给开翻了,造成近2个小时整个博客站点无法访问,由此给您带来 ...
- k8s 开船记-触礁:四涡轮发动机撞坏3个引发502故障
(图片来自网络) 非常抱歉,这次开船触礁故障给您带来麻烦了,请您谅解. 在我们昨天发布 k8s 开船记首航博文后,有园友在评论中发来贺词——“泰坦尼克号出发了[狗头]”,借此吉言,今天船就触礁了,还好 ...
- k8s 开船记:升级为豪华邮轮(高可用集群)与遇到奇怪故障(dns解析异常)
之前我们搭建的 k8s 集群只用了1台 master ,可用性不高,这两天开始搭建高可用集群,但由于之前用 kubeadm 命令创建集群时没有使用 --control-plane-endpoint 参 ...
- k8s 开船记-首航:博客站点从 docker swarm 切换到 k8s
昨天晚上,我们将博客站点的生产环境从 docker swarm 集群切换到了 k8s 集群,开船到目前,航行非常平稳,可以说首航成功! k8s 集群是我们用10台阿里云服务器自己搭建的,1台 mast ...
- k8s 开船记-修船:改 readinessProbe ,去 DaemonSet ,上 Autoscaler
(图片来自网络) 改 readinessProbe 对于昨天 k8s 尼克号发生的触礁事故,我们分析下来主要是2个原因,一是当时4个节点不够用造成部分容器负载过高而宕机,二是 readinessPro ...
- k8s 开船记-全站登船:Powered by .NET Core on Kubernetes
今天 18:30 左右,我们迈出了 kubernetes 航行的关键一步——全站登船,完成了全站应用从 docker swarm 集群向 k8s 集群的切换,以前所未有的决心与信心重新开起这艘巨轮,而 ...
- k8s 开船记-脚踏两只船:船儿还是旧的好,不翻船才是硬道理
自从上次开始脚踏两只船(2个独立的k8s集群同时运行),园子暂时用奢侈的土豪方式过上了安稳的船上生活. 这种方式除了费钱之外,还带来一个问题,我们的集装箱自动装船系统(基于gitlab-ci的自动化部 ...
- 【故障公告】再次遭遇SQL语句执行超时引发网站首页访问故障
非常抱歉,昨天 18:40~19:10 再次遭遇上次遇到的 SQL 语句执行超时引发的网站首页访问故障,由此您带来麻烦,请您谅解. 上次故障详见故障公告,上次排查下来以为是 SQL Server 参数 ...
- 【故障公告】redis 服务器宕机引发博客站点故障
非常抱歉,今天下午 17:10~17:40 左右,由于博客系统所使用的 redis 服务器宕机,造成博客站点无法正常访问,由此给您带来很大的麻烦,请您谅解. 我们会针对这次故障改进 redis 服务器 ...
随机推荐
- 获取iframe外的document
在iframe中点击弹出层外部分弹出层消失,但是点击iframe外部分就操作不了弹出层了,被这个问题困扰了不少时间,今天得以解决,代码如下: 说明:$(top.document,document).c ...
- 微软开源Kubernetes服务网格项目Open Service Mesh
尽管微服务环境提供可移植性,允许更快更频繁的部署周期,甚至还能让组织创建关注于特定领域的团队,但这也伴随着对于流量管理.安全以及可观测性等需求的增长.在整个生态系统中,针对这些需求的服务网格模式的实现 ...
- Spring Security 接口认证鉴权入门实践指南
目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...
- 【SpringCloud技术专题】「Gateway网关系列」(3)微服务网关服务的Gateway全流程开发实践指南(2.2.X)
开发指南须知 本次实践主要在版本:2.2.0.BUILD-SNAPSHOT上进行构建,这个项目提供了构建在Spring生态系统之上API网关. Spring Cloud Gateway的介绍 Spri ...
- python2.7发送邮件失败之——SMTPAuthenticationError问题
使用python2.7发送邮件,代码如下: from email.header import Headerfrom email.mime.text import MIMETextimport smtp ...
- Rust 实现Netty HashedWheelTimer时间轮
目录 一.背景 二.延迟队列-时间轮 三.Netty 时间轮源码分析 四.Rust实现HashedWheelTimer 五.总结思考 一.背景 近期在内网上看到一篇文章,文中提到的场景是 系统自动取消 ...
- SQL安全执行
begin tran begin -----------执行SQL开始----------------- update Audioset Name =3 -----------执行SQL结束----- ...
- unity3d之public变量引发错误
public变量引发错误 在vs ide中怎么更改也无效 后来发现public里面的值一直不改变,手动改之.
- java有四种访问权限
Java面向对象的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有.默认.保护和公有,具体规则如下表:
- CentOS7搭建Docker私有仓库----Docker
有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,这点跟Maven的管理类似.目前Docker Registry已经升级到了v2 ...