Rockset的Kubernetes
在Rockset,我们使用Kubernetes(k8s)进行集群编排。它运行我们所有的生产微服务-从我们的提取工人到我们的查询服务层。除了托管所有生产基础架构之外,每位工程师还拥有自己的Kubernetes命名空间和专用资源,我们可以使用它们在本地部署和测试新版本的代码和配置。这种沙盒开发环境使我们每周可以放心地多次发布软件。在此博客文章中,我们将探索内部构建的工具,该工具可让我们查看Kubernetes事件,这是有关系统状态的极好信息源,我们发现该工具有助于对系统进行故障排除和了解其长期运行状况。
为什么我们关心Kubernetes Events?
只要它管理的任何资源发生任何更改,Kubernetes都会发出事件。这些事件通常包含有关触发它的实体的重要元数据,事件的类型(正常,警告,错误等)以及原因。此数据通常存储在etcd中,并在您运行某些kubectl命令时可用。
$ kubectl describe pods jobworker-c5dc75db8-7m5ln
...
...
...
Events: Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m default-scheduler Successfully assigned master/jobworker-c5dc75db8-7m5ln to ip-10-202-41-139.us-west-2.compute.internal
Normal Pulling 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal pulling image "..."
Normal Pulled 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Successfully pulled image "..."
Normal Created 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Created container
Normal Started 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Started container
Warning Unhealthy 2m (x2 over 2m) kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Readiness probe failed: Get http://XXX.XXX.XXX.XXX:YYY/healthz: dial tcp connect: connection refused
这些事件有助于了解特定实体进入特定状态时幕后发生的情况。查看所有事件的汇总列表的另一个地方是通过kubectl get事件访问所有事件。
$ kubectl get events
LAST SEEN TYPE REASON KIND MESSAGE
5m Normal Scheduled Pod Successfully assigned master/jobworker-c5dc75db8-7m5ln to ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal
5m Normal Pulling Pod pulling image "..."
4m Normal Pulled Pod Successfully pulled image "..." ...
...
从上面可以看出,这为我们提供了详细信息-发出事件的实体,事件的类型/严重性以及触发事件的原因。当希望了解系统中正在发生的更改时,此信息非常有用。这些事件的另一种用途是了解长期系统性能和可靠性。例如,导致Pod重新启动的某些节点和网络错误可能不会在高可用性设置中引起服务中断,但通常可能掩盖了使系统面临更大风险的潜在条件。
在默认的Kubernetes设置中,事件被持久保存到键值存储etcd中。 etcd已针对快速快速一致的查询进行了优化,但不足以提供对数据的分析能力。随着大小的增长,etcd也难以跟上,因此,事件会定期压缩和清理。默认情况下,etcd仅保留过去一小时的事件。
历史背景可用于了解集群的长期健康状况,过去发生的事件以及在Kubernetes中采取的缓解它们的措施,并建立准确的事后统计。尽管我们研究了事件的其他监视工具,但我们意识到我们有机会使用自己的产品来分析这些事件,而其他监视产品则无法使用这种方法,并使用它来构建我们所有状态的可视化Kubernetes资源。
预览
为了提取Kubernetes事件,我们使用了Heptio的开源工具eventrouter。它从Kubernetes API服务器读取事件,并将其转发到指定的接收器。接收器可以是从Amazon S3到任意HTTP端点的任何内容。为了连接到Rockset集合,我们决定为eventrouter构建一个Rockset连接器,以控制上传到我们的集合的数据的格式。我们将此Rockset接收器贡献到了上游eventrouter项目中。这个连接器非常简单-它接收所有接收到的事件并将它们发送到Rockset中。真正很酷的部分是,对于摄取这些事件(它们是随不同类型的实体而变化的JSON有效负载),我们不需要构建任何架构或进行结构转换。我们可以按原样将JSON事件发送到Rockset集合中,并对其进行查询,就好像它是完整的SQL表一样。 Rockset首先通过使用聚合索引为所有json字段建立索引,然后通过Smart Schema自动对其进行模式化,从而将JSON事件自动转换为SQL表。
前端应用程序是SQL层上的薄层,它允许按名称空间和实体类型(Pod,Deployment等)过滤事件,然后在这些实体类型内按正常/错误过滤事件。目的是使这些事件具有直方图,以便在较长的时间内直观地检查和了解群集的状态。当然,我们展示的内容只是可以构建的内容的一个子集-人们可以想象更复杂的分析-例如分析网络稳定性,部署过程,发布软件版本,甚至使用事件存储作为关键诊断工具来发现之间的相互关系集群级别的警报和Kubernetes级别的更改。
安装
在开始从eventrouter接收事件到Rockset之前,我们必须在Rockset中创建一个集合。这是所有eventrouter事件都存储在的集合。您可以使用免费帐户https://console.rockset.com/c...。
Rockset中的集合可以从指定来源获取数据,也可以通过REST API发送事件。 API”作为数据源来创建这样的集合。
创建集合时,我们可以选择一个保留期(例如120天)或任何合理的时间,以使我们对集群的运行状况有所了解。此保留时间是根据Rockset _event_time中的特殊字段应用的。我们会将这个字段映射到JSON事件有效负载中的特定字段,该事件将从事件路由器收到,称为event.lastTimestamp。转换函数如下所示:
UNIX_MILLIS(PARSE_TIMESTAMP_ISO8601(event.lastTimestamp))
创建集合后,我们现在可以设置并使用eventrouter来开始接收Kubernetes事件。
现在,从eventrouter接收事件还需要做一件事-Rockset API密钥。我们可以在Rockset中使用API密钥将JSON写入集合并进行查询。在这种情况下,我们从“管理”>“ API密钥”创建一个名为eventrouter_write的API密钥。
复制API密钥,因为在下一步设置eventrouter时将需要它,以将事件发送到我们刚刚设置的Rockset集合中。您可以通过克隆eventrouter存储库来设置eventrouter,然后将YAML文件 yaml/deployment。
# eventrouter/yaml/deployment.yaml
config.json: |-
{
"sink": "rockset"
"rocksetServer": "https://api.rs2.usw2.rockset.com",
"rocksetAPIKey": "<API_KEY>",
"rocksetCollectionName": "eventrouter_events",
"rocksetWorkspaceName": "commons",
}
您可以将<API_KEY>替换为我们在上一步中刚刚创建的Rockset API密钥。现在,我们准备好了!运行kubectl apply -f yaml / deployment.yaml,eventrouter可以立即开始监视和转发事件。查看Rockset中的集合,您应该开始看到流入的事件并可以作为SQL表使用。我们可以从Rockset控制台中查询它,如下所示,并了解一些流入的事件。我们可以在它上面运行完整的SQL,包括所有类型的过滤器,联接等。
查询数据
现在,我们可以开始从集群中提出一些有趣的问题,并了解集群的运行状况。我们要问的一个问题是-我们多久将一次新映像部署到生产中。我们按照严格的发布时间表进行操作,但是有时会退出和回滚镜像。
上面的查询处理了我们的部署,部署又创建了副本集并找到了部署特定镜像的最后日期。
这张带有时间戳的镜像和Pod摘录,向我们介绍了最后几次部署及其发生的时间。将其绘制在图表上将告诉我们有关部署的一致性以及部署实践的健康程度。
现在,继续提高群集本身的性能,运行我们自己的手动Kubernetes群集意味着我们可以对升级和系统设置进行大量控制,但是值得一看的是何时节点可能丢失/网络分区导致节点丢失标记为未就绪。这些事件的聚类可以告诉我们很多有关基础结构的稳定性。
该查询为我们提供了节点状态变为“未就绪”的时间,我们可以尝试使用SQL时间函数对数据进行聚类,以了解在特定时间段内发生问题的频率。
我们还可以查找pod和容器级事件,例如它们何时发生OOMKilled并将其与系统中发生的其他事件相关联。与诸如Prometheus之类的时间序列数据库相比,SQL的强大功能使我们可以编写和加入不同类型的事件,以尝试将在特定时间间隔内发生的不同事情组合在一起,这可能是因果关系。
为了可视化事件,我们构建了一个使用React的简单工具,我们在内部使用它来浏览并进行Kubernetes事件及其中发生的错误的一些基本聚类。我们正在将此仪表板发布为开源,并希望了解社区可能将其用作什么。 Kubernetes事件的可视化有两个主要方面。首先是对每个资源的粒度的群集的高级概述。这使我们能够查看来自部署和Pod的实时事件流,并查看Kubernetes系统中每个资源的状态。还有一个按名称空间过滤的选项-因为某些服务集在它们自己的名称空间中运行,这使我们能够深入到特定的名称空间来查看事件。
如果我们对任何特定资源的运行状况和状态感兴趣,则可以单击每个每个资源的摘要,并打开一个页面,其中包含该资源的事件日志的详细概述,并带有一个图表,该图表显示了随时间推移的事件和错误,以提供有关如何管理资源的整体图。
此可视化中的图形具有可调的粒度,并且时间范围的更改允许在任何指定的时间间隔内查看给定资源的事件。将鼠标悬停在堆叠条形图上的特定条形上,使我们可以查看在该时间段内发生的错误类型,以帮助您对特定资源正在发生的情况进行超时分析。该图下方列出的事件表按事件时间排序,还告诉您包含与该图相同的信息-也就是说,按时间顺序概述了此特定k8s资源发生的所有事件。图形和表格是了解Kubernetes资源过去为何失败以及该失败可能伴随时间的任何趋势(例如,如果它与新的微服务的发布同时发生)的有用的方式。
结论
当前,我们正在使用事件的实时可视化来研究我们自己在开发和生产中的Kubernetes部署。该工具和数据源使我们能够查看正在进行的部署,而无需纠缠kubectl界面来查看损坏的原因。此外,此工具有助于回顾过去的事件。例如-如果我们发现了瞬态问题,那么我们现在可以及时回顾过去,回顾一下瞬态生产问题,找到可能发生的原因的模式,以及我们可以采取的措施来防止再次发生该事件。在将来。
能够以精细的粒度访问历史Kubernetes事件日志的功能是一种强大的抽象,它使Rockset能够比单独使用kubectl更好地了解我们的Kubernetes系统状态。这种独特的数据源和可视化功能使我们能够监视我们的部署和资源,并从历史角度查看问题。如果您发现它在您自己的环境中有用,我们很乐意尝试并做出贡献!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。