EKS节点诊断收集工具

用于通过SSM Automation收集和分析EKS工作节点诊断日志的工具,覆盖20+日志源,包括kubelet、containerd、iptables等。

  • by aws-samples
  • Python
  • 本地部署
  • 14 星标
  • 更新于
在 GitHub 查看 aws-samples/sample-eks-node-diagnostics-mcp

使用说明

EKS节点诊断MCP

⚠️ 概念验证(POC): 这个项目是一个概念验证,应该首先在非生产环境中进行测试。在与生产工作负载一起使用之前,在过渡或开发帐户中进行彻底验证。

AWS DevOps代理的MCP服务器,用于使用SSM Automation从EKS工作节点收集和分析诊断日志。涵盖20多个日志源,包括kubelet、containerd、iptables、CNI config、路由表、dmesg、IPAMD等,这些工件位于节点操作系统上,无法通过Kubernetes API或CloudWatch访问。

想了解内部吗? 看 建筑与设计 深入了解组件的工作原理、数据流、工具设计和安全模型。


先决条件

1.Node.js(v18.x或更高版本)

macOS(Homebrew):

brew install node

Linux(Ubuntu/Debian):

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

2.AWS CLI v2

macOS:

brew install awscli

Linux:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

3.AWS-CDK-CLI

npm install -g aws-cdk

4.Python 3

大多数系统都预装了它:

python3 --version

5.AWS证书

您需要权限来创建IAM角色、Lambda函数、S3 Bucket、KMS密钥、Cognito用户池和BedrockAgentCore网关。

aws configure
# Or use AWS SSO:
aws sso login --profile your-profile
export AWS_PROFILE=your-profile

6.Worker节点上的crictl(适用于pod级别的tcpdump)

仅适用于 tcpdump_capture 随着 podName/podNamespace默认情况下,EKS优化的AMI包括它。


部署

# Clone the repository
git clone https://github.com/aws-samples/sample-eks-node-diagnostics-mcp.git
cd sample-eks-node-diagnostics-mcp

# Make the script executable
chmod +x deploy.sh

# Deploy (defaults to us-east-1)
./deploy.sh

# Or deploy to a specific region
AWS_REGION=us-west-2 ./deploy.sh

deploy.sh 从您的交互选择中自动导出安全范围——没有单独的“收紧”步骤。选择集群后,脚本将导出:

  • ALLOWED_REGIONS 从所选集群的区域中。
  • ALLOWED_CLUSTER_NAMES 根据所选集群的名称。
  • EKS_NODE_ROLE_ARNS 从所选节点组角色中选择。

这些直接流入CDK构造,因此部署的IAM策略是标记范围和区域范围的,没有任何额外的标志。如果跳过集群选择(或找不到集群),脚本将退回到仅部署区域,并在部署不受限制的集群范围之前进行提示。

交互式部署流程

部署脚本将引导您完成三个交互式提示:

步骤1——区域选择:

Which AWS regions should be scanned for EKS clusters?

  1) All enabled regions
  2) Current deploy region only (us-east-1)
  3) Enter a specific region

Select [1/2/3] (default: 1):

步骤2——集群选择:

Found 4 EKS cluster(s):

  1) prod-cluster    (us-east-1)
  2) dev-cluster     (us-east-1)
  3) analytics        (us-west-2)
  4) eu-cluster       (eu-west-1)

  a) All clusters

Select clusters (comma-separated numbers, or 'a' for all) [default: a]:

步骤3——节点角色选择:

Found 3 unique node role(s):

  1) arn:aws:iam::123456789012:role/eks-prod-node-role
     └─ eks-prod-node-role  (prod-cluster / us-east-1)
  2) arn:aws:iam::123456789012:role/eks-dev-node-role
     └─ eks-dev-node-role  (dev-cluster / us-east-1)
  3) arn:aws:iam::123456789012:role/eks-eu-node-role
     └─ eks-eu-node-role  (eu-cluster / eu-west-1)

  a) All roles

Select node roles (comma-separated numbers, or 'a' for all) [default: a]:

回退——手动输入ARN:

如果找不到EKS集群或节点角色,则脚本会提示您手动输入角色ARN:

WARNING: No EKS clusters found in the selected region(s).

Would you like to manually enter node role ARN(s)? [y/N]: y
Enter comma-separated role ARNs (e.g. arn:aws:iam::123456789012:role/MyNodeRole):
>

非交互/CI模式

预先设置env变量以跳过每个提示。建议用于可重复部署:

AWS_REGION=us-east-1 \
ALLOWED_REGIONS=us-east-1 \
ALLOWED_CLUSTER_NAMES=prod-cluster,staging-cluster \
EKS_NODE_ROLE_ARNS=arn:aws:iam::123456789012:role/eks-node-role \
./deploy.sh EksNodeLogMcpStack

如果你真的需要通配符作用域(Lambda可以针对帐户中的任何EKS集群),请明确选择加入:

AWS_REGION=us-east-1 \
ALLOW_ANY_CLUSTER_NAME=true \
EKS_NODE_ROLE_ARNS=arn:aws:iam::123456789012:role/eks-node-role \
./deploy.sh EksNodeLogMcpStack

没有一个 ALLOWED_CLUSTER_NAMES 或 ALLOW_ANY_CLUSTER_NAME=true, cdk synth 由于明显的错误而失败——这是故意的。

最大限制

对于生产部署,将其余控件分层:

AWS_REGION=us-west-2 \
ALLOWED_REGIONS=us-west-2 \
ALLOWED_CLUSTER_NAMES=prod-cluster \
ALLOWED_SSM_DOCUMENTS=AWS-RunShellScript \
EKS_NODE_ROLE_ARNS=arn:aws:iam::123456789012:role/eks-node-role \
PRESIGNED_URL_EXPIRATION=120 \
PCAP_PRESIGNED_URL_EXPIRATION=30 \
PER_CALLER_RATE_LIMIT_PER_MINUTE=30 \
TOOL_AUTHORIZATION="collect:client-soc;tcpdump_capture:client-emergency" \
MCP_VPC_ID=vpc-0123456789abcdef0 \
MCP_VPC_SUBNET_IDS=subnet-aaa,subnet-bbb \
MAX_PCAP_BYTES=104857600 \
./deploy.sh
Env-var 它限制了什么 默认值
ALLOWED_REGIONS IAM资源ARN+Lambda区域扫描 堆栈区域
ALLOWED_CLUSTER_NAMES ssm:SendCommand 实例上的标记条件 (无--失败关闭)
ALLOW_ANY_CLUSTER_NAME 显式选择加入任何集群通配符 false
ALLOWED_SSM_DOCUMENTS 哪些SSM文件可以执行 AWS-RunShellScript
EKS_NODE_ROLE_ARNS S3 PutObject+KMS加密主体 帐户根
PRESIGNED_URL_EXPIRATION 日志工件预签名URL生存期(最大900秒) 300秒
PCAP_PRESIGNED_URL_EXPIRATION Pcap预签名URL生存期(最多300秒) 60秒
ENABLED_RESTRICTED_TOOLS tcpdump工具可用性 空(不可用)
TOOL_AUTHORIZATION 每个工具客户端id ACL(tool:client_a,client_b;…) 空(打开)
PER_CALLER_RATE_LIMIT_PER_MINUTE 每位呼叫者的费率限制(0 禁用) 60
MCP_VPC_ID / MCP_VPC_SUBNET_IDS 在VPC中运行Lambda+创建S3/KMS端点 无
MAX_PCAP_BYTES Pcap上传大小上限(仅警告) 200 MiB

部署什么

资源 目的
S3存储桶(KMS加密) 存储收集的日志包
S3 Bucket(SOP) 存储41个Runbook,通过CDK自动部署
Lambda(SSM自动化) 处理所有21个MCP工具调用(19个始终开启+2个受限tcpdump)
Lambda(解压缩) 自动提取上传的存档
Lambda(发现索引器) 预索引错误以实现快速检索
SSM自动化角色 在EC2实例上运行日志收集
Cognito用户池 MCP网关的OAuth2身份验证
BedrockAgentCore网关 MCP协议端点
KMS密钥 加密所有静态数据

