1. 简介
排查 Kubernetes 部署中断问题是平台工程师日常工作中常见但往往令人沮丧的一部分。这通常需要大量的人工调查:挖掘日志、运行 kubectl describe 命令,以及交叉引用 YAML 文件,以找到单个不匹配项或配置错误。
虽然通用 AI 聊天机器人可以帮助解释概念或编写基本代码,但它们是在真空中运行的。它们对您的特定代码库或集群的实时状态一无所知,因此需要进行大量的手动复制粘贴和上下文切换。
在本实验中,您将体验如何使用具有不断增加的上下文的 AI 工具来弥合这一差距。您将使用 Gemini CLI 和 Model Context Protocol (MCP) 来排查 GKE 上损坏的应用。完成本实验后,您将了解如何使用能够感知您的文件和基础设施的 AI 来更快地解决复杂问题,以及如何将这些工作流编入可供团队重复使用的“技能”中。
核心概念
- 平台工程:平台工程是指构建和维护内部工具和工作流的实践,使软件开发者能够管理自己的基础设施,而无需精通每项底层云服务。其目标是在保持一致性和安全性的同时减少技术摩擦。通过创建标准化的黄金路径,平台团队可确保应用开发者能够安全快速地进行部署,同时平台团队可保持对治理和成本的控制。
- Gemini CLI:Gemini CLI 是一种命令行界面,可让您直接从终端与 Gemini 模型进行交互。与基于网络的标准聊天机器人不同,CLI 旨在存在于您的开发环境中,从而更轻松地将 AI 集成到基于 Shell 的现有工作流程中。借助该功能,您可以将其他命令的输出直接通过管道传输到模型,并在不离开终端的情况下执行指令。
- Model Context Protocol (MCP):MCP 是一种开放标准,可让 AI 模型连接到特定工具或数据源。如果没有 MCP,AI 模型只能了解其训练数据,而无法查看您的特定资源。借助 GKE MCP 服务器,Gemini CLI 可以主动查询您的 Google Cloud 项目的 API、检查集群的状态,并代表您执行命令。它充当模型推理引擎与实际 GKE API 之间的桥梁。
- Agent Skills:技能是指令、脚本和资源的软件包,可扩展 AI 智能体的功能,以执行专门的任务。借助技能,您可以将组织标准编入代码并自动执行复杂的工作流程。
实验目标
您此实验中,您将执行以下操作:
- 体验上下文进展:了解增加上下文如何提升 AI 问题解决能力。
- 人工问题排查与 AI 问题排查:比较人工调试与 AI 辅助工作流的难度。
- 全上下文调试:将 Gemini CLI 与 GKE MCP 服务器搭配使用,以在充分了解基础架构的情况下调试应用。
- 扩展功能:学习如何编写自定义技能以实现工作流自动化。
关于 LLM 输出的注意事项
由于本实验的性质以及 LLM 的运作方式,您获得的输出可能与显示的示例输出不同。这是生成式 AI 的预期行为。请专注于理解步骤和模型提供的推理,而不是尝试复制示例中的确切文本或格式。
2. 项目设置
在开始实验之前,请准备好您的环境。打开 Cloud Shell,选择您的项目,然后运行设置脚本。让我们开始吧!
打开 Cloud Shell
在此实验中,您将使用 Cloud Shell,这是 Google Cloud 提供的一个基于浏览器的终端环境。它预配置了您所需的所有工具,包括 Google Cloud CLI (gcloud)、kubectl 和 Gemini CLI,可节省您在本地机器上安装这些工具的时间。
- 前往 Google Cloud 控制台。
- 查看控制台右上角的标题,然后点击激活 Cloud Shell 按钮(看起来像终端提示符
>_)。 - 终端会话会在浏览器窗口底部打开。如果出现提示,点击继续。
选择项目
在 Cloud Shell 终端中,确保您正在正确的项目中操作。
- 在控制台中选择现有项目,或专门为此实验创建新项目。
- 记下您的项目 ID。通过运行以下命令在当前 shell 中设置项目:
gcloud config set project [YOUR_PROJECT_ID]
实验设置
现在,运行设置脚本以准备环境并引入实验所需的 bug。
- 克隆代码库:
👉💻 运行以下命令,仅克隆实验目录:git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos ~/devrel-demos cd ~/devrel-demos git sparse-checkout set codelabs/ai-toolkit-lab-1 - 前往实验目录:
👉💻 运行:cd ~/devrel-demos/codelabs/ai-toolkit-lab-1/ - 设置环境变量:
👉💻 运行以下命令以设置项目和区域:export PROJECT_ID=$(gcloud config get-value project) export REGION=us-central1 - 运行设置脚本:
此脚本会启用下列 API,创建 GKE Autopilot 集群,并确保安装了所需的工具。
👉💻 从根目录运行脚本: 注意:创建集群可能需要 5-10 分钟。./setup.sh - 初始化损坏状态:
为了模拟同事留给您的环境损坏的场景,请运行break.sh脚本。它会将损坏的清单复制到有效代码库目录中。
👉💻 运行脚本:./break.sh - 准备进行实验练习:
为防止 AI 作弊(看到解决方案),请在实验的剩余部分切换到cymbal-bank目录。
👉💻 运行:cd ~/devrel-demos/codelabs/ai-toolkit-lab-1/cymbal-bank
已启用的 API
设置脚本会启用多个 Google Cloud API。这些 API 的用途如下:
- container.googleapis.com::Google Kubernetes Engine API。任何集群级操作都需要此权限。
- generativelanguage.googleapis.com::允许 Gemini CLI 与 Gemini 模型通信的 API。
- cloudresourcemanager.googleapis.com::用于检查项目级元数据和管理权限。
- logging.googleapis.com::对于问题排查至关重要,因为它允许从容器中提取和分析日志。
3. 第 0 阶段:手动问题排查(不使用 AI)
现在,您已进入 cymbal-bank 目录,接下来我们尝试手动查找错误。这是“硬方法”。在让 AI 帮你减负之前,先体验一下基准效果。手动问题排查是指使用 kubectl 等标准工具检查集群状态、提取日志和通读 YAML 文件,以发现不一致之处。这种方法通常很慢、很乏味,并且需要专业知识才能将各个点联系起来。这可作为您日后使用的 AI 工具的完美参考点。
- 尝试部署:我们来看看 Kubernetes 对这些清单的看法。
👉💻 运行以下命令以应用清单: 这些 Pod 可能需要几秒钟才能启动。您可以使用“watch kubectl get pods”命令来监控它们是否已启动。当它们启动后,使用 Ctrl+c 退出监视。您会注意到列表中有两个失败的 pod:kubectl apply -f kubernetes-manifests/- 前端 pod 显示 “CreateContainerConfigError”。此类错误通常表示容器在加载所需配置时遇到问题。想想容器启动时可能需要哪些外部资源 - 是否有环境变量、密文或 ConfigMap 可能配置不正确或缺失?您需要调查 pod 的配置,以找出具体原因。
- userservice pod 处于 "ImagePullBackOff" 状态。看到此状态通常意味着集群无法检索其被告知要使用的容器映像。请考虑映像请求的详细信息:映像名称和标记是否完全正确?注册表是否存在潜在的权限问题?查看映像的拉取来源,看看是否能发现请求失败的原因。
- 检查损坏情况:使用标准 Kubernetes 命令查看哪些内容出现故障。
- 👉💻 检查 pod 的状态及其名称:
kubectl get pods- 观察:您会看到
ImagePullBackOff、CrashLoopBackOff、Pending或CreateContainerConfigError中的 pod。 - 注意:处于
Running状态的 pod 并不一定意味着它在正常运行。例如,它可能缺少足够的健康探测(活跃性/就绪性),导致即使内部应用出现故障,它仍被标记为正在运行。即使 Pod 看起来正在运行,日志也可能会显示错误。总共有 11 处不同的错误需要修正。
- 观察:您会看到
- 👉💻 描述失败的 pod 以查看事件(将
[POD_NAME]替换为实际的 pod 名称):kubectl describe pod [POD_NAME] - 👉💻 检查失败的 pod 的日志,查看是否存在应用错误:
kubectl logs [POD_NAME]
- 👉💻 检查 pod 的状态及其名称:

