工程

元数据在 Kubernetes 可观测性计划中的重要性

本博文最初发布于 tfir.io

Kubernetes 作为热门的容器编排系统,一直是“云原生计算基金会”项目的核心。它能够自动完成容器、容器化应用程序和“pod”(包含一个或多个容器的组)的部署、生命周期和运行。该平台本身以及这些工作负载都可能生成事件数据,而且与这些过程相关的数据多种多样。日志可以是简单的故障排查消息“yep, got here”,也可以是提供事务信息的详细 Web 服务器访问日志。指标或时序数据都是以固定时间间隔测量的数值。例如,每秒即时操作数、缓存命中率、访问您网站的客户数,或者诸如容器在过去 5 秒钟内使用了多少 CPU 或内存等这样的基本信息。

可观测性获取这些日志和指标,并让它们通常在相关的数据存储中变得可搜索,而且经常与应用程序跟踪数据结合使用。通过这些跟踪数据或详细的应用程序性能监测 (APM) 信息,可了解应用程序或服务在哪些位置运行,以何种方式与哪些内容进行了交互,以及遇到了哪些错误。日志和指标提供了应用程序的黑盒视图,而 APM 数据则显示了应用程序内部的情况。  

将日志、指标和应用程序跟踪数据结合使用,有助于缩短检测和解决错误或事件的平均时间,但随着应用程序部署模型的发展(就像 Kubernetes 部署一样),了解动态环境中实际发生的事情变得非常重要。这就是元数据可以发挥作用的时候了。

究竟什么元数据呢?

按照 Webster 的定义,元数据是“针对其他数据提供相关信息的数据”。 听起来很简单,对吧?有许多常见的地方都有元数据的影子,例如,托管这篇博文的页面就有元数据,里面的 SEO 标签、帮助不同浏览器设置正确页面格式的提示,以及帮助描述页面的关键字,这些都是元数据。同样,移动设备上的一张图片也有一大堆的元数据 — 以下只是其中一个片段:

ExifTool Version Number         :11.11 
File Name                       :60398459048__A20828DD-FAA4-4133-BA1F-059DEC9E7332.jpeg 
Directory                       : .
File Size                       :2.8 MB 
File Modification Date/Time     :2020:02:21 08:30:01-05:00 
File Access Date/Time           :2020:02:21 08:30:23-05:00 
File Inode Change Date/Time     :2020:02:21 08:30:22-05:00 
MIME Type                       : image/jpeg 
JFIF Version                    :1.01 
Acceleration Vector             : -0.03239090369 -0.9104139204 -0.3862404525 
Exif Byte Order                 :Big-endian (Motorola, MM) 
Make                            :Apple 
Camera Model Name               : iPhone XS 
Orientation                     :Rotate 90 CW 
X Resolution                    :72 
Y Resolution                    :72 
Exif Image Width                :4032 
Exif Image Height               :3024

您可能会问,“知道 iPhone 图片的 MIME 类型对我的可观测性计划有什么帮助?”它是没有帮助,因为图像元数据的用途不在于此,但这应该会让您了解元数据带来了什么样的信息。iPhone 元数据可让您根据大小、方向或者拍照时的摇晃程度(显然这方面我还得加把劲)进行筛选。让我们来看看可以帮助您关联和导航可观测性数据的一些信息,也就是来自您环境的日志、指标和应用程序跟踪数据。  

软件和硬件部署趋势

在单一数据中心的单一用途、裸机服务器上运行单体式应用程序的辉煌时代已经一去不复返了。当然,我们仍然可以看到运行专用工作负载的它们,这并没有什么问题;许多大型应用程序和产品都需要尽可能多的计算能力。但是,总体而言,软件和硬件部署模型的行业趋势正在朝着微服务和容器发展。

trends-increasingly-complex-systems.png

这种“向右转”的趋势并不是什么爆炸性新闻。许多公司都拥有多个并行工作的软件部署模型,同时还有多种硬件模式。虚拟机或云实例运行客户端/服务器或 SOA 应用程序,而容器运行由 Kubernetes 或 Docker 编排的微服务镜像。在很多情况下,一种部署模型中的应用程序和服务会利用另一种部署模型中的服务 — 那个花哨的新微服务也说不定仍在使用托管在裸机上的数据库。

这些异构系统的性质使得元数据变得更加重要。随着我们逐渐转向容器、pod 和动态调度的微服务,以后走进数据中心,您就很难肯定地指着一台服务器说“我的应用程序就在那台服务器上”。 因为您的应用程序可能在那里,但可能位于您身后的其他四台服务器上。 

这就是定位元数据发挥作用的地方。我说的不是经纬度(尽管这样比喻可能很方便),而是一个寻址方案,它至少可让您从逻辑上看到一段数据(无论是日志、指标还是应用程序跟踪数据)的来源。  

基础架构的特点

定位,定位,还是定位

您所需要的内容会根据您的设置而有所不同,但您应该为未来做好计划。您可以捕获的数量将取决于给定的作业运行在什么上面,如果是裸机上的单体式应用程序,您就不会捕获 Kubernetes pod 的详细信息,这很好。我们基本上想提供面包屑导航,以便我们能够看到应用在哪里运行。我们一会儿就知道原因了。

通过定位,我们可以找到元数据的层次结构,直到应用程序级别,也就是作业实际运行的地方。  

数据中心

数据中心元数据应包括每个数据中心的唯一标识符,例如城市名称。当谈论云服务提供商时,这些信息可能会有些模糊,但也有一些可类比的情况。在这种情况下,我们可以利用云服务提供商和我们运行所在的区域,例如 GCP,europe-west1 和可用性区域 b。

