目录
- 故障描述
- 处理经过
- 原因分析
- 故障思考
小D所在业务要从公司独立出去,部分业务和域名需要从公司拆分出去。小D领到了一个任务:迁移源站的多媒体裁切服务(CropSrv)。
上图是一个典型的互联网CDN接入和分发流程,以小D公司为例:
- APP上看到的图片,音频,视频都是就近CDN的接入点(Pop)下载
- CDN如果没有相应的资源,会到源站(IDC内)下载
- 源站的资源存储在OSS(对象存储)
- 源站根据资源的格式需求进行裁切(图片一般是下载现场裁切,音视频则是提前裁切好)
时间紧,任务重,小O通过以下命令下载了裁切服务的镜像
docker save -o crop_service.v1.tar hub.aaa.com/crop_service:v1
然后推送到新公司的hub上
docker load < crop_service.v1.tar
docker tag crop_service:v1 hub.bbb.com/crop_service:v1
docker push hub.bbb.com/crop_service:v1
然后直接部署在了K8S上,迁移直接就结束了。测试功能正常没有问题。
业务独立运行一个月后:
操作结束,Pod重建,小O看了一眼自己的CropSrv服务,没什么问题
结果群里就炸了,图片请求不到了
故障描述
源站裁切服务故障致APP白屏
处理经过
时间 |
处理同学 |
动作 |
17:00 |
小O |
K8S系统演练,重启Node |
17:05 |
小D |
确认Pod Running态正常,以为没问题 |
17:20 |
APP白屏 | |
17:20 - 18:00 |
小D |
定位原因,重新打镜像修复问题 |
原因分析
公司的容器模型是这样的:
- 配置文件在服务发版的时候打包到镜像内
- 服务启动的时候从配置中心现场获取一份最新的配置文件
这样设计是为了保证任何情况下服务都能正常启动。
容器内下载配置文件示意图
结果,小D进到容器内发现服务没有启动。
服务没有启动为什么Pod还是Running呢?
容器内进程树
容器内的进程模型如上,1号进程为supervisor 。对于K8S来说只要supervisor不失败Pod就会一直是Running状态。前提是不开启健康检查。
巧了,这个服务没有开启健康检查。服务启动就Crash,然后被supervisor拉起,再crash,如此往复:
那服务为什么没有启动呢?
- 巧了,镜像里没有打默认的配置文件
- 老的配置中心的域名已经失效,无法启动下载配置文件
发现原因后,小D立刻制作了一份带配置文件的新镜像,重新部署紧急恢复了
FROM hub.bbb.com/crop_service:v1
COPY conf/ /app/crop_service/conf
故障思考
故障的时候总是各种巧合都撞在一起:
- 服务没有遵循规范开启健康检查
- 服务没有遵循规范将配置文件打包到镜像内
- 迁移服务的时候把镜像不做任何修改的打包过来恰好正常运行了
结果故障就是这样发生了~解决巧合只能靠规范化的流程和不偷懒的实践~
记录那些年我们一起处理过的故障~
公众号:小O小D