- 侦探工作:使用 Cloud Shell 编辑器或终端中的
cat打开kubernetes-manifests/中的清单。尝试将日志和事件中看到的错误与 YAML 文件中的配置相关联。挑战:尝试手动修复一个错误。请注意,您必须在文件之间跳转才能找出其余的故障链。
4. 第 1 阶段:向网络提问(Gemini Web 界面)
由于手动问题排查速度较慢,我们不妨尝试使用 AI 助理。Gemini Web 应用是一款功能强大的通用聊天界面。它擅长解释概念和生成代码段。不过,它在运行时没有任何关于您特定环境的上下文。它无法查看您的文件、检查您的集群或运行命令。您必须手动复制并粘贴错误消息和文件内容。

- 前往 Gemini:在新标签页中打开 gemini.google.com。您需要使用自己的 Google 账号登录。
- 针对特定错误寻求帮助:假设您在
userservicepod 上看到ImagePullBackOff错误。
👉💬 在 Gemini Web 界面中输入以下提示:My Kubernetes deployment for 'userservice' is failing with ImagePullBackOff. Here is the image name: us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/user-service:v0.6.9. What is wrong? - AI 的回答:Gemini 会列出一些常见原因:
- 相应图片不存在。
- 您无权拉取。
- 有拼写错误。
userservice(不含连字符)。
这里的主要阻力在于,Gemini 无法了解您的本地环境。为了让模型获得所需的上下文,您需要手动提供(通过提示和复制粘贴周围的文本),这既耗时又容易出错。
5. 第 2 阶段:终端功能 (Gemini CLI)
现在,使用 Gemini CLI 转到终端。Gemini CLI 可将 Gemini 模型的强大功能直接引入您的终端。该 CLI 位于您的工作环境中,可读取本地文件、接受管道输入,甚至可以代表您执行 shell 命令(经您批准)。这使得您可以将 AI 集成到工作流程中,而无需切换上下文,非常实用。如需了解更多详细信息和高级用法,请参阅 Gemini CLI 官方文档。
注意:目前,Antigravity CLI 已正式发布,是 Gemini CLI 的继任者。本实验将继续使用 Gemini CLI。如需详细了解 Antigravity CLI,请参阅 Antigravity CLI 官方文档。
背景信息和可见性
在介绍相关说明之前,请注意 Gemini CLI 对项目的可见性取决于您启动它的位置。该模型可以查看相对于当前工作目录的文件和文件夹。如果您从项目根目录运行它,它将有权访问该项目中的所有文件。如果您从子目录运行它,它的视图将仅限于该子目录及其子目录。在要求模型分析或修改文件之前,请务必确保您位于正确的目录中!
启动 Gemini CLI
Cloud Shell 默认包含 Gemini CLI。只需启动该应用,即可开始使用它来处理本地文件。
- 前往 Cymbal Bank 目录:
👉💻 运行以下命令,确保您位于正确的目录中:cd ~/devrel-demos/codelabs/ai-toolkit-lab-1/cymbal-bank - 启动 Gemini CLI:
👉💻 运行以下命令以启动 Gemini CLI:gemini

