这篇文章发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不再正确。

为人类注释 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/ownerSSO 用户名 (GitHub)、电子邮件地址(链接到 GitHub 帐户)或非结构化的所有者描述。
a8r.io/chatSlack 频道,或指向外部聊天系统的链接。
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 的 ServicesDBSpotify 的 System Z 等工具推广,它们是面向内部的开发人员门户,提供有关微服务的关键信息。

请注意,这些服务目录不应与 Kubernetes 服务目录项目混淆。Kubernetes 服务目录基于 Open Service Broker API 构建,使 Kubernetes 运营商能够将不同的服务(例如,数据库)插入到其集群中。

立即注解你的服务,以后你会感谢自己

就像在微服务系统中实现可观察性一样,你往往不会意识到自己需要人工服务发现,直到为时已晚。不要等到生产环境出现问题时才开始希望你已经实施了更好的指标,并记录了如何与你的组织中负责该部分的人员联系。

构建有效的“版本 0”服务有巨大的好处:一个跳舞的骨架应用程序,具有一小部分完整的功能,可以使用最少但有效的持续交付管道部署到生产环境。

添加服务注解应该成为所有服务“版本 0”的重要组成部分。现在添加它们,以后你会感谢自己。