后端与接口
把已有 AI 推理负载(Cloud Run /…
当用户已有 AI 推理工作负载并希望迁移到 GKE 上用 vLLM 自托管推理时,按四阶段流程完成发现、设计、实施与流量切换。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
把已有 AI 推理负载(Cloud Ru特定
解决思路
- 先做范围判断:若用户是要在 GKE 上从零部署全新模型服务、没有现存负载要迁移,停止并改用 gke-inference 技能;若用户明确要求用 Gemini Cloud Assist MCP 自动化迁移,停止手动流程并回复四点:说明本技能仅用于手动 CLI 迁移、解释 MCP 能力(gemini_cloud_assist:ask_cloud_assist 做基础设施分析、gemini_cloud_assist:invoke_operation 做资源变更)、给出 Gemini Cloud Assist MCP 文档链接、给出 Intent to Infrastructure Codelab 链接;若用户只是顺带提到 MCP 或明确拒绝 MCP,则继续手动流程;若完全没提 MCP,直接进入当前阶段,仅在首次发现回复中加一句说明存在 MCP 自动化替代方案。
- 执行策略:Phase 1 在用户授权后直接执行只读 gcloud 检查命令(list、describe)并汇总结果;Phase 2-4 把清单写到磁盘,然后把确切的 gcloud 和 kubectl 命令交给用户执行,除非用户明确要求你运行,否则不要执行变更类命令(apply、create、delete、集群或 IAM 变更);纯信息与排障问题只给 markdown 指引、清单和建议命令,不执行任何操作。
- 每个架构回复开头打印进度指示行:`**Migration Progress:** [● Discovery] ➔ [○ Solution Design] ➔ [○ Implementation] ➔ [○ Validation]`,用 ● 标记当前阶段。
- 阶段路由:若当前目录存在 migration-state.md,先读取它并从记录的阶段和值继续,只有值缺失或被用户提示推翻时才重新提问;新迁移请求走 Phase 1;发现已完成或要求架构设计/YAML 生成走 Phase 2;权重已暂存或直接要部署步骤走 Phase 3;负载已运行或要健康检查/测试走 Phase 4。
- Phase 1 发现六类属性:源平台与服务配置(Cloud Run / Gemini API / Agent Platform / 自建 VM,容器镜像 tag、环境变量、CPU/内存、密钥绑定);模型规格(名称与参数量、目标精度与量化容忍度、是否 gated 模型需要 HF_TOKEN、模型卡或 config.json 中的特殊架构要求如 --trust-remote-code 或 rope scaling);目标 GKE 与硬件(集群名与区域、加速器偏好 L4/A100/H100/TPU v5e、Spot/CCC 还是按需、区域配额);模型存储与暂存(权重当前位置、Cloud Storage FUSE 还是 Managed Lustre);流量画像与负载均衡(流量量级、并发、突发性、是否需要 GKE Inference Gateway、是否要 HPA——必须问,不能假设);模型等价性(仅 Gemini API/Agent Platform 源:在用哪些 Gemini 模型与 API 特性、用哪个开源模型替代、如何评估输出质量、客户端代码需改动之处,因为 vLLM 端点是 OpenAI 兼容而非 Gemini API 兼容)。
- 发现执行:先明确请求用户授权再执行检查命令;授权后运行 `gcloud run services list --format="table(metadata.name,status.url,status.latestReadyRevisionName)"` 枚举服务,再运行 `gcloud run services describe {service_name} --format="yaml(spec.template.spec.containers,spec.template.metadata.annotations,spec.template.spec.serviceAccountName,spec.template.spec.containerConcurrency)"` 只提取镜像、环境变量、资源限制、并发和密钥绑定;用 `gcloud container clusters list` 和 `gcloud container clusters describe {cluster_name}` 检查集群配置、Workload Identity 和加速器池;用 `gcloud ai endpoints list` 或 `gcloud storage buckets list` 定位模型产物和存储桶;检查本地工作区配置文件与环境变量;所有发现命令都用 --format 过滤,绝不把完整未过滤资源描述拉进对话。
- 汇总发现结果并询问缺失项,若有未解决或有歧义项必须获得用户明确确认才能进入 Phase 2;若全部无歧义,可把发现汇总与 Phase 2 方案放在同一回复中,用同一个审批门。
- 用户确认发现汇总后,写入 migration-state.md:每个清单类别一节记录确认值,最后一行 `Current phase: <phase name>`,每次阶段推进都更新该行。
- Phase 2 设计:对每个主要组件(负载均衡、自动扩缩、单节点 vs 多节点)给出推荐的 Golden Path 选项与替代方案;若用户要 HPA,设计必须处理 LLM 自动扩缩陷阱并推荐自定义指标(默认队列大小)。
- 加速器选择参考 GPU platforms 和 Plan your TPU configuration in GKE 文档;注意 assets/ 中的清单模板仅支持 GPU,若用户选 Cloud TPU 要明确说明并基于 GKE TPU 服务文档而非本技能模板。
- 存储选择参考 GCP AI Storage Options 文档,为模型暂存与服务推荐最佳存储方案。
- 用确定性 VRAM 公式做硬件与显存估算:`VRAM_total = ((Parameters × 2 / Quantization) + KV_Cache_Overhead) × 1.2`,其中 Parameters 为十亿参数量,Quantization 对 16 位取 1、8 位取 2、4 位取 4,KV_Cache_Overhead(GB) = (2 × n_layers × n_kv_heads × d_head × Context Length × Batch Size × Precision Bytes) / 10^9,层结构未知时按模型权重内存的约 0.2 倍估算,1.2 为 20% 安全余量;映射到加速器时用显卡全部显存(如 L4 的 24GB)比较,不要用被 --gpu-memory-utilization 折减后的显存,否则会双重计算余量而选高一档。
- 集群与节点设计:用 Custom Compute Classes (CCC) 提高加速器可获得性,使用 GKE 托管 GPU 驱动;vLLM Deployment 必须用 `nodeSelector: cloud.google.com/compute-class: {compute_class_name}` 选择节点;若用户拒绝 CCC 只要按需节点,改用 `cloud.google.com/gke-accelerator: {accelerator_type}` 并完全跳过 ccc-profile.yaml,不要应用无人引用的 ComputeClass。
- 模型暂存设计:源为 Hugging Face 或目标为 Lustre 且源为 GCS 时,用 Job 下载/复制权重;源为 GCS 且目标为 GCS FUSE 时跳过暂存;用 Cloud Storage FUSE 或 Lustre CSI 挂载存储。
- 生成清单:读取 assets/ 下模板(vllm-deployment.yaml.tmpl、ccc-profile.yaml.tmpl、gke-inference-gateway.yaml.tmpl、storage-config.yaml.tmpl、model-staging-job.yaml.tmpl),代入 Phase 1 参数,把生成的 YAML 保存到当前目录;vllm-deployment.yaml 中把 Phase 1 发现的模型特殊架构参数(如 --trust-remote-code)显式注入容器 args;gke-inference-gateway.yaml 默认用 `gatewayClassName: gke-l7-rilb`,HTTPRoute 把 /v1 流量路由到 vLLM ClusterIP 服务 `{workload_name}-vllm-svc` 的 8000 端口;若用非 gcsfuse-csi 的存储类(如 lustre-csi),从 storage-config.yaml 移除 gcsfuse.cloud.google.com 注解。
- 推理栈默认用 vLLM(vllm/vllm-openai);从 Vertex AI 迁移可保留 Vertex AI Model Garden 镜像(如 pytorch-vllm-serve);无论选哪个镜像,vLLM Deployment 必须显式设置 `command: ["python", "-m", "vllm.entrypoints.openai.api_server"]` 以绕过可能崩溃的入口脚本(如 Vertex AI 镜像里的 gcs_download_launcher.sh)。
- 始终固定明确的稳定 vLLM 镜像 tag,绝不用 :latest;设计时解析当前稳定版本(查 vLLM releases 页或取 `gcloud container ai profiles manifests create` 输出中的 tag)并记录到 migration-state.md,不要复用上次迁移或文档示例中的 tag。
- 通过 GKE Gateway API 暴露服务,默认区域内部应用负载均衡器(gatewayClassName: gke-l7-rilb);若用户需要 LLM 感知负载均衡(按 KV 缓存利用率、队列深度或 LoRA 适配器位置路由),提供 GKE Inference Gateway 升级方案:它需要 InferencePool 资源作为 HTTPRoute 后端而非 Service,且仅支持 gke-l7-rilb 和 gke-l7-regional-external-managed 两种 GatewayClass;生成 InferencePool 清单前先获取 About GKE Inference Gateway 文档,不要凭记忆编写。
- 多节点模型用 LeaderWorkerSet (LWS) 配合 vLLM。
- 安全:始终用 GKE Workload Identity 访问 Google Cloud API;gated 模型(Llama 3、Gemma 等)的 HF_TOKEN 绝不以字面值写入 Deployment 或 Pod 规格,用 `env.valueFrom.secretKeyRef` 引用(如 hf-secret);绝不把 Kubernetes Secret 清单写到磁盘或放进模板,而是明确指示用户在应用任何其他清单之前先用 CLI 创建:`kubectl create secret generic hf-secret --namespace={namespace} --from-literal=hf_api_token=<YOUR_HF_TOKEN>`,由用户自己替换真实值;若用户已把 token 粘贴到对话中,视为已泄露,所有命令和清单用 `<YOUR_HF_TOKEN>` 占位,并建议迁移完成后到 https://huggingface.co/settings/tokens 吊销并重新签发。
- 端点暴露:Gateway 默认用内部类 gke-l7-rilb;vLLM 的 OpenAI 兼容端点没有内置认证,若用户要求外部暴露,明确警告未认证的外部监听器等于把推理 API 敞开在 GPU 账单上,必须获得明确决定并加前置控制(IAP、认证 API 网关或严格客户端白名单)后才生成外部暴露的 Gateway 清单。
- 模型存储与冷启动:把模型暂存到 Cloud Storage 桶以避免重复下载;通过集群上的 Job 执行暂存(保存为 model-staging-job.yaml 并让用户运行 `kubectl apply -f model-staging-job.yaml`),避免把大权重下载到本地工作站、也避免每次容器重启重新下载;大多数负载用 Cloud Storage FUSE,超低延迟 PiB 级需求用 Managed Lustre。
- 每个挂载 Cloud Storage FUSE 卷的 Pod 必须带注解 `gke-gcsfuse/volumes: "true"`(注入 FUSE sidecar),且必须以绑定到拥有模型桶 `roles/storage.objectUser` 的 Google 服务账号的 Kubernetes ServiceAccount 运行(通过 Workload Identity);缺任一项都会挂载或读取失败,排障时先查这两项。
- 可观测性默认用 Google Cloud Managed Service for Prometheus 配合 DCGM 指标做 GPU 深度可见性。
- 自动扩缩:不要假设用户要 HPA,必须在发现阶段询问;若不要 HPA 就省略所有自动扩缩清单;若要 HPA,警告 LLM 自动扩缩陷阱——标准 CPU、内存、GPU 显存利用率指标不可靠,因为 vLLM 预分配 KV 缓存显存会一直显示高利用率;推荐基于反映真实并发或队列深度的自定义服务指标(如 vllm:num_requests_waiting 或批大小),除非用户特别指定其他指标否则默认用队列大小;实现可用 GKE Custom Metrics(Stackdriver Adapter)或 KEDA。
- Phase 3 实施:确认计费、API 和 IAM 权限就绪;提供 gcloud 命令配置存储与集群前置(如启用 Cloud Storage FUSE CSI 驱动)并配置 Workload Identity IAM 绑定;Gateway API 预检——明确让用户先运行 `gcloud container clusters update <CLUSTER_NAME> --gateway-api=standard` 再应用路由清单,避免 CRD-not-found 错误。
- 创建存储资源(Cloud Storage 桶或 Managed Lustre 文件系统)。
- 按 Phase 2 设计做模型暂存:若模型已在 GCS 且用 GCS FUSE 则跳过;Hugging Face 源且为 gated 模型时,先让用户在本地运行 `kubectl create secret generic hf-secret ...` 再应用任何 Job 或 Deployment,然后运行 `kubectl apply -f model-staging-job.yaml`;GCS 到 Lustre 源时运行 `kubectl apply -f model-staging-job.yaml`(配置为用 gcloud storage cp 等);任何活跃暂存 Job 用 `kubectl wait --for=condition=complete job/{workload_name}-model-staging --timeout=90m` 设完成门(超时按模型大小调整),失败时先 `kubectl logs job/{workload_name}-model-staging` 再重试。
- 工作负载部署:提供 `kubectl apply -f storage-config.yaml`、`kubectl apply -f ccc-profile.yaml`、`kubectl apply -f vllm-deployment.yaml`、`kubectl apply -f gke-inference-gateway.yaml`;确保 vLLM Deployment 把暂存的模型权重从 PVC 挂载到 /models;若为 gated 模型创建了 Secret,确保 Deployment 正确引用;vLLM 的 `--model` 设为暂存本地路径 `/models/{model_name}`,绝不用 Hugging Face repo ID(否则每次 Pod 启动都重新下载全部权重,静默破坏暂存步骤);用 `--served-model-name={model_id}` 保留对 API 客户端的公开模型名。
- 验证发布:用 `kubectl rollout status deployment/{workload_name}-vllm --timeout=30m` 和 `kubectl get pods -l app={workload_name}-vllm -o wide` 确认;若失败或超时,直接带观察到的错误进入排障指引,不要在命令输出已给出答案时还问用户部署是否成功;只问集群无法验证的结果(例如响应质量是否与源系统一致)。
- Phase 4 验证与切换:推荐健康检查命令 `kubectl get pods`、`kubectl get nodes`、`kubectl get gateway`;用 `kubectl port-forward svc/{workload_name}-vllm-svc 8000:8000` 加示例 curl 请求 /v1/chat/completions 测试推理,并与原基础设施响应对比。
- 流量切换:不要自动实施流量迁移;提供已就绪的内部 GKE 端点、基于相关代码库的迁移建议、标准 GKE 发布方式(如更新现有 Deployment 清单指向新服务),不要花哨的灰度或蓝绿;只有用户明确要求才提供更高级的流量迁移选项。
- 回滚准备:流量切换前确认源服务保持部署(可缩容但不可删除),直到 GKE 端点承载生产流量达到用户选定的时长;提供一条命令或配置变更即可把流量恢复到源服务;只有用户宣布迁移稳定后,才提供下线源服务的命令。
- 编制验证报告汇总所有健康检查结果与推理测试结果,并明确请求用户最终批准以完成迁移工作流。
- 排障指引:推荐 `kubectl logs {pod_name}` 查容器启动日志、`kubectl describe pod {pod_name}` 查 Pod 初始化状态;检查目标区域的 GPU/TPU 配额;若 curl 返回 Connection refused 但 Pod 是 Running,服务引擎(如 vLLM)可能仍在做 JIT 编译(Triton PTX 或 Torch Inductor)或捕获 CUDA 图,这在权重加载后可能还要几分钟,让用户查日志并等待 `Uvicorn running on http://0.0.0.0:8000`(或等价)日志出现再怀疑网络问题;检查 GKE Workload Identity 绑定、PVC 挂载健康(Cloud Storage FUSE)和 GKE Inference Gateway 监听器配置。
适用边界 · 注意事项
- 用户要在 GKE 上从零部署全新 AI 模型服务、没有现存负载要迁移时(应改用 gke-inference 技能)。
- 用户明确要求用 Gemini Cloud Assist MCP 服务器自动化迁移时(应停止手动流程并转向 MCP)。
- 用户选择 Cloud TPU 时不能套用本技能的 assets/ GPU 清单模板,需基于 GKE TPU 服务文档另行设计。