如果您的数据中心有专用层(可能是为生产或测试预留的特定主机,或者是跨项目划分的),请确保也将其添加到元数据中。  专用层有点像数据中心的隔离部分,或数据中心内的数据中心。

主机信息

无论我们是在裸机、虚拟机还是云实例上运行,我们都会定期获得一些主机信息。每个主机都具有以下属性:主机名、IP 地址、硬件模型或实例类型、配置的 RAM 和存储,甚至操作系统信息。您甚至可以包含更详细的信息,例如,这台主机所在的位置 — 数据中心的楼层号、哪个机架、哪一排、哪一个搁板。这已经不是第一次整个机架因电源或布线不良而受到影响了!

应用程序详情

现在,我们已经有了足够的信息来确定每个设备的运行位置,但也只限于主机级别,而且每个主机可能会运行各种不同的服务或应用程序。当我们开始谈到应用程序和服务时,我们就需要添加相应级别的元数据了。说到这里,事情会变得有些复杂,所以我们长话短说,开始使用 Kubernetes 编排的微服务来处理更复杂的场景。将微服务应用于裸机应用程序和虚拟化环境应该是非常简单的。

Kubernetes 和 Docker 中的容器会自动带有一定级别的可用元数据,这些元数据应该包括在内。至少我们要包括容器和/或 pod 名称、用作容器基础的镜像和版本,以及开始时间。理想情况下,我们还将包括网络名称和 IP 信息,以及任何网络、内存或存储配额。是不是注意到与主机信息有一些相似之处?容器和虚拟机基本上是在另一个主机上运行的主机,因此我们要提取相同的信息是有道理的。

也就是说,在虚拟化环境中运行时,我们可以进行相同的类比。虚拟主机将具有与主机相同的概要详细信息:名称、IP 地址、内存和存储限制。

在这一点上,我们有一个难题:我们有一些重复的字段名。重要的是要记住,我们要保持一个层次结构。在该层次结构中,主机元数据高于容器或虚拟机:

├── NYC DC 1 
│   ├── Host 1 
│   │   ├── vm 1 
│   │   ├── vm 2 
│   │   └── vm 3 
│   └── Host 2 
│       ├── vm 1 
│       └── vm 2 
└── NYC DC 2 
    └── Host 1 
        ├── vm 1 
        ├── vm 2 
        ├── vm 3 
        └── vm 4

很明显,基于这一点,我们需要将这些值放在不同的、可预测的命名空间中,以确保这些名称不会发生冲突。一个很好的方法是将它们作为键/值对传递;例如,在我们的 NYC DC 1 中,Host 1 上 vm 2 的元数据可能包括:

dc.name:"NYC DC 1" 
dc.floor:2 
 
host.name: "Host 1" 
host.IP: … 
host.available_memory_mb:16384 
vm.name: "vm 1" 
vm.IP: …

说到层次结构时,容器会有点不一样,因为一个 Kubernetes 集群可以跨多个主机。在这种情况下,如上所述,我们不仅关心给定 pod 或容器的位置信息,还关心相应的编排元数据。接下来,我们将了解元数据如何帮助我们更好地观测应用程序。

应用程序可观测性

至此,我们已经知道了如何完全解决系统中运行的问题,下面我们开始讨论收集实际数据(回想一下:元数据是描述其他数据的数据)。“可观测性的三大支柱”是日志、指标和应用程序跟踪数据(也称为 APM 数据),有时将运行时间数据视为第四个“支柱”。 如下图所示,在收集日志和指标时,我们要在生态系统的每一层收集数据,其中包括关于应为每个抽象层收集哪些类型的可观测性数据的信息:

what-to-monitor.png

例如,我们要从数据中心的每个主机或网络元素收集日志、指标和可用性数据,但要为应用程序和服务添加 APM。

我们通过为每一层添加相应的元数据,丰富上述所有内容,以提高应用程序、基础架构和整个生态系统的可见性。有很多方法可以实现这一点 — 我们可以将元数据与每个事件或跟踪一起发送,从而实现快速搜索和筛选,或者通过存储我们生态系统静态部分的元数据,供以后进行交叉引用。尽管后一种方法可以节省一些空间,但存在过时的风险,尤其是在动态生态系统中。

将上面这些碎片信息拼凑在一起

有了通过元数据得到进一步丰富的可观测性数据,我们可以基于我们选择的方面进行分片和切块,而不仅仅局限于查看特定的 APM 数据或日志。例如,我们可以细分每个主机、每个服务的当前 CPU 利用率:

infra-viewer.png

或者观察同一参数在一段时间内的变化情况:

metrics-explorer.png

这样一来,我们就可以挑选出想要细究的细节,回答我们之前无法回答的一些问题,例如:

  • 与我的 EMEA 数据中心相比,我的美国数据中心是否过度利用?
  • 在我的生态系统中,是否有哪个机架遇到的错误比其他机架都要多?
  • 我能略微改动一些开发基础架构以便投入生产吗?
  • 我的电子商务应用的容器和 pod 运行在哪些物理主机上?
  • 最后,为什么我的 iPhone 图片总模糊不清?

总结

元数据能够为您的分析增加新的维度,提供聚合、分片和切块数据的新方法,有助于回答您的业务和运营问题。确保您用于可观测性计划的解决方案可与您的业务一起成长,同时考虑到了可搜索和可导航的元数据,例如 Elastic Common Schema,这样您就可以确保元数据最终出现在您需要的位置。