作者:Richard Li,Ambassador Labs
你是否曾经被要求对出现故障的 Kubernetes 服务进行故障诊断,并努力寻找有关该服务的基本信息,如源仓库和所有者?
随着 Kubernetes 应用程序的增长,其中一个问题是服务的扩散。随着服务数量的增长,开发人员开始专门处理特定的服务。然而,当涉及故障排除时,开发人员需要能够找到源,了解服务和依赖关系,并与拥有任何服务的团队交谈。
故障排除总是从信息收集开始。在集中机器数据(如日志、指标)的同时,对服务发现的人员方面的关注却少得多。谁拥有一个特定的服务?团队在哪个 Slack 频道工作?服务的源在哪里?目前已知并正在跟踪的问题是什么?
Kubernetes 注释就是为解决这个问题而设计的。经常被忽视的是,Kubernetes 注释的设计目的是向 Kubernetes 对象添加元数据。Kubernetes 文档说,注释可以“将任意的非识别元数据附加到对象上”。这意味着应该使用注释来附加 Kubernetes 外部的元数据(即 Kubernetes 不会用于标识对象的元数据)。因此,注释可以包含任何类型的数据。这与标签形成了对比,标签是为 Kubernetes 内部使用而设计的。因此,标签结构和值受到限制,以便 Kubernetes 能够有效地使用它们。
下面是一个例子。假设你有一个用于 quoting 的 Kubernetes 服务,称为 quote 服务。你可以这样做:
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,转载如下:
Annotation | Description |
---|---|
a8r.io/description | Unstructured text description of the service for humans. |
a8r.io/owner | SSO username (GitHub), email address (linked to GitHub account), or unstructured owner description. |
a8r.io/chat | Slack channel, or link to external chat system. |
a8r.io/bugs | Link to external bug tracker. |
a8r.io/logs | Link to external log viewer. |
a8r.io/documentation | Link to external project documentation. |
a8r.io/repository | Link to external VCS repository. |
a8r.io/support | Link to external support center. |
a8r.io/runbook | Link to external project runbook. |
a8r.io/incidents | Link to external incident dashboard. |
a8r.io/uptime | Link to external uptime dashboard. |
a8r.io/performance | Link to external performance dashboard. |
a8r.io/dependencies | Unstructured text describing the service dependencies for humans. |
随着微服务和注释数量的激增,运行 kubectl describe 可能会变得冗长乏味。而且,使用 kubectl describe 要求每个开发人员都能直接访问 Kubernetes 集群。在过去的几年中,服务目录在 Kubernetes 生态系统中获得了更大的曝光度。随着Shopify 的 ServicesDB[1]和Spotify 的 System Z[2]等工具的普及,服务目录是面向开发者的内部门户,提供有关微服务的关键信息。
请注意,不应将这些服务目录与Kubernetes 服务目录项目[3]混淆。Kubernetes 服务目录建立在开放服务代理 API 的基础上,使 Kubernetes 的操作人员能够将不同的服务(如数据库)插入到他们的集群中。
就像在微服务系统中实现可观察性一样,当你意识到需要人员服务发现时,往往为时已晚。不要等到生产中某些事情发生时才开始希望自己一早应该实现了更好的指标,并记录了如何与管理它的组织部门取得联系。
构建一个有效的“0 版本”服务有巨大的好处:这里有一个骨架应用程序[4],具有完整的基本功能,可以通过最小但有效的连续交付流水线部署到生产环境中。
添加服务注释应该是所有服务的“0 版本”的重要部分。现在就添加它们,以后你会感谢自己的。