使用 Gemini CLI
您对该应用的了解仅限于代码的存放位置以及应用运行失败。接下来,我们来详细了解一下,看看 Gemini 如何帮助您修复该应用。首先,尝试测试 Gemini 探索上下文的能力,方法是询问一个关于它应该能够看到的应用文件的问题。
- 探索代码库:问问 Gemini,解释此应用是什么以及它的用途。
👉💬 在 Gemini CLI 中输入以下提示:What is this application and what does it do?
Gemini CLI 会读取当前目录中的文件,并提供项目的高级概览。 - 尝试在代码库中查找问题:由于 Gemini CLI 可以查看您的文件,因此请让它查找不匹配项。
👉💬 在 Gemini CLI 中输入以下提示:The contacts service pod is running, but I can't reach the service. Review kubernetes-manifests/contacts.yaml and check for common issues
Gemini CLI 会读取文件并发现app: contacts-backend和app: contacts之间的不匹配项。与之前的阶段相比,这是一个巨大的进步。 - 让 Gemini CLI 修复错误:
👉💬 在 Gemini CLI 中输入以下提示:Fix the label mismatch in contacts.yaml so the service matches the deployment.
Gemini CLI 会向您显示更正后的 YAML,如果您批准该命令,它甚至会应用相应更改。 - 限制:虽然它能看到文件,但仍然不知道集群中实际运行的是什么。如果 pod 因静态 YAML 中不明显的运行时错误而失败,则在没有日志或集群状态的情况下,无法提供帮助。
注意:Gemini CLI 在运行命令或修改文件时会征求您的同意。这样可确保您对自己的环境保持控制权。当您看到如下提示时,可以按“Enter”键来回答“1. 针对每项操作请求选择“允许一次”。您也可以点按向下箭头键,然后按 Enter 键选择“2. 允许本次会话”,这样一来,在本次对话期间,Gemini CLI 将始终独立执行该操作,而无需征求您的许可。不过,如果您关闭 Gemini CLI 并重新打开,它将不再拥有该权限,并且在采取任何行动之前会再次请求您的许可。