安全模型

默认情况下,所有安全控制都是强制执行的。除非您做出明确的集群作用域选择,否则该构造无法合成——没有隐式通配符。

默认值(无需额外配置)

控制 默认 可通过配置
地区限制 仅限堆栈区域 ALLOWED_REGIONS 有人是。
集群限制 故障关闭 --必须设置 ALLOWED_CLUSTER_NAMES 或 ALLOW_ANY_CLUSTER_NAME=true ALLOWED_CLUSTER_NAMES, ALLOW_ANY_CLUSTER_NAME
SSM文件限制 AWS-RunShellScript 只有 ALLOWED_SSM_DOCUMENTS 有人是。
tcpdump工具 已从路由表中删除 ENABLED_RESTRICTED_TOOLS 有人是。
预设URL过期(日志) 300秒,最大900秒 PRESIGNED_URL_EXPIRATION 有人是。
预设URL过期(pcap) 60秒,最多300秒 PCAP_PRESIGNED_URL_EXPIRATION 有人是。
根据工具授权 所有经过身份验证的调用者都可以调用任何非受限工具 TOOL_AUTHORIZATION 有人是。
每个呼叫者的费率限制 60次调用/分钟/呼叫者 PER_CALLER_RATE_LIMIT_PER_MINUTE env var(0禁用)
VPC端点(S3、KMS、SSM、EC2、日志、度量) 关闭(Lambda在VPC之外运行) MCP_VPC_ID + MCP_VPC_SUBNET_IDS
Pcap上传绑定 200 MiB(超过时发出警告) MAX_PCAP_BYTES 有人是。
响应编辑 SG/ENI/子网/VPC ID、ARN中的帐户ID、私有IP(网络工具)、IAM错误体、JWT/AKIA令牌、命名字段 *password*/*secret*/*token*/*credential* 始终开启
S3加密 带自动旋转钥匙的SSE-KMS enableEncryption CDK道具
S3公共访问 已阻止 始终打开
S3运输 SSL强制 始终打开
认证 Cognito OAuth2客户端凭据 始终打开
EKS实例验证 基于标记的+EKS API交叉引用 始终打开
BPF过滤器验证 基于允许列表(非denylist) 始终打开
Idempotency写道 S3条件写入(IfNoneMatch=*) 始终开启
基线计数器写入 乐观并发(IfMatch=<VersionId>,重试 PreconditionFailed) 始终开启
日志自动删除 1天 logRetentionDays CDK道具

IAM范围界定

ssm:SendCommand 限制在三个级别:

  1. 资源ARN --实例ARN的作用域为 ALLOWED_REGIONS (例如。, arn:aws:ec2:us-west-2:ACCOUNT:instance/*).文档ARN的范围是特定的文档名称(例如。, document/AWS-RunShellScript).
  2. 标签条件 --实例必须具有 eks:cluster-name 标签匹配 ALLOWED_CLUSTER_NAMES。对于特定名称,该条件使用 StringEquals (完全匹配)。通配符形式(StringLike: *)仅在以下情况下发射 ALLOW_ANY_CLUSTER_NAME=true.
  3. 地区条件 --所有SSM、EC2和EKS操作包括 aws:RequestedRegion 条件。

如果 ALLOWED_CLUSTER_NAMES 是空的 和 ALLOW_ANY_CLUSTER_NAME 不是 true, cdk synth 失败原因:

Error: SsmAutomationGatewayV2: must set either `allowedClusterNames` (preferred)
or `allowAnyClusterName: true` to acknowledge that ssm:SendCommand should be
permitted against every EKS cluster in this account.

这可以防止意外部署不受限制的实例范围。

每工具授权和费率限制

每次调用都会提取调用者的Cognito client_id 和 sub 来自AgentCore网关转发的JWT索赔。然后在发货前运行两次检查:

  1. 每个工具ACL — TOOL_AUTHORIZATION 是一个 ;-分隔列表 tool:client_a,client_b 条目。列出的工具会得到一个非空的允许集(只有这些客户端可以调用)。用空集合列出的工具是全部拒绝。未列出的工具仍对所有经过身份验证的调用者开放。
  2. 令牌桶速率限制 --每位来电者尽最大努力,放在一个温暖的容器里。默认60/min。返回HTTP 429 retryAfterSeconds 当超过。集 PER_CALLER_RATE_LIMIT_PER_MINUTE=0 禁用。

tcpdump工具

tcpdump_capture 和 tcpdump_analyze 是 默认情况下不可用。它们已从Lambda的工具路由表中完全删除,不会出现在 available_tools 并且不能被调用。要启用它们,请设置 ENABLED_RESTRICTED_TOOLS=tcpdump_capture,tcpdump_analyze 在部署之前。即使启用:

  • 每次捕获都需要 confirmCapture=true.
  • tcpdump将不会自动安装在节点上(脚本会随手动安装说明一起运行)。
  • Pcap预签名的URL使用较短的 PCAP_PRESIGNED_URL_EXPIRATION 窗口(默认60秒)。
  • 捕获大于 MAX_PCAP_BYTES (默认值为200 MiB)在响应中显示警告。

响应补救措施

redact_response 在每个Lambda响应返回网关之前运行:

  • 资源ID(sg-…, eni-…, subnet-…, vpc-…, vol-…, fs-…)被蒙面 <prefix>-***.
  • ARN中的帐户ID被替换为 ***.
  • AWS访问密钥(AKIA…, ASIA…)JWT形弦被遮蔽。
  • IAM/凭据错误消息正文(AccessDenied, Unauthorized, not authorized to perform, ExpiredToken等)被折叠成 <iam-error-details-redacted>.
  • 用于网络相关工具(network_diagnostics, tcpdump_*, cluster_health, storage_diagnostics),RFC1918+CGNAT私有IP被屏蔽 <private-ip>.
  • 关键字包含的字段 password, secret, token, apikey,或 credential 被替换为 <redacted>. volumeHandle/volume_handle 被截断为24个字符。

VPC端点(可选)

设置 MCP_VPC_ID 和 MCP_VPC_SUBNET_IDS 将Lambda附加到VPC,并为S3提供网关端点,以及为KMS、SSM、SSM消息、EC2、CloudWatch日志和CloudWatch指标提供接口端点。SDK调用和预分配的URL流量留在AWS网络上,而不是公共互联网上。


部署后:EKS节点IAM设置

什么是自动

如果您在交互式部署流程中选择了节点角色(或通过 EKS_NODE_ROLE_ARNS),CDK堆栈会自动授予:

  • S3存储桶策略: s3:PutObject, s3:GetBucketPolicyStatus, s3:GetBucketAcl 在原木桶上
  • KMS密钥策略: kms:GenerateDataKey, kms:Encrypt, kms:Decrypt 关于加密密钥(kms:Decrypt 需要S3多部分上传大于~8 MiB的文件)

这些角色不需要手动设置S3或KMS。

如果在部署期间没有提供节点角色,则堆栈将回退到帐户范围的策略(帐户中的任何主体都可以上传)。这限制较少,但仍然有效。

你可能还需要什么

CDK堆栈唯一没有附加的是SSM代理管理的策略。EKS优化的AMI默认包括SSM代理,但IAM角色需要以下策略:

# Only needed if not already attached
aws iam attach-role-policy \
  --role-name <YOUR-NODE-ROLE-NAME> \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

部署后添加节点角色

如果稍后添加新的EKS集群,请重新运行部署脚本——它将检测新的节点角色并自动更新S3存储桶和KMS密钥策略。

或者,直接传递新角色:

EKS_NODE_ROLE_ARNS="arn:aws:iam::123456789012:role/ExistingRole,arn:aws:iam::123456789012:role/NewRole" ./deploy.sh

每个集群的检查表

  • []部署期间选择了节点角色(或通过重新部署添加)
  • []节点角色具有 AmazonSSMManagedInstanceCore 管理策略(用于SSM代理)
  • []SSM代理正在节点上运行(EKS优化AMI上的默认设置)
  • [ ] AWSSupport-CollectEKSInstanceLogs 目标区域中存在SSM文档

DevOps代理中的配置

部署后,脚本输出MCP服务器配置所需的所有值:

设置 值
MCP服务器URL https://<gateway-id>.gateway.bedrock-agentcore.<region>.amazonaws.com/mcp
OAuth客户端ID 输出中的Cognito客户端ID
OAuth客户端密码 输出中的Cognito客户端密码
令牌URL https://<stack-name>-<account>.auth.<region>.amazoncognito.com/oauth2/token
范围 ssm-automation-gateway-id/gateway:read

值也保存到 mcp-config.txt 以供参考。


代理技能

A预制 代理技能 被包含在 skills/ 教AWS DevOps Agent如何有效地使用此MCP服务器。该技能将调查工作流程、抗幻觉护栏和所有41个runbook程序加载到代理的上下文中,从而补充了运行时 list_sops/get_sop 工具。

技能拉链 大小 内容
eks-node-diagnostics.zip 188K 21个工具工作流程,41个运行本,VPC CNI抗幻觉规则,存储护栏

上传技能

  1. 导航到 技能 您的页面 代理空间运营商Web应用程序
  2. 点击 添加技能 → 上传技巧
  3. 上传 skills/eks-node-diagnostics.zip
  4. 将代理类型设置为 通用的 (所有代理类型)
  5. 点击 上传

有关更多详细信息,请参阅 AWS DevOps代理技能文档.

技能vs SOP:调查开始时的技能负荷(前期方法和陷阱)。SOP通过以下方式按需获取 get_sop (详细的分步程序)。两者结合使用可获得最佳效果。


运作原理

该服务器使MCP兼容代理能够从EKS工作节点收集完整的诊断包,对严重性分类的错误进行预索引,在不截断的情况下流式传输多GB日志文件,跨日志源关联事件,运行实时tcpdump捕获,比较节点,并遵循结构化运行手册——所有这些都通过5层组织的21个MCP工具(19个始终在线+2个受限制的tcpdump工具,选择加入)完成。

有关架构、数据流、工具设计、跨区域机制、安全模型和抗幻觉设计的详细演练,请参阅:

建筑与设计→

MCP工具(快速参考)

层级 工具 目的
1--核心 collect, status, validate, errors, read 日志收集、发现、流式传输
2--分析 search, correlate, artifact, summarize, quick_triage, history 深入调查、关联、总结
3--集群 cluster_health, compare_nodes, batch_collect, batch_status, network_diagnostics, storage_diagnostics 多节点操作
4--捕获 tcpdump_capture, tcpdump_analyze 实时数据包捕获(默认情况下禁用)
5-SOP list_sops, get_sop 41本结构化的小册子

注: 默认情况下,第4层工具将从路由表中删除。他们没有出现在 available_tools 除非满足以下条件,否则无法调用 ENABLED_RESTRICTED_TOOLS 包括他们。看 安全模型.

代理工作流

collect → status (poll) → validate → errors → search → correlate → read → summarize

Runbook库(41 SOP)

类别 覆盖范围
A--节点生命周期 OOM/NotReady、证书、引导、时钟偏斜、连接失败
B-Kubelet 配置错误、驱逐、PLEG
C--容器运行时 映像拉取、沙箱创建、覆盖FS/索引节点
D--网络 VPC CNI、kube-proxy、conntrack、MTU、DNS、ENA、pod到pod
E--存储 EBS CSI、EFS装载
F-调度 CPU/内存、最大Pod数、污染/容忍度
G--资源压力 磁盘压力、OOMKill、PID压力
H-IAM/安全 节点角色、IRSA/Pod标识、IMDS
I——升级 版本偏差
J-基础设施 ENA/实例限制、EBS瞬态、AZ停机
K--工作负载问题 终止Pod卡住、探测器故障、CrashLoopBackOff、容器故障、CSI插件
Z--包罗万象 一般故障排除

使用示例

基础调查

Node i-0abc123def in us-west-2 went NotReady around 3am. Collect its logs
and correlate what happened in the 5 minutes before it went down.

集群范围分类

We have a 200-node cluster and something is off. Do a dry run batch collection
first — show me which nodes you'd sample. Then collect from the unhealthy ones.

实时数据包捕获

要求: ENABLED_RESTRICTED_TOOLS=tcpdump_capture,tcpdump_analyze 在部署时设置。tcpdump必须预先安装在节点AMI上。每次捕获都需要 confirmCapture=true.

Pods on node i-0abc123def can't reach the API server. Run a 2-minute tcpdump
filtered on port 443, then analyze — show me RST counts and retransmissions.

吊舱液位捕捉

要求: 与上述相同,另外 crictl 在节点上(EKS优化AMI的默认设置)。

DNS lookups are timing out. CoreDNS pod coredns-5d78c9869d-abc12 is on node
i-0abc123def in kube-system. Capture UDP port 53 from inside the pod for 60s.

SOP指导

I don't know what's wrong — just investigate. List the available SOPs, run a
general triage, and follow whichever runbook matches.

云形成输出

输出 描述
GatewayId AgentCore网关ID
GatewayUrl MCP服务器URL
CognitoUserPoolId Cognito用户池ID
CognitoClientId OAuth客户端ID
OAuthExchangeUrl OAuth令牌URL
OAuthScope OAuth作用域
LogsBucketName S3原木桶
SOPBucketName S3 Runbook桶
SSMAutomationRoleArn SSM自动化角色ARN
EncryptionKeyArn KMS密钥ARN

故障排除

症状 原因 修复
cdk synth 以“必须设置”失败 allowedClusterNames …“ 未选择群集范围 设置 ALLOWED_CLUSTER_NAMES=… (首选)或 ALLOW_ANY_CLUSTER_NAME=true 并重新运行 ./deploy.sh
工具返回403“工具'…'被限制且未启用” 呼叫者点击 tcpdump_capture / tcpdump_analyze 无选择加入 设置 ENABLED_RESTRICTED_TOOLS=tcpdump_capture,tcpdump_analyze 并重新部署
工具返回403“不允许调用者调用‘…’” 每个工具的ACL不包括此客户端 将客户端添加到匹配中 TOOL_AUTHORIZATION 入口
工具返回429“超出费率限制” 超出呼叫者 PER_CALLER_RATE_LIMIT_PER_MINUTE 等等 retryAfterSeconds 在响应中,或提高限制
collect 返回“找不到文档” SSM文档不在目标区域 使用支持的区域或通道 region 明确
collect 失败在 CheckS3BucketPublicStatus SSM自动化角色缺失 s3:GetBucketPublicAccessBlock / s3:GetAccountPublicAccessBlock 已由当前构造授予--如果您的堆栈早于修复,请重新部署
上传步骤失败 节点角色缺少S3/KMS权限 通过传递节点角色 EKS_NODE_ROLE_ARNS 并重新部署
status 返回错误的区域 区域元数据未持久化 通过 region 明确
自动检测超时 不常见区域中的实例 将区域添加到 ALLOWED_REGIONS 并通过 region 明确
errors 返回空 结果索引器尚未运行 等待几秒钟 validate,或使用 search
响应缺少应该存在的ID(例如。 sg-…) 红色行动层正在屏蔽它们 需要-- redact_response 按设计屏蔽SG/ENI/子网/VPC ID和帐户ID

清理

cdk destroy

日志和SOP桶配置了 removalPolicy: DESTROY 和 autoDeleteObjects: true,所以 cdk destroy 将删除bucket及其所有内容。从下载您需要的任何内容 eksnodelogmcpstack-logs-<account> 第一。


许可证

本项目根据麻省理工学院无署名(MIT-0)许可证获得许可。请参阅 许可证 文件。