宜信容器云排错工具集 (2)

在使用web terminal来调试应用程序的过程中,业务线用户经常需要各式各样的命令来调试程序。之前的解决方案要么是给业务线定制他们所需的基础镜像,尽量涵盖多的所需命令,要么就是在业务线用户构建镜像时在Dockerfile中添加命令。

但是,因为业务线众多,定制基础镜像工作量过大;而在构建业务镜像时添加过多命令,又操作繁琐,并可能会带来安全隐患。这些解决方案实际上都不符合容器技术的实践原则--尽可能构建最简容器镜像,而精简后的镜像又极度缺失所需的命令工具。

鉴于存在这样的矛盾,我们集成并改造了kubectl-debug(https://github.com/aylei/kubectl-debug)这个插件。容器实质上是由cgroup和namespace限制的一组进程,只要能够加入到这个进程的各项namespace,就可实现交互。因此,debug容器的基本思路是:启动一个包含众多排障工具命令的容器,来加入到业务容器的namespace中,便能够在工具容器中实现对业务容器的排障。

效果类似于:

docker run -it --network=container:<container_ID> --pid=container:<container_ID> --ipc=container :<container_ID> -v /log/container _ID:/debugviewlogs <image>

web端显示如下图:

宜信容器云排错工具集

debug容器原理如下图:

宜信容器云排错工具集

将Debug-agent以DaemonSet的形式部署到kubernetes集群的所有节点中,并挂载了宿主机的/var/docker/docker.sock,实现与docker daemon的通信。如上图的步骤:

1)web端提供pod的cluster、namespace、podname信息,向后端服务Backend server发起websocket请求;

2)后端服务Backend server接收到请求后,向Api-server验证该pod是否存在,并返回pod所在的宿主机Node和pod的容器信息,根据状态判断是否可以debug;

注意:如果pod的状态reason是CrashLoopBackOff,那么Backend server将会请求Api-server让kubelet复制一个pod, 复制的Pod被改写了启动命令(sleep)、去掉了label及健康检查。后续debug操作是对复制后pod进行的。

3)Backend server传递debug的pod信息,发起debug请求(升级的SPDY请求,映射了WS的标准流)。

4)Debug-agent收到请求后,开始拉取debug工具镜像,进而创建一个debug容器,并将debug容器的各个namespace设置为目标业务容器app的namespace。再将宿主Node的目录/log/ 挂载到debug容器的目录/debugviewlogs中,便可实现将debug容器中生成的文件在web端下载。如下两图:

宜信容器云排错工具集

宜信容器云排错工具集

创建完debug容器后,Debug-agent将Backend server的SPDY请求中继到debug容器。debug容器将SPDY的标准流attach到业务容器中。如此,web端便可与debug容器实现交互。在debug操作结束后,Debug-agent便会将debug容器清理回收。同样的,debug的操作也做了安全审计。

因此,我们只要构建一个包含众多排障工具的镜像,不仅实践了业务镜像尽可能最简的原则,还提供了调试应用程序所需的各种命令工具。

总结

终端信息、events、web terminal及debug容器都提供了一个可视化的web,让用户能够方便快速地实现对pods排错和对应用程序的排障。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygjjg.html