使用说明
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 限制在三个级别:
- 资源ARN --实例ARN的作用域为
ALLOWED_REGIONS(例如。,arn:aws:ec2:us-west-2:ACCOUNT:instance/*).文档ARN的范围是特定的文档名称(例如。,document/AWS-RunShellScript). - 标签条件 --实例必须具有
eks:cluster-name标签匹配ALLOWED_CLUSTER_NAMES。对于特定名称,该条件使用StringEquals(完全匹配)。通配符形式(StringLike: *)仅在以下情况下发射ALLOW_ANY_CLUSTER_NAME=true. - 地区条件 --所有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索赔。然后在发货前运行两次检查:
- 每个工具ACL —
TOOL_AUTHORIZATION是一个;-分隔列表tool:client_a,client_b条目。列出的工具会得到一个非空的允许集(只有这些客户端可以调用)。用空集合列出的工具是全部拒绝。未列出的工具仍对所有经过身份验证的调用者开放。 - 令牌桶速率限制 --每位来电者尽最大努力,放在一个温暖的容器里。默认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抗幻觉规则,存储护栏 |
上传技能
- 导航到 技能 您的页面 代理空间运营商Web应用程序
- 点击 添加技能 → 上传技巧
- 上传
skills/eks-node-diagnostics.zip - 将代理类型设置为 通用的 (所有代理类型)
- 点击 上传
有关更多详细信息,请参阅 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)许可证获得许可。请参阅 许可证 文件。
