我们已经与数百名客户合作,为他们的环境构建了监控栈,所以我们已经了解什么是可行的,什么是不可行的。这些合作的结果可能会让你大吃一惊,比如我们发现在监控的时候,仪器和应用程序其实是一样重要的。 本文将介绍如何建立一个横向扩展、高度可靠的监控系统来处理数万个容器所需要的细节,并且还将分享一下基础架构,设计选择和权衡。我将介绍的五个方面如下:
1.系统测量;
2.将数据与应用程序,主机和容器相关联;
3.利用协调器;
4.决定要存储的数据;
5.如何在集装箱化环境中启用故障排除;
首先你得了解,Sysdig是一家做容器监控的公司。开源项目允许您看到单个主机上的每个系统调用过程、参数、有效负载和连接。
商业产品将所有这些数据转化为数千个指标,为每个容器和主机提供数据,并汇总所有数据,并为您提供仪表板,报警和类似htop的环境。 我们从容器对监控系统的影响开始,深入了解一些细节。
为什么说容器改变了监控的规则
容器的功能非常强大,特点如下: 简单性:典型的单个进程; 体积小:体积是VM大小的1/10,表示它们是便携式的; 无依赖性:组件之间无依赖性; 动态性:快速的启动时间; 保持容器的简单性是其价值主张的核心,也是微服务的重要构建块。但是这种简单性是有代价的。从ops的角度来看,您需要在容器内进行深入的可视性,而不仅仅是知道某些容器存在。 您的容器也很可能由一个编配系统管理(想想Kubernetes或swarm),如果您正在运行PaaS,那么您的开发人员可能会在任何时候推动新的应用程序,而不通知平台团队。 好了,现在我们知道正在处理这些小的黑盒子,它们出现,死亡,并且被你的编配系统的突发奇想所感动。您的开发人员可以自由地添加和修改他们的应用程序。你的工作是确保公司的应用程序运行正常,更不要说有数据来解决问题。让我们开始打破监控的挑战。
仪器需要透明
1.在静态或虚拟环境中,让代理在主机上运行很简单,并根据相关应用程序配置代理。
然而,在集装箱化的环境中,这种方法并不起作用:
2.不能将代理放在每个容器中(不破坏容器的键值);
随着应用程序的出现和运行,开发者不能手动配置代理插件来收集相关的应用级别指标; 所以我们试图使仪器的功能必须尽可能透明,尽可能少的人为干预。 基础设施指标,应用指标,服务响应时间,自定义指标和资源/网络利用率应该在容器内不需要任何消耗的情况下就可以完成。
它当然不应该要求每个附加容器的自旋向上。 实现这一目标有两种可能方法。首先是pods,这是Kubernetes创造的一个概念。pod是一组共享公共名称空间的容器。因此,一个容器内的容器可以看到相同容器中的其他容器正在做什么。对于监视代理,这通常被称为“sidecar”容器。
好处之一是在Kubernetes中,这是相对容易的事情。然而,缺点是:如果机器上有很多的pods,资源消耗就会很高——这有点像每个进程都有一个监控代理,而且您还创建了依赖项,以及在这个pod中附加的攻击表面。这意味着,如果您的监视sidecar具有性能、稳定性或安全性问题,它就会对您的应用程序造成严重破坏。
第二种模式是每个主机,透明的仪器。 这个透明的仪器利用单个测试点捕获所有应用程序,容器,统计信息和主机指标,利用内核中的跟踪点设备,并将其发送到每个主机的容器进行处理和传输。
这消除了将所有内容变成统计数据的需求,这是我们看到许多人所追求的。 与sidecar模型不同,每个主机代理极大地减少了监视代理的资源消耗,并且不需要修改应用程序代码。但是,它确实需要一个特权容器和一个内核模块。
核心设备是如何运作的
ContainerVision是让Sysdig如此不同的一个重要因素,所以让我们花点时间去了解一下它是怎么运行的吧。这一部分我将重点讲一下开源项目是如何运作的。你们中的大多数人可能会成为第一批使用这个版本的,所以读完这篇文章以后,你应该会有更深刻的理解。
Sysdig的架构和libpcap/tcpdump/wireshark非常相似(这不是巧合,因为Sysdig是由wireshark的共同创建者之一创建的)。首先是由sysdig-probe这么一个小型驱动器在内核中去捕获事件,它使用的内核工具是tracepoints。tracepoints使得可以安装从内核中的特定功能调用的“处理程序”。
目前,sysdig注册进入和退出的系统调用的跟踪点以及进程调度事件。 Sysdig-probe对这些事件的处理程序是非常简单的
- 它仅限于将事件详细信息复制到共享缓冲区中,以供以后使用。 保持处理程序简单的原因可以想像,是性能,因为原始的内核执行被“冻结”,直到处理程序返回。。
驱动器就是负责做这些事的,其它的不可思议的事情是发生在User层。 Event Buffer被内存映射到用户空间,这样就不需要任何副本即可进行访问,从而最大限度地减少CPU使用率和缓存。libscap和libsinsp这两个lib提供了读取、解码和解析事件的支持。具体来说,libscap提供了跟踪文件管理功能,而libsinsp包含复杂的状态跟踪功能(例如,您可以使用文件名而不是FD号),还可以过滤事件解码,Lua
JIT编译器来运行chisels等等。最后,sysdig把它作为一个简单的包装器放在这些库中。 但是,如果sysdig,libsinsp或libscap不够快,无法跟上来自内核的事件流呢?sysdig会像strace那样导致系统变慢吗(聪明的读者会问)?当然不可能。在这种情况下,事件缓冲区会被填满,sysdig-probe开始遗漏传入的事件。
所以你会丢失一些跟踪信息,但机器和运行的其他进程不会减慢。 这是如果sysdig架构的关键优势,因为这不仅意味着可以预测跟踪的开销,还意味着在生产环境中运行,情况也会比较乐观,而且chisels不需要像DTraces的D脚本那样经过仔细的优化。除此之外,chisels还可以利用为Lua编写lib(想要将chisels的数据传递到Redis?用这个lib就可以做到!)。想在这个问题上稍微深入一点,可以阅读DTrace
vs strace vs sysdig: A technical discussion。
开源故障排除工具既为用户提供了命令行界面,也提供了针对单个主机基于curses的所有数据(如下所见)的接口。
对于我们的监控产品,我们使用同样的系统进行调用,进而从堆栈中提取相关的指标,并在分布式环境中创建一个类似htop的界面。
然而我们相信,如果处理容器的话,仅仅靠衡量标准就不够了。 因此让我们谈一谈这一切的意义。
如何将数据关联到应用,主机,容器和Orchestrators
随着环境复杂性的增加,基于元数据过滤、分段和分组度量的能力是至关重要的。标记可以帮助用户展示出应用程序体系结构的逻辑蓝图,但是不包括容器运行的物理现实。例如,您可以通过dev/prod、service、pod或其它的来进行划分。 您应该能够动态地选择或在指标上进行标记——以层次结构命名的、点分隔的指标名称和预定义的聚合正在逐渐消失。动态选择使您能够快速回答有关服务性能的问题,或者深入到名称空间甚至容器中。 可以想到有两种方式可以用来标记指标:显式标签(要存储的属性)vs隐式标签(协调器)。您应该有机制和最佳做法来添加明确的标签,以便团队中的任何人都可以根据各自的需求进行添加。但是默认情况下应该捕获隐式标记。后面的一点非常重要,因为它是下一个观点的重要组成部分。
随着产品的发展,我们发现发现默认情况下,通常会添加12-25个标签。 有的用户可能会用更多。 将每个独特的标签组合视为一个单独的指标,您需要根据需要对用户进行存储,处理和调用。
这有一些相当重大的影响,我们在下面的“决定要存储的内容”中讨论。
Leveraging Orchestrators
从根本上改变了容器的调度管理方法,并在此过程中影响了用户的监视策略。无论是Kubernetes、Swarm还是Mesos,您都将看到与监视方法类似的变化。单个容器变得不那么重要,而服务的性能变得更重要。该服务由许多容器组成,更重要的是,协调器可以根据需要移动这些容器,以满足性能和健康需求。具体来说,对于监控系统有两个含义: 监控系统必须根据协调器的元数据,隐式地标记所有指标。这适用于系统度量、容器度量、应用程序组件度量,甚至是定制的度量。 自定义度量需要重复:您的开发人员应该能够简单地输出定制的度量,而监视系统应该保持状态,关于度量来自何处。如果您依赖于“最佳实践”来进行标记,那么当您真正需要解决问题的时候,您的度量标准将是无用的。更多关于这个话题。 名义上有两种方法:依赖于协调器发出的事件来标记容器,或者根据容器的试探来确定应用程序。后者在你的监控系统中需要更多的智能,但会产生更可靠的结果。这是因为您的系统调用不会说谎—您可以轻松地将它们与运行中的应用程序联系起来。考虑到我们的仪表,你可以猜测Sysdig选择了后一种方法。 要了解更多关于Kubernetes和Kubernetes的信息,请点击“监视Kubernetes:详细的指南”
决定需要存储哪些数据:“所有的数据”
另一种说法就是“收集所有的数据”,是所有的数据,没有过滤过的,没经过任何处理的。 你得承认这样一个事实,那就是随着你的系统变得越来越复杂,软件变得越来越分布式,需要收集的数据也越来越多。标记就是最好的例子:它们的数量是那些必须要存储的指标的数倍。 当然,如果仅仅只存储节点应用程序Kubernetes部署的平均值/最小值/最大值/ 95th百分位这些,指标的数量应该也会降下来。它能很明显地减少指标收集,存储和计算。 但是随着基础的内容越来越复杂,存储所有数据的重要性也就越来越高,并以一种允许进行临时分析和故障排除的方式进行存储。例如,如果在之前提到的那个节点应用程序中有间歇性缓慢的响应时间,该怎么办呢?你怎么知道这是代码中的系统性问题,或是frtiz的容器问题,还是AWS的问题?通过部署来聚合所有这些信息,将不会给您足够的解决方案。 当然,这种方法产生的问题并不令人惊讶:您需要收集大量的数据。还需要收集指标和事件。你必须坚持,使用户可以随时访问。在这里,我们也做了一些重大的设计决策: 我们认为,在每个服务或每个应用程序环境中部署较小的、隔离的后端是不合理的。 对我们来说,这似乎不是一种可管理的方法来运行(在云环境中),或者让客户管理(在我们的软件的内部部署中)。如果您想知道为什么这是一个需要考虑的问题,那么您将看到像普罗米修斯这样的开源项目实际上是默认的后端模型,因此通过迫使更多的管理工作向用户提供更多的管理工作,从而引发了对可伸缩性的关注。相反,我们希望构建一个水平可伸缩的后端,我们的应用程序可以根据用户或服务来隔离数据、指示板、警报等。 为了提供没有时间限制的保留,我们决定在一段时间内滚动数据。我们将完整的解析数据存储6个小时,然后在此之后开始聚合数据。(我们还有一个解决方案,可以在警报的周围存储完整的分辨率数据。请参阅下一节。)
虽然我们的后端继续发展,但今天它由水平可伸缩的Cassandra(指标)、弹性搜索(事件)和Redis(服务代理)组成。基于这些组件的构建提供了很高的可靠性和规模,可以存储多年的数据来进行长期趋势分析和分析。所有数据都可以通过REST
API访问。整个后端可以通过sys挖苦的云服务来使用,也可以在私有云中部署,以获得更大的安全性和隔离性。该设计允许您避免运行一个系统来监视和另一个系统进行长期分析或数据保留。
如何在集装箱化的环境中启用故障排除
容器设计时都是小巧轻便的。 这对于可部署性和可重复性都是非常好的,但也会影响您对容器进行故障排除的方式。 还记得你的老朋友ssh、top、ps、ifconfig等吗?你可能不会把它们放在你的容器里。如果您在一个受控的PaaS环境中运行,即使这些工具是可用的,您也可能无法访问它,并且……我们提到的容器有的可能已经不存在了?如果协调器正在执行它的工作,那么在您进行故障排除之前,这个容器可能已经很久了。 简而言之,获取所需要的信息将会变得很复杂。除此之外,从协调器中获得适当的上下文是至关重要的。因此,让开发人员能够获得这些深入的信息是非常必要的,理想情况下不会破坏生产环境。必须解决这个问题,因为我们认为简化故障排除和对容器工作负载进行监控一样重要。 这就是开源Sysdig的容器故障排除工具。 它捕获主机上的每个单一系统调用的能力可以深入了解应用程序,容器,主机和网络的运行情况。 能够与业务流程管理对接,也就意味着它可以收集相关的元数据,以便您可以捕获分布式系统的上下文和状态,而不仅仅是单个机器的状态。
最后,Sysdig将所有内容全部捕获到文件中的功能意味着您可以从prod捕获数据,但可以在笔记本电脑上进行故障排除。
你可以在容器不在的时候做很久,当你的处境并不是非常紧急的时候,你可以做一个正确的事后分析。
例如,由于您在特定容器上看到大量的网络连接而收到警报, 我们的监控服务中的警报可以触发捕获,在该主机上记录所有系统调用一段时间。
探索在cSysdig中,您可以获取正确的容器上下文,然后深入其网络连接:
要了解开源sysdig可以做什么,请查看Kubernetes DNS服务的工作原理。
结论
构建一套高度可伸缩的分布式监控系统并不是一件容易的事情。不管你是选择自己做还是利用别人的系统,我相信您将不得不做出许多与我们一样的选择。 总的来说:
1.如何测量系统?
2.如何与协调器对接?
3.如何简化数据与自定义指标?
4.决定保留什么?
5.是否能够在动态的、短暂的环境中进行故障排除?
|