mcpField
D
dt-obs-kubernetes

dt-obs-kubernetes

github.com/dynatrace云与 DevOps1692.6k 次安装今天更新
代码仓库

关于 dt-obs-kubernetes

dt-obs-kubernetes 是使用 Dynatrace DQL 监控和分析 Kubernetes 基础设施的 Skill,适用于集群与工作负载运维。它涵盖资源使用、调度、成本及安全检查,并结合指标与事件排查问题。

主要功能

  1. 01查询集群、节点、Pod 和工作负载
  2. 02监控 CPU、内存及重启等指标
  3. 03结合 Kubernetes 事件排查故障
  4. 04分析 Pod 调度与节点放置
  5. 05检查资源成本和安全配置

适用场景

  1. 01检查集群健康和节点容量
  2. 02调查 OOMKill、驱逐及重启
  3. 03定位部署退化或调度失败
  4. 04发现资源过度配置和特权容器

MCP 相关

文档提及 Dynatrace MCP 工具 get-events-for-kubernetes-cluster,用于查询 Kubernetes 集群事件。必要时也可使用 DQL 查询 events。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-obs-kubernetes

安装后在 Claude Code 中输入/dt-obs-kubernetes确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
cluster-inventory.md
ingress.md
labels-annotations.md
network-policies.md
pod-debugging.md
pod-node-placement.md
pv-pvc.md
workload-health.md

详细介绍

Infrastructure Kubernetes

使用 Dynatrace DQL 监控和分析 Kubernetes 基础设施。查询集群资源、监控工作负载运行状况、分析 Pod 放置情况、优化成本并评估安全态势。

何时使用此技能

  • 监控 Kubernetes 集群的运行状况和容量
  • 分析 Pod 和容器的资源利用率
  • 调查 Pod 故障、OOMKill、驱逐或崩溃循环
  • 调试性能下降的部署、卡住的发布或节点压力问题
  • 优化 Kubernetes 资源成本
  • 评估安全态势和合规性
  • 排查工作负载调度和放置问题
  • 审核 Ingress 路由和网络策略

知识库结构

核心监控(从这里开始)
  1. 集群清单 → references/cluster-inventory.md - 集群、 命名空间、资源分布
  2. 节点监控 - 节点容量、CPU/内存使用量、Pod 密度
  3. Pod 监控 - Pod CPU、内存、生命周期事件
  4. 工作负载监控 - Deployment、StatefulSet、DaemonSet 资源
高级主题
  1. 配置分析 → references/labels-annotations.md - 解析 k8s.object、标签、注解
  2. 调度与放置 → references/pod-node-placement.md - 节点 选择器、亲和性、污点、高可用性
  3. 成本优化 - 适当调整规格、检测资源浪费、效率评分
  4. 安全与合规性 - 特权容器、安全上下文

核心概念

实体类型

工作负载: K8S_DEPLOYMENT、K8S_STATEFULSET、K8S_DAEMONSET、 K8S_JOB、K8S_CRONJOB、K8S_HORIZONTALPODAUTOSCALER
基础设施: K8S_CLUSTER、K8S_NAMESPACE、K8S_NODE、K8S_POD
配置: K8S_SERVICE、K8S_CONFIGMAP、K8S_SECRET、 K8S_PERSISTENTVOLUMECLAIM、K8S_PERSISTENTVOLUME、K8S_INGRESS、 K8S_NETWORKPOLICY

注意: HPA、Job、CronJob 和配置实体类型仅用于清单查询。如需分析 HPA 扩缩容,请参阅 references/workload-health.md; 如需了解 PVC/PV,请参阅 references/pv-pvc.md;如需了解 Ingress/NetworkPolicy,请参阅 对应的参考文件。

查询类型

smartscapeNodes - 查询 K8s 实体(当前状态,无需时间范围):

smartscapeNodes K8S_POD
| filter k8s.namespace.name == "production"
| fields k8s.cluster.name, k8s.pod.name

timeseries - 监控一段时间内的指标(始终指定 from: 范围):

timeseries cpu = sum(dt.kubernetes.container.cpu_usage),
  by: {k8s.pod.name, k8s.namespace.name},
  from: now()-1h
| fieldsAdd avg_cpu = arrayAvg(cpu)

timeseries 会将每个指标作为时间桶数组返回。若要在下游的 fieldsAdd 中将其折叠为标量,请使用 arrayAvg(series) 或 arraySum(series) — 不支持在 timeseries {} 块外对 series 字段调用 avg() 或 sum()。

fetch logs - 分析日志事件:

fetch logs
| filter k8s.namespace.name == "production" and loglevel == "ERROR"
核心字段
  • k8s.cluster.name、k8s.namespace.name、k8s.pod.name、k8s.node.name
  • k8s.workload.name、k8s.workload.kind、k8s.container.name
  • k8s.object - 用于深入检查的完整 JSON 配置
  • tags[label] - 访问标签和注解

k8s.workload.kind 的值(在 DT 中始终为小写,与 K8s API 中的 Pascal 命名法不同): "deployment"、"statefulset"、"daemonset"、"replicaset"、"job"、"cronjob"

k8s.object 的可用性:

实体类型k8s.object 是否可用?
K8S_POD是
K8S_NAMESPACE是
K8S_NODE是
工作负载类型(K8S_DEPLOYMENT 等)是
K8S_CLUSTER否
可用指标

CPU: dt.kubernetes.container.cpu_usage、cpu_throttled、limits_cpu、 requests_cpu
内存: dt.kubernetes.container.memory_working_set、limits_memory、 requests_memory
操作: dt.kubernetes.container.restarts、oom_kills
节点: dt.kubernetes.node.pods_allocatable、cpu_allocatable、 memory_allocatable、dt.kubernetes.pods

requests/limits 的聚合规则: 聚合 requests_cpu、limits_cpu、requests_memory 或 limits_memory 时,始终使用 sum(),切勿使用 avg()。 avg() 返回的是每个容器的平均值,会在多容器 Pod 和多副本工作负载中无声地低估总量。对于 DaemonSet (每个节点一个 Pod),这种误差与集群规模成正比。

实体消歧

K8S_POD 与 CONTAINER:它们在 Dynatrace 中是不同的实体类型。

  • K8S_POD — Kubernetes 原生实体,包含 k8s.object JSON、调度状态、条件和 Kubernetes 指标。使用此技能。
  • CONTAINER — 主机级容器清单(镜像、生命周期、主机分配)。请改用 dt-obs-hosts 技能。

smartscape 边为 CONTAINER --(is_part_of)--> K8S_POD。要从 Pod 找到容器,请反向遍历:

smartscapeNodes K8S_POD
| filter k8s.namespace.name == "<namespace>"
| traverse edgeTypes: {is_part_of}, targetTypes: {CONTAINER}, direction: backward, fieldsKeep: {id}
| fields k8s.cluster.name, k8s.namespace.name, k8s.pod.name, container.id=id
Service → K8S_POD 关联

SERVICE 和 K8S_POD 之间不存在直接的 smartscape 边。关联键是共享维度 k8s.workload.name。完整的两步模式请参阅 references/pod-debugging.md 中的 Service → Pod 下钻。

常见工作流

1. 集群健康检查

列出所有集群:

smartscapeNodes K8S_CLUSTER
| fields k8s.cluster.name, k8s.cluster.version, k8s.cluster.distribution

检查节点容量:

timeseries {
  current_pods = avg(dt.kubernetes.pods),
  max_pods = avg(dt.kubernetes.node.pods_allocatable)
}, by: {k8s.node.name, k8s.cluster.name},
from: now()-1h
| fieldsAdd pod_capacity_pct = (arrayAvg(current_pods) / arrayAvg(max_pods)) * 100
| filter pod_capacity_pct > 80

识别处于非 Running 状态的 Pod:

smartscapeNodes K8S_POD
| parse k8s.object, "JSON:config"
| fieldsAdd phase = config[status][phase]
| filter not(in(phase, {"Running", "Succeeded"}))
| fields k8s.cluster.name, k8s.namespace.name, k8s.pod.name, phase

对于已完成的 Job Pod,Succeeded 是正常的终态 — 排除它可避免误报。若要专门审计已完成的 Job,请相应调整。

2. 资源优化

Pod 级别 — 查找资源配置过高的 Pod(使用率 < 30%):

timeseries {
  cpu_usage = sum(dt.kubernetes.container.cpu_usage),
  cpu_requests = sum(dt.kubernetes.container.requests_cpu)
}, by: {k8s.pod.name, k8s.namespace.name, k8s.cluster.name},
from: now()-7d
| fieldsAdd usage_pct = (arrayAvg(cpu_usage) / arrayAvg(cpu_requests)) * 100
| filter usage_pct < 30 and arrayAvg(cpu_requests) > 0

工作负载级别 — 汇总所有副本(正确统计 DaemonSet 时必须如此):

timeseries {
  cpu_usage = sum(dt.kubernetes.container.cpu_usage),
  cpu_requests = sum(dt.kubernetes.container.requests_cpu)
}, by: {k8s.workload.name, k8s.workload.kind, k8s.namespace.name, k8s.cluster.name},
from: now()-7d
| fieldsAdd
    avg_usage = arrayAvg(cpu_usage),
    avg_requests = arrayAvg(cpu_requests)
| fieldsAdd usage_pct = (avg_usage / avg_requests) * 100
| filter usage_pct < 30 and avg_requests > 0
| sort usage_pct asc

在每个聚合级别上,cpu_usage 和 cpu_requests 都要使用 sum()。 在 50 个节点上运行的 DaemonSet,其 Pod 请求总量是单个 Pod 请求量的 50 倍;使用 avg() 会将报告的预留容量低估至真实值的 1/50。

识别未设置 limits 的容器:

smartscapeNodes K8S_POD
| parse k8s.object, "JSON:config"
| expand container = config[spec][containers]
| fieldsAdd
    container_name = container[name],
    cpu_limit = container[resources][limits][cpu],
    memory_limit = container[resources][limits][memory]
| filter isNull(cpu_limit) or isNull(memory_limit)
3. 排查 Pod 问题

将指标(时间序列)与 Kubernetes 事件(事件流)结合起来,有助于全面排查 Pod 问题。

基于指标的故障排查

查找发生 OOMKill 的 Pod:

timeseries oom_kills = sum(dt.kubernetes.container.oom_kills),
  by: {k8s.pod.name, k8s.namespace.name, k8s.cluster.name},
  from: now()-1h
| filter arraySum(oom_kills) > 0
| fieldsAdd total_oom_kills = arraySum(oom_kills)
| sort total_oom_kills desc

分析 Pod 重启模式:

timeseries restarts = sum(dt.kubernetes.container.restarts),
  by: {k8s.pod.name, k8s.namespace.name, k8s.cluster.name},
  from: now()-1h
| fieldsAdd total_restarts = arraySum(restarts)
| filter total_restarts > 5
基于事件的故障排查

对于运维事件(Pod 重启、OOM 杀死、驱逐、调度失败),Kubernetes 事件能提供比单纯指标更丰富的上下文,包括事件原因、消息和时间戳。

优先使用 Kubernetes 事件而非指标的情况:

  • 用户询问近期运维事件(“显示 Pod 重启事件”)
  • 用户想了解事件详情,例如原因和消息
  • 用户询问特定时间范围内的事件(“过去 48 小时”)
  • 用户想将事件与根本原因关联起来

Kubernetes 事件可通过 get-events-for-kubernetes-cluster 工具(Dynatrace MCP 工具)获取。调用时,将 findAllK8Events 设为 true 可获取所有集群的事件;设为 false 并提供 clusterId(k8s.cluster.uid)或 kubernetesEntityId(dt.entity.kubernetes_cluster),可限定为单个集群。使用 history 设置回溯时间范围(例如 "1h"、"24h"、"7d";最长为 "60d")。 用户询问 OOM 事件、Pod 重启、驱逐或集群级事件历史时,优先使用此工具。如果该工具不可用,则使用下方的 fetch events DQL 模式。

重要:筛选结果时要区分事件类型。 Kubernetes 事件涵盖多种类别。用户询问特定事件类型时,应相应筛选结果,不要报告无关事件:

用户询问相关事件原因无关事件
Pod 重启BackOff、CrashLoopBackOff、Killing就绪探针失败、CPU 限流
OOM 事件OOMKilling、OOMKilled内存压力警告
驱逐Evicted、Preempting节点压力
调度失败FailedScheduling、Unschedulable资源配额

要提供完整答案,请结合两种方法:

  1. 使用事件工具获取事件详情(发生了什么、何时发生、原因是什么)
  2. 使用时间序列指标展示量化影响(重启次数、随时间变化的 OOM 杀死次数)
通过 DQL 获取 Kubernetes 事件

也可以通过 DQL 从 events 表中查询 Pod 重启和运维事件:

fetch events
| filter event.kind == "K8S_EVENT"
| filter event.type == "Warning"
| fields timestamp, k8s.cluster.name, k8s.namespace.name, k8s.pod.name,
    event.reason, event.message
| sort timestamp desc
| limit 50

筛选特定事件原因:

fetch events
| filter event.kind == "K8S_EVENT"
| filter in(event.reason, {"OOMKilling", "BackOff", "Evicted", "FailedScheduling"})
| fields timestamp, k8s.cluster.name, k8s.namespace.name, k8s.pod.name,
    event.reason, event.message
| sort timestamp desc

**fetch events 中的字段名:**请使用 event.reason 和 event.message,而不是 dt.kubernetes.event.reason。dt.kubernetes.* 前缀用于时间序列指标,而非 events 表。使用错误前缀的查询会返回零条结果。

4. 安全评估

识别特权容器:

smartscapeNodes K8S_POD
| parse k8s.object, "JSON:config"
| expand container = config[spec][containers]
| fieldsAdd
    container_name = container[name],
    privileged = container[securityContext][privileged]
| filter privileged == true

查找以 root 身份运行的容器:

smartscapeNodes K8S_POD
| parse k8s.object, "JSON:config"
| expand container = config[spec][containers]
| fieldsAdd
    container_name = container[name],
    run_as_user = container[securityContext][runAsUser],
    run_as_non_root = container[securityContext][runAsNonRoot]
| filter (isNull(run_as_user) or run_as_user == 0) and run_as_non_root != true
5. 调度分析

验证 Deployment 和 StatefulSet 的 Pod 分布(是否符合 HA 要求):

smartscapeNodes K8S_POD
| filter in(k8s.workload.kind, {"deployment", "statefulset"})
| summarize pod_count = count(),
            node_count = countDistinct(k8s.node.name),
            by: {k8s.cluster.name, k8s.namespace.name, k8s.workload.name, k8s.workload.kind}
| fieldsAdd ha_compliant = node_count > 1
| filter pod_count >= 2 and not ha_compliant

DaemonSet 会被有意排除——按照设计,每个 Pod 只会在一个节点上运行,因此对它们来说,位于单个节点并不违反 HA 要求。

6. 影响 K8s 实体的 DAVIS 问题

查找影响 K8s 实体的活跃 DAVIS 问题:

fetch dt.davis.problems, from:now() - 2h
| filter not(dt.davis.is_duplicate) and event.status == "ACTIVE"
| filter iAny(startsWith(smartscape.affected_entities[][type], "K8S_"))
| fields display_id, event.name, event.category, affected_entity_ids = smartscape.affected_entities[][id]

smartscape.affected_entities 是一个记录数组;每条记录都有 id、type 和 name。使用 [][id] 获取 Smartscape ID 数组,以查询受影响的实体;或者在 expand smartscape.affected_entities 后使用 [id]。若前面没有 expand,[id] 会静默返回 null。filter 不能接受未包装的迭代表达式,因此请将其包装在 iAny(...) 中。

最佳实践

选择合适的数据源
用户问题最佳方法原因
“显示 OOM 事件”事件工具 + 指标事件提供原因和消息;指标展示趋势
“显示 Pod 重启事件”事件工具 + 时间序列指标事件揭示原因(BackOff、Killing、CrashLoopBackOff);dt.kubernetes.container.restarts 指标提供实际重启次数
“Pod 重启了多少次?”时间序列指标按时间展示定量数据
“过去 48h 我的 Pod 发生了什么?”事件工具提供带上下文的运维事件历史
“哪些 Pod 的 CPU 使用量最高?”时间序列指标资源利用率分析
“列出所有集群/命名空间”smartscapeNodes实体发现和清单
“是否存在调度失败?”事件工具事件原因能解释失败缘由
“哪些工作负载的资源配置过高?”时间序列指标,工作负载级别requests 必须使用 sum();按 k8s.workload.name 分组
时间范围
  • smartscapeNodes — 无时间范围;始终返回当前实体状态。
  • timeseries — 始终添加 from: now()-<window>。默认时间窗口由系统决定,通常过短,不适合分析趋势。建议的默认值: now()-1h 用于查看近期峰值,now()-24h 用于查看每日规律,now()-7d 用于查看每周趋势。
  • fetch events — 建议添加 from:,以便获得可复现的结果;如果不添加,则使用系统默认时间窗口。
  • fetch dt.davis.problems — 对于活动问题,使用 from: now()-2h;将范围延长至 now()-7d,以包含近期已关闭的问题。
查询性能
  1. 尽早筛选 - 立即应用集群/命名空间筛选条件
  2. 使用具体实体类型 - 避免使用通配符
  3. 限制结果集 - 探索数据时使用 limit
  4. 缓存集群列表 - 将其存储在变量中
  5. 除非确有需要,否则省略 k8s.object - 解析该字段会显著增加查询成本
监控建议
  1. 为所有容器设置资源限制
  2. 监控 OOMKills 并调整内存限制
  3. 跟踪 CPU 节流情况并调整 CPU 限制
  4. 定期检查资源效率(目标为 70-80%)
  5. 实施安全最佳实践(非 root、只读文件系统)
  6. 使用具体的镜像标签(避免使用 :latest)
配置规范
  1. 使用标签进行组织(应用、环境、团队)
  2. 设置资源请求和限制
  3. 配置健康检查(存活性/就绪性探针)
  4. 对所有入口资源使用 TLS
  5. 使用注解编写文档

故障排查

问题原因解决方案
未返回 Pod 数据实体类型错误或缺少集群筛选条件使用 K8S_POD(而非 POD);添加 k8s.cluster.name 筛选条件
k8s.object 解析错误JSON 结构复杂使用 parse k8s.object, "JSON:config",然后访问嵌套字段
Pod 网络指标不可用Grail 中不提供使用服务网格指标或主机级网络指标
结果集过大未指定时间范围或集群筛选条件添加时间范围,并尽早按集群/命名空间筛选
输出中缺少标签标签访问方式不正确使用 tags[label_name] 访问标签
k8s.workload.kind 筛选条件未返回结果值采用 Pascal 命名法(例如 "Deployment")DT 中的值均为小写:"deployment"、"statefulset"、"daemonset"

限制

不可用的指标:

  • Grail 中不提供 Pod 网络指标(rx_bytes、tx_bytes)
  • 解决方法:使用服务网格指标或主机级网络指标

查询注意事项:

  • 尽量缩小结果集:如果不需要,请勿包含 k8s.object 字段
  • 尽量简化结果集:解析 k8s.object 会增加查询复杂度
  • 大型集群可能需要分页或限制时间范围
  • 某些 K8s 状态字段会异步更新

何时加载参考资料

在以下情况下加载 cluster-inventory.md:
  • 执行集群、命名空间或资源分布分析
  • 审核跨集群的工作负载数量

→ references/cluster-inventory.md

在以下情况下加载 labels-annotations.md:
  • 按标签或注释筛选
  • 解析 k8s.object 以详细检查配置

→ references/labels-annotations.md

在以下情况下加载 pod-node-placement.md:
  • 分析调度约束(亲和性、污点、容忍度)
  • 验证 HA 合规性和 Pod 分布

→ references/pod-node-placement.md

在以下情况下加载 pod-debugging.md:
  • 调查 Pod 退出代码、崩溃循环或初始化容器故障
  • 诊断镜像拉取错误或服务到 Pod 的连接问题
  • 从服务问题深入排查 Pod 级别的详细信息

→ references/pod-debugging.md

在以下情况下加载 workload-health.md:
  • 调查性能下降的部署或停滞的滚动更新
  • 检查节点状况、CPU 节流或 HPA 扩缩容
  • 分析 StatefulSet 的排序或 DaemonSet 的覆盖范围

→ references/workload-health.md

在以下情况下加载 pv-pvc.md:
  • 使用持久化存储(PVC/PV 生命周期、孤立卷)
  • 检查 StorageClass 配置

→ references/pv-pvc.md

在以下情况下加载 ingress.md:
  • 分析 ingress 路由规则或 TLS 证书
  • 审核 ingress 控制器配置

→ references/ingress.md

在以下情况下加载 network-policies.md:
  • 列出或审核网络策略
  • 检查命名空间隔离配置

→ references/network-policies.md

参考资料

相关技能

  • dt-obs-problems — 用于处理与 Kubernetes 集群相关的问题(将 dt.smartscape_source.id 与 K8S_ 前缀筛选条件配合使用)
  • dt-dql-essentials — DQL 核心语法和查询结构
  • dt-obs-hosts — K8s 节点的主机级指标

评论

支持 Markdown