本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
为人类注解 Kubernetes 服务
您是否曾被要求排查出现故障的 Kubernetes 服务,却难以找到有关该服务的基本信息,例如源仓库和所有者?
随着 Kubernetes 应用程序的增长,其中一个问题是服务的泛滥。随着服务数量的增加,开发人员开始专注于处理特定服务。然而,在故障排除时,开发人员需要能够找到任何服务的来源、理解服务及其依赖项,并与拥有团队进行沟通。
人工服务发现
故障排除总是从信息收集开始。虽然人们对集中机器数据(例如日志、指标)给予了大量关注,但对服务发现的人工方面却关注甚少。谁拥有特定的服务?团队在哪个 Slack 频道上工作?服务的来源在哪里?目前已知并正在跟踪哪些问题?
Kubernetes 注解
Kubernetes 注解正是为解决这个问题而设计的。Kubernetes 注解经常被忽视,但它旨在为 Kubernetes 对象添加元数据。Kubernetes 文档指出,注解可以“将任意非标识性元数据附加到对象”。这意味着注解应该用于附加 Kubernetes 外部的元数据(即 Kubernetes 不会用于识别对象的元数据)。因此,注解可以包含任何类型的数据。这与标签形成对比,标签是为 Kubernetes 内部使用而设计的。因此,标签的结构和值受到约束,以便 Kubernetes 可以高效地使用它们。
Kubernetes 注解的实际应用
这里有一个例子。假设您有一个用于报价的 Kubernetes 服务,称为报价服务。您可以执行以下操作:
kubectl annotate service quote a8r.io/owner=”@sally”
在这个例子中,我们添加了一个名为 `a8r.io/owner` 的注解,其值为 `@sally`。现在,我们可以使用 `kubectl describe` 来获取信息。
Name: quote
Namespace: default
Labels: <none>
Annotations: a8r.io/owner: @sally
Selector: app=quote
Type: ClusterIP
IP: 10.109.142.131
Port: http 80/TCP
TargetPort: 8080/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>
如果您正在实践 GitOps(您应该这样做!),您会希望将这些值直接编码到您的 Kubernetes 清单中,例如:
apiVersion: v1
kind: Service
metadata:
name: quote
annotations:
a8r.io/owner: “@sally”
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: quote
注解的约定
采用通用的注解约定可确保一致性和可理解性。通常,您会将注解附加到服务对象,因为服务是与团队职责最清晰对应的高级资源。对注解进行命名空间划分也非常重要。以下是一组约定,记录在a8r.io,并转载如下
注解 | 描述 |
---|---|
a8r.io/description | 服务的非结构化文本描述,供人类阅读。 |
a8r.io/owner | SSO 用户名(GitHub)、电子邮件地址(链接到 GitHub 帐户)或非结构化所有者描述。 |
a8r.io/chat | Slack 频道或外部聊天系统链接。 |
a8r.io/bugs | 外部错误跟踪器链接。 |
a8r.io/logs | 外部日志查看器链接。 |
a8r.io/documentation | 外部项目文档链接。 |
a8r.io/repository | 外部 VCS 仓库链接。 |
a8r.io/support | 外部支持中心链接。 |
a8r.io/runbook | 外部项目运行手册链接。 |
a8r.io/incidents | 外部事件仪表板链接。 |
a8r.io/uptime | 外部运行时间仪表板链接。 |
a8r.io/performance | 外部性能仪表板链接。 |
a8r.io/dependencies | 服务的非结构化文本描述,供人类阅读。 |
注解可视化:服务目录
随着微服务和注解数量的激增,运行 `kubectl describe` 可能会变得繁琐。此外,使用 `kubectl describe` 要求每个开发人员都能够直接访问 Kubernetes 集群。在过去几年中,服务目录在 Kubernetes 生态系统中获得了更高的可见性。通过 Shopify 的 ServicesDB 和 Spotify 的 System Z 等工具的推广,服务目录成为了面向内部的开发者门户,提供了有关微服务的关键信息。
请注意,这些服务目录不应与Kubernetes 服务目录项目混淆。Kubernetes 服务目录基于开放服务代理 API 构建,使 Kubernetes 运营商能够将不同的服务(例如数据库)连接到其集群。
现在就为你的服务添加注解,以后你会感谢自己的
就像在微服务系统中实现可观测性一样,你常常直到为时已晚才意识到自己需要人工服务发现。不要等到生产环境中出现问题才开始希望自己能够实现更好的度量,并记录下如何联系负责该部分的组织。
构建一个有效的“版本 0”服务具有巨大的优势:一个跳舞的骨架应用程序,具有一小部分完整的功能,可以通过最小但有效的持续交付管道部署到生产环境。
添加服务注解应该成为所有服务的“版本 0”的重要组成部分。现在就添加它们,以后你会感谢自己的。