注意:如果您遇到问题,或者想从头开始重试,可以随时通过从 cymbal-bank 目录运行 ../break.sh 将 Kubernetes 清单重置回初始的损坏状态。
注意:如果达到使用限额,请选择“停止”,然后运行 /model 以查看哪些模型已达到限额,并切换到其他模型,例如 gemini-2.5-flash-lite。然后,向模型输入“继续”,以使用新模型继续完成实验。
6. 第 3 阶段:完整上下文调试 (Gemini CLI + GKE MCP)
虽然第 2 阶段展示了 AI 在能够查看文件时的强大功能,但它也存在一些问题。您必须手动批准每次文件读取和工具操作,这会在复杂的调试会话期间造成很大的阻碍。第 3 阶段引入了 GKE MCP 服务器来帮助解决此问题,为 AI 提供直接的“基础设施感知”。这使得 Gemini 能够以更少的手动中断来排查日志、事件和元数据,从而创建更自动化、更连贯的问题排查流程。
什么是 MCP?
若要了解 MCP,首先需要了解 AI 领域的工具概念。工具本质上是 LLM 可用于执行操作或提取数据的外部函数或应用,否则 LLM 将无法访问这些数据,例如查看天气、运行特定脚本或查询数据库。虽然单个工具功能强大,但如何在不同的 AI 智能体和环境之间安全且一致地共享这些工具一直是一个难题。MCP 通过充当可托管这些工具并将其公开给任何兼容的 AI 客户端的标准化平台来解决此问题。
Model Context Protocol (MCP) 是一种开源协议,可让 AI 模型安全地访问外部数据源和工具。MCP 提供了一种标准化方法,让模型能够与其环境互动,而无需为每个特定工具或数据库硬编码集成。
您可以在 Gemini CLI 中运行 /mcp,以查看可用的工具。
在此实验中,GKE MCP 服务器可让 Gemini CLI 直接与您的 GKE 集群互动,从而能够检查资源、读取日志,并帮助您调试问题,同时全面了解集群的实时状态。这样一来,AI 就从静态代码分析器转变为能够了解基础设施实时状态的主动问题排查助理。
配置 GKE MCP 扩展程序
默认情况下,Gemini CLI 是一种通用工具。通过创建配置文件来配置 GKE MCP 服务器。
- 👉💻 首先,如果您仍在 Gemini CLI 中,请输入
/quit退出。 - 👉💻 运行以下命令以创建扩展程序目录:
mkdir -p ~/.gemini/extensions/gke - 👉💻 运行以下命令以创建配置文件。此命令会自动将您的
PROJECT_ID注入到文件中:cat << EOF > ~/.gemini/extensions/gke/gemini-extension.json { "name": "gke", "version": "1.0.0", "mcpServers": { "container": { "httpUrl": "https://container.googleapis.com/mcp", "authProviderType": "google_credentials", "oauth": { "scopes": ["https://www.googleapis.com/auth/container"] }, "timeout": 30000, "headers": { "x-goog-user-project": "$PROJECT_ID" } } } } EOF - 👉💻 启动 Gemini CLI:
gemini - 在 Gemini CLI 中输入
/mcp,验证 MCP 服务器是否已启用。
问问 Gemini,使用集群状态进行调试
- 调试失败的部署:现在,问问 Gemini 检查集群并根据其发现的问题修复清单。
👉💬 在 Gemini CLI 中输入以下提示:The frontend deployment is failing. Can you use your tools to check the logs and events of the pods, and then fix it?
Gemini 会使用 MCP 工具在后台调用kubectl命令。它会发现ImagePullBackOff错误,说明原因,并建议正确的修复方法。 - 解决复杂问题:让它查看日志,找出应用级错误。
👉💬 在 Gemini CLI 中输入以下提示:Check the logs for the 'contacts' pod. Why is it failing to connect to the database?
它会发现连接被拒绝的错误,并将其追溯到config.yaml中的端口不匹配或服务名称不匹配问题! - 迭代:继续让 Gemini 修复您在第 0 阶段发现的其他问题。
👉💬 在 Gemini CLI 中输入以下提示:Check if the service 'contacts' is correctly routing traffic to its pods
👉💬 在 Gemini CLI 中输入以下提示:Are there any pods failing due to resource limits?
注意:如果您遇到问题,或者想从头开始重试,可以随时通过从 cymbal-bank 目录运行 ../break.sh 将 Kubernetes 清单重置回初始的损坏状态。
7. 第 4 阶段:赋能团队(Agent Skills)
最后,通过创建自定义 Agent Skills,根据您的特定需求扩展 AI 的功能。
什么是代理技能?
智能体技能是指令、脚本和资源的软件包,可扩展 AI 智能体以执行专门的任务。它们可让您将组织标准编入代码并自动执行复杂的工作流。技能位于特定目录中,并包含一个用于定义其行为的 SKILL.md 文件。通过创建技能,您可以确保 AI 遵循一致的、可重复的流程,而不是即兴发挥。
典型的技能目录如下所示:
my-skill/
├── SKILL.md # Main instruction file (Required)
├── scripts/ # Helper scripts (Optional)
└── resources/ # Templates or data files (Optional)
构建 Kubernetes 问题排查技能
Gemini CLI 提供了一种强大的方式,可使用自然语言来搭建技能框架,而无需手动创建这些文件。
假设您想创建一个名为 k8s-troubleshooter 的技能,以自动执行您刚刚执行的步骤。
- 通过提示创建技能:您可以问问 Gemini CLI,根据您今天所学的知识为您创建技能。
👉💬 在 Gemini CLI 中输入以下提示:Create a new skill called 'k8s-troubleshooter' that helps diagnose issues with Kubernetes manifests and cluster state. It should be able to analyze pod logs, events, and resource descriptions to identify common deployment problems and configuration errors.
与调用工具或执行操作时类似,Gemini CLI 应该会告知您,您的提示已激活其“技能创建器”技能。这是 Gemini CLI 中预配置的技能,可让 Gemini 创建代理技能。
Gemini 应该会征求您的许可,以创建技能目录。选择“1. 允许一次”以批准。
Gemini 会自动执行以下操作:- 在
~/.gemini/skills/k8s-troubleshooter/中创建目录。 - 根据您的提示生成包含指令的
SKILL.md文件。 - 创建标准资源目录。
- 在
- 重启 Gemini CLI:
👉💻 关闭 Gemini CLI (/quit),然后重新启动:gemini - 验证技能是否已加载:
👉💻 在 Gemini CLI 中输入/skills,验证技能是否处于有效状态。您应该会在列表中看到k8s-troubleshooter。 - 实际应用:现在,调用技能:
👉💬 在 Gemini CLI 中输入以下提示:Use the k8s-troubleshooter skill to find out why the contacts service is failing.
AI 会遵循SKILL.md中的结构化计划,而不是即兴发挥,从而获得更一致的结果。
练习:构思自己的技能
想想您的日常工作流程。您可以使用技能自动执行哪些重复性任务?
- 创意:在部署之前,使用技能审核清单是否符合安全性方面的最佳实践。
- 创意:一种根据工作负载类型生成复杂 GKE 集群配置的技能。
8. 总结
本实验演示了一种与云基础架构互动的新方式,即通过不同级别的 AI 上下文逐步完成任务。通过从零上下文到完整的基础设施上下文(Gemini CLI + GKE MCP),您会发现 AI 助理在了解您的文件和集群状态后,效率会大幅提升。
实验总结
- 上下文很重要:您会发现,没有上下文的 AI 工具无法帮助解决特定的代码库问题。
- 终端上下文:您可以使用 Gemini CLI 直接从工作区分析本地文件并识别配置错误。
- 完整上下文调试:您将 Gemini CLI 与 MCP 搭配使用,让 AI 通过将代码库文件与实时集群状态相关联来诊断和修复复杂问题。
- 可扩展性:您将了解技能以及如何使用技能将组织知识编成代码。
清理
为避免持续产生费用,请运行收尾清理脚本。请注意,如果您在 Qwiklabs 上运行本实验,则无需执行此步骤。
👉💻 从研讨会的目录中运行以下命令:
cd ~/devrel-demos/codelabs/ai-toolkit-lab-1/
./teardown.sh
后续步骤
以下是一些建议,供您进一步阅读:
- Gemini CLI 文档:Gemini CLI 的官方文档。
- GKE 文档:所有 GKE 文档的着陆页。
- Google Cloud 上的平台工程:有关如何在 Google Cloud 上开展平台工程的指南。
- GKE 上的 AI 和机器学习:有关在 GKE 上运行 AI/机器学习工作负载的文档。
- Google Cloud 架构中心:有关在 Google Cloud 上构建工作负载的指导信息和最佳实践。
9. 附录:清单损坏的解决方案
如果您遇到问题或想验证错误,请参阅以下列表,了解 manifests-broken/ 目录中引入的破坏性更改以及如何修复这些更改:
config.yaml中的格式错误的网址:- 错误:
TRANSACTIONS_API_ADDR: "ledgerwriter::8080"(双冒号)。 - 原因:应用无法解析地址,导致连接错误。
- 修复:将其改回
"ledgerwriter:8080"。
- 错误:
contacts.yaml中的标签不一致:- 错误:服务选择器设置为
app: contacts-backend而不是contacts。 - 原因:服务找不到 Pod(仍具有
app: contacts),因此流量不会被路由。 - 修复:将选择器更改为
app: contacts。
- 错误:服务选择器设置为
userservice.yaml中的端口不匹配:- 错误:服务
targetPort设置为8081而不是8080。 - 原因:发送到服务的流量将被转发到错误的容器端口,导致连接被拒绝。
- 修复:将
targetPort更改回8080。
- 错误:服务
config.yaml中服务名称不一致:- 错误:
BALANCES_API_ADDR: "balance-reader:8080"(而非balancereader)。 - 原因:由于服务名为
balancereader,因此主机名无法在 DNS 中解析。 - 修复:将其改回
"balancereader:8080"。
- 错误:
contacts.yaml中的映像拉取政策:- 错误:
imagePullPolicy: Never。 - 原因:K8s 不会从注册表中拉取映像,而是假设映像位于本地。它会失败并显示
ErrImagePull。 - 修复:移除相应行或将其设置为
IfNotPresent。
- 错误:
userservice.yaml中的就绪探测失败:- 错误:路径已更改为
/healthz,而不是/ready。 - 原因:容器不提供
/healthz,因此探测失败,并且 pod 永远不会标记为就绪。 - 修复:将路径改回
/ready。
- 错误:路径已更改为
contacts.yaml中的资源限制:- 错误:内存限制设置为
10Mi而不是128Mi。 - 原因:应用需要更多内存才能启动,导致其被 OOMKilled。
- 修复:恢复内存限制。
- 错误:内存限制设置为
frontend.yaml中缺少环境变量:- 错误:已移除
REGISTERED_OAUTH_CLIENT_ID环境变量。 - 原因:如果缺少预期的环境变量,应用可能会失败或停用某些功能。
- 修复:恢复环境变量定义。
- 错误:已移除
frontend.yaml中的 ConfigMap 键不匹配:- 错误:
key: DEMO_USER而不是DEMO_LOGIN_USERNAME。 - 原因:K8s 无法在 ConfigMap 中找到相应密钥,导致容器无法启动。
- 修复:将密钥改回
DEMO_LOGIN_USERNAME。
- 错误:
userservice.yaml中的图片名称存在拼写错误:- 错误:
user-service而不是userservice。 - 原因:注册表中不存在相应映像,导致
ImagePullBackOff。 - 修复:更正了映像名称。
- 错误:
contacts.yaml中的服务账号问题:- 错误:
bank-of-anthos-sa而不是bank-of-anthos。 - 原因:服务账号不存在或缺少权限。
- 修复:使用正确的 ServiceAccount 名称。
- 错误: