关于 dt-obs-kubernetes
dt-obs-kubernetes 是使用 Dynatrace DQL 监控和分析 Kubernetes 基础设施的 Skill,适用于集群与工作负载运维。它涵盖资源使用、调度、成本及安全检查,并结合指标与事件排查问题。
主要功能
- 01查询集群、节点、Pod 和工作负载
- 02监控 CPU、内存及重启等指标
- 03结合 Kubernetes 事件排查故障
- 04分析 Pod 调度与节点放置
- 05检查资源成本和安全配置
适用场景
- 01检查集群健康和节点容量
- 02调查 OOMKill、驱逐及重启
- 03定位部署退化或调度失败
- 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.mdingress.mdlabels-annotations.mdnetwork-policies.mdpod-debugging.mdpod-node-placement.mdpv-pvc.mdworkload-health.md详细介绍
Infrastructure Kubernetes
使用 Dynatrace DQL 监控和分析 Kubernetes 基础设施。查询集群资源、监控工作负载运行状况、分析 Pod 放置情况、优化成本并评估安全态势。
何时使用此技能
- 监控 Kubernetes 集群的运行状况和容量
- 分析 Pod 和容器的资源利用率
- 调查 Pod 故障、OOMKill、驱逐或崩溃循环
- 调试性能下降的部署、卡住的发布或节点压力问题
- 优化 Kubernetes 资源成本
- 评估安全态势和合规性
- 排查工作负载调度和放置问题
- 审核 Ingress 路由和网络策略
知识库结构
核心监控(从这里开始)
- 集群清单 →
references/cluster-inventory.md- 集群、 命名空间、资源分布 - 节点监控 - 节点容量、CPU/内存使用量、Pod 密度
- Pod 监控 - Pod CPU、内存、生命周期事件
- 工作负载监控 - Deployment、StatefulSet、DaemonSet 资源
高级主题
- 配置分析 →
references/labels-annotations.md- 解析 k8s.object、标签、注解 - 调度与放置 →
references/pod-node-placement.md- 节点 选择器、亲和性、污点、高可用性 - 成本优化 - 适当调整规格、检测资源浪费、效率评分
- 安全与合规性 - 特权容器、安全上下文
核心概念
实体类型
工作负载: 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.namek8s.workload.name、k8s.workload.kind、k8s.container.namek8s.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.objectJSON、调度状态、条件和 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 | 资源配额 |
要提供完整答案,请结合两种方法:
- 使用事件工具获取事件详情(发生了什么、何时发生、原因是什么)
- 使用时间序列指标展示量化影响(重启次数、随时间变化的 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,以包含近期已关闭的问题。
查询性能
- 尽早筛选 - 立即应用集群/命名空间筛选条件
- 使用具体实体类型 - 避免使用通配符
- 限制结果集 - 探索数据时使用
limit - 缓存集群列表 - 将其存储在变量中
- 除非确有需要,否则省略
k8s.object- 解析该字段会显著增加查询成本
监控建议
- 为所有容器设置资源限制
- 监控 OOMKills 并调整内存限制
- 跟踪 CPU 节流情况并调整 CPU 限制
- 定期检查资源效率(目标为 70-80%)
- 实施安全最佳实践(非 root、只读文件系统)
- 使用具体的镜像标签(避免使用 :latest)
配置规范
- 使用标签进行组织(应用、环境、团队)
- 设置资源请求和限制
- 配置健康检查(存活性/就绪性探针)
- 对所有入口资源使用 TLS
- 使用注解编写文档
故障排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 未返回 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 级别的详细信息
在以下情况下加载 workload-health.md:
- 调查性能下降的部署或停滞的滚动更新
- 检查节点状况、CPU 节流或 HPA 扩缩容
- 分析 StatefulSet 的排序或 DaemonSet 的覆盖范围
→ references/workload-health.md
在以下情况下加载 pv-pvc.md:
- 使用持久化存储(PVC/PV 生命周期、孤立卷)
- 检查 StorageClass 配置
在以下情况下加载 ingress.md:
- 分析 ingress 路由规则或 TLS 证书
- 审核 ingress 控制器配置
在以下情况下加载 network-policies.md:
- 列出或审核网络策略
- 检查命名空间隔离配置
→ references/network-policies.md
参考资料
- cluster-inventory.md — 集群、命名空间和资源分布分析
- labels-annotations.md — 标签/注释筛选和 k8s.object 解析
- pod-node-placement.md — 调度、亲和性、污点和 HA 模式
- pod-debugging.md — 退出代码、Pod 状况、初始化容器、镜像拉取错误、日志、从服务深入排查 Pod
- workload-health.md — 性能下降的部署、停滞的滚动更新、节点状况、CPU 节流、HPA、StatefulSet 排序
- pv-pvc.md — PVC/PV 生命周期、阶段参考、孤立卷、StorageClass
- ingress.md — 路由规则解析、TLS 审核
- network-policies.md — 策略列表、命名空间隔离审核
相关技能
- dt-obs-problems — 用于处理与 Kubernetes 集群相关的问题(将
dt.smartscape_source.id与 K8S_ 前缀筛选条件配合使用) - dt-dql-essentials — DQL 核心语法和查询结构
- dt-obs-hosts — K8s 节点的主机级指标