zoukankan      html  css  js  c++  java
  • 宜信容器云排错工具集

    宜信容器云是一套基于kubernetes的容器管理平台。业务线用户在容器云上部署应用程序时,常常会遇到容器无法启动或者应用程序运行不正常的情况。为了方便用户排查在应用上云过程中的问题,我们在web端集成了一系列的排错方式,如下图:

    一、终端信息

    终端信息查看的是容器实例运行时的标准输出日志。

    效果等同于:kubectl logs PODNAME [-c CONTAINER]

    基本原理如下图:

    应用部署时,所属节点的kubelet通过grpc调用容器运行时接口(container runtime interface),来请求docker守护进程创建容器运行时。

    此时,docker守护进程会创建一个协程来接收容器运行时的标准输出日志,这个协程最终将STDOUT(标准输出)的日志写到容器运行时所在节点的对应目录下:/var/lib/docker/containers/container_id/{container_id-json.log}

    如下图:

    在web端查看对应实例的终端信息时,kubelet将接收的Api-server请求转化成docker client来请求docker守护进程。Docker守护进程到相应的目录下读取对应容器的日志文件数据,再由kubelet返回日志数据到Api-server,最终显示到web端,供用户查看。

    容器日志的生命周期与容器的生命周期一致,容器销毁后,其相关的日志文件也会销毁。

    二、events

    events是kubelet用来记录容器启动及运行过程中的事件。

    效果等同于:kubectl get events

    同样,当使用kubectl describe pod来查看pod时,也一样能看到与该pod相关的events,从这些信息中可以很清楚看到事件的状态变化,从而获知pod启动失败的多种原因。比如:

    1)没有可用的node供调度,如调度的节点资源不够;

    2)健康状态检查失败;

    3)拉取镜像失败,如下图:

    events的基本实现如下图:

    events中包含事件相关的类型、原因、来源、消息等,会在kubelet和controller manager等组件中生成,广播出去后,经过一系列的函数过滤、聚合等,再发送给Api-server存到etcd中。当web端查看events事件时,请求Api-server读取etcd中相应的事件,并返回显示,供用户查看异常参数、错误状态等。

    三、web terminal

    web terminal可提供一个交互式的界面shell,可执行各种命令。

    效果等同于:kubectl exec -it <podName> -c <containerName> bash

    web端显示如图:

    实现如下:

    web terminal主要是通过websocket技术实现的,前端交互界面使用的是开源项目container-terminal(https://github.com/kubernetes-ui/container-terminal),其提供了一个容器的TTY(虚拟终端)。

    当查看web terminal时,前端web发起了一个websocket请求,到Api-server。再由所属节点的kubelet响应该Api-server的请求,并与容器运行时建立连接。

    之所以kubelet能够与容器运行时建立连接,是因为kubelet 定义了一个 CRI 规范中的 RuntimeServiceClient 接口,而容器运行时中的RuntimeServiceServer(即Streaming Server,提供了streaming API)实现了该接口。

    kubelet 和容器运行时建立连接后,kubelet返回请求,Api-server将请求升级为SPDY(SPDY允许在单个的TCP请求中复用独立的STDIN/STDOUT/STDERR),并将WS的流映射到SPDY相应的标准流上,便与目标容器运行时Streaming Server建立了流,Api-server便实现了web与容器运行时的数据交互。

    此时,在web端输入命令,下发执行完后,可看到返回的结果,如此便实现了交互。

    web terminal提供了进入容器的便利,用户可以执行任何操作,为了安全,我们做了必要的安全措施:

    1)记录了用户的操作命令。

    待用户输入命令后,记录操作,作为安全审计。

    2)生产环境使用普通用户进入容器。

    即在exec进入容器时的命令/bin/bash -i更改为/bin/bash –c chmod -R 777 $KUBERNETES_FILELOGS;useradd spider > /dev/null 2>&1;su spider,其中环境变量$KUBERNETES_FILELOGS为在容器创建时需要赋权的文件目录。主要是防止用户误操作,删除存储挂载等。

    四、debug容器

    debug容器是通过工具容器来对业务容器排障。

    在使用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排错和对应用程序的排障。

    作者:段德华

    来源:宜信技术学院

  • 相关阅读:
    POJ 1015 Jury Compromise【DP】
    POJ 1661 Help Jimmy【DP】
    HDU 1074 Doing Homework【状态压缩DP】
    HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
    占坑补题。。最近占的坑有点多。。。
    Codeforces 659F Polycarp and Hay【BFS】
    Codeforces 659E New Reform【DFS】
    Codeforces 659D Bicycle Race【计算几何】
    廖大python实战项目第四天
    廖大python实战项目第三天
  • 原文地址:https://www.cnblogs.com/yixinjishu/p/11983459.html
Copyright © 2011-2022 走看看