非常非常抱歉,新年上班第一天, 在今天阿里云上气候突变情况下,由于我们开船技术差,在今天 10:15~12:00 左右的访问高峰,我们竟然把船给开翻了,造成近2个小时整个博客站点无法访问,由此给您带来很大很大的麻烦,恳请您的谅解。
翻船经过如下。
翻船前的船只情况
博客站点正在使用的 k8s 集群一共用了 9 台 worker 节点服务器,在访问低峰时用 5 台,另外 4 台处于关机状态,在进入访问高峰前启动。所以我们用 cron 定时任务在工作日每天早上启动 4 台服务器,每天晚上关闭 4 台服务器。为了节约成本,这 4 台服务器用的是阿里云抢占式实例,由此带来的风险是如果启动时当前可用区对应的实例库存不足,就会启动失败。
还有一个正在搭建中的高可用 k8s 集群,运行着 1 台 master 与 1 台 worker 节点,另外 2 台 master 与 1 台 worker 处于关机状态。
在 k8s 集群之前使用的 docker swarm 集群处于待弃用状态,运行着 1 台 manager 与 1 台 worker 节点,其他节点都处于关机状态,用的也是阿里云抢占式实例。
风云突变,船只颠簸
今天新年上班第一天,阿里云上生意非常火爆,我们的服务器所在可用区的所有4核8G的抢占式实例全部售罄,造成定时启动 k8s 集群节点服务器的任务全部失败,仅有的 5 台服务器在访问高峰不堪重负,开始出现 502 ,当我们发现后,尝试通过阿里云 ecs 控制台启动这些服务器,但依然因库存不足而无法启动。
操作有错误发生: i-bp10c3nww9y26s9yppcq : 库存不足,请您尝试其它类型的实例规格 或者 其它可用区/地域的实例。您可以选择变配到其他规格,然后启动。更改实例规格 RequestId: 86752D85-39F0-4FEC-875B-80A3269D0B23
紧急自救,却遭意外雷击而翻船
手动启动服务器失败后,我们赶紧新购服务器添加到集群,本以为等服务器加好就能恢复,哪知却遭遇新的意外情况,新加服务器上所有博客站点的 pod 都启动失败。
NAME READY STATUS RESTARTS AGE blog-web-bw87z 0/1 CrashLoopBackOff 4 4m36s
Pod 启动失败是因为其中的博客站点容器 dns 解析失败,无法解析所依赖的服务的地址。
接着情况变得越来越严重,不仅新加服务器因 dns 解析问题无法启动 pod ,而且集群中已有服务器也因为这个问题无法启动 pod 。本来已有 5 台还能支撑部分请求,但由于这个意外的 dns 解析问题,集群中除了1-2台博客应用的 pod 还在运行,其他全挂了,这时整个博客站点全是 502 错误,k8s 巨轮就这么翻了。
救援行动,旧渔船挺身而出
巨轮翻了后,我们开始救援行动,首当其冲就是另外一艘建造中的更高级的巨轮 —— k8s 高可用集群,新购服务器加到这个集群,准备用这个集群处理负载,哪知这个集群也出现了异常情况,pod 也是无法启动,一直处于 ContainerCreating 状态。
NAME READY STATUS RESTARTS AGE blog-web-b2ggt 0/1 ContainerCreating 0 4m48s Error from server: Get https://10.0.2.82:10250/containerLogs/production/blog-web-b2ggt/blog-web: dial tcp 10.0.2.82:10250: connect: connection refused
这时唯一的救命稻草就是那艘准备弃用的旧渔船 —— docker swarm 集群,这个集群中处于关机状态的节点服务器也因为库存不足而无法启动,只能新加服务器,赶紧把 k8s 集群中的那些服务器拿过来用镜像更换系统后加入 docker swarm 集群。
sudo rm -rf /var/lib/docker/swarm && service docker restart && docker swarm join --token xxx 10.0.151.251:2377
当 docker swarm 集群投入使用并加到一定量的服务器后,博客站点才恢复正常。
开船的迷茫
恢复正常后,我们立即去排查出现 dns 解析问题的 k8s 集群,发现所有 worker 节点都出现了 dns 解析问题, 上次我们也被 dns 解析问题坑过(详见 k8s 开船记:升级为豪华邮轮(高可用集群)与遇到奇怪故障(dns解析异常)),只是上次只有部分节点出现这个问题,这次是所有 worker 节点,上次是通过重启服务器解决的,难道这次也要重启才能解决?
于是将 worker 节点全部重启,重启后所有 pod 都正常运行了,这时我们恍然大悟,后悔莫及,当时营救翻船最简单快速的方法就是重启所有 worker 节点服务器。
开着旧渔船,回想着靠岸待修理的巨轮,望着茫茫大“云”,我们更加迷茫了。使用 docker swarm 时多次遭遇奇怪的网络问题,通过重启节点服务器解决,开始我们怀疑水(云),后来我们怀疑船(docker swarm),于是下定决心换掉渔船,换上巨轮(k8s),结果又遇到到了奇怪的网络问题(dns 解析问题是网络问题引起的),现在我们该怀疑谁呢?.
对于这次大翻船,最重要的原因是我们过多地使用了抢占式实例,是我们的过错,我们会吸取教训,调整服务器的部署。
这次大故障给您带来麻烦了,再次恳请您的谅解。