全部版块 我的主页
论坛 新商科论坛 四区(原工商管理论坛) 商学院 管理科学与工程
73 0
2025-11-17

本文档详尽记载了一次从服务无反应开始,到最终实现 Envoy 代理集群自动化滚动更新的全过程。

1. 初始问题

我们试图通过

curl

命令访问部署在
http://www.jpgcp.cloud

上的聊天服务,但请求被长时间挂起,没有回应。
curl -N -X POST "http://www.jpgcp.cloud/py-chat-deepseek-svc/api/v1/chat" -H "Content-Type: application/json" -d '{"message": "Why is the sky blue?"}'

2. 排查过程

2.1. 后端服务日志分析

猜测
: 后端 Cloud Run 服务 (

py-chat-deepseek-svc

) 在调用上游 LLM 时被阻碍。
行动
: 使用
gcloud logging read

查看 Cloud Run 服务日志。
发现
: 日志中没有我们
curl

请求的记录,反而充斥着来自外部 IP 对
.env

,
.git/config

等路径的扫描请求,且均返回
403 Not Authenticated


初步结论
: 请求在抵达应用代码之前就被 GCP 前端阻止了。

2.2. 基础设施架构深入研究

重要信息
: 用户指出,在 Cloud Run 服务前设有一个 Envoy 代理,此代理部署在 GCE 虚拟机上,并负责处理 GCP 身份验证 (

gcp_authn

)。
修正方向
: 问题重点从 Cloud Run 转向 Envoy 代理及其所在 GCE 虚拟机。

2.3. Envoy 虚拟机与配置不符

猜测
: 运行在 GCE 上的 Envoy 配置可能不准确。
行动
: 使用

gcloud compute instances list

找到名为
my-envoy-vm-b5hr

的可疑虚拟机。
SSH 连接到该虚拟机,尝试查找并读取
/etc/envoy/envoy.yaml

配置文件。
发现
: 服务器上的
envoy.yaml

是一个过时版本,完全没有定义与聊天服务相关的路由 (
/py-chat-deepseek-svc

) 和集群。而我们本地代码库
envoy-config

中的
envoy.yaml

是一个更新、更全面的版本。
结论
: 部署流程失败,最新的配置没有同步到虚拟机上。

2.4. 代管实例组 (MIG) 的发现

猜测
: 为什么虚拟机会使用旧配置?它是手动创建的吗?
行动
: 使用

gcloud compute instances describe

检查
my-envoy-vm-b5hr


managedBy

字段,意外返回
null


根据用户提示,使用
gcloud compute instance-groups managed list

检查项目中的 MIG。
关键发现
: 项目中确实存在一个名为
my-envoy

的 MIG。进一步使用
list-instances

确认,
my-envoy-vm-b5hr

正是由这个 MIG 管理的实例。
最终结论
: 直接修改单个虚拟机的配置是无效且错误的,因为任何修改都会在 MIG 重启或修复实例时丢失。唯一正确的路径是更新 MIG 所使用的实例模板,然后触发滚动更新。

2.5. 自动化更新流程的建立与调试

我们的目标转变为:创建一个自动化的 Cloud Build 管道,用于正确地更新 MIG。
构建新镜像
: 我们确认使用

cloudbuild.yaml

和 Packer (
gce.pkr.hcl

) 用于构建包含最新
envoy.yaml

的虚拟机镜像 (
packer-gce-envoy

)。
成功运行
gcloud builds submit --config cloudbuild.yaml .

,生成了最新的镜像。
创建自动化更新管道 (
cloudbuild_refresh_envoy_proxy.yaml

)
: 目标
: 创建一个新管道,该管道能基于最新镜像创建新实例模板,并用它来滚动更新 MIG。
迭代调试过程
: 初版
: 尝试创建实例模板并设置给 MIG。
失败 & 修复 (权限问题)
: 日志显示 Cloud Build 使用的服务账号 (
terraform@...

) 缺少
compute.images.get

权限。我们确认该权限已存在,排除了权限问题。
失败 & 修复 (网络问题)
: 日志显示找不到名为
default

的网络。我们在
instance-templates create

命令中明确添加了
--subnet=tf-vpc0-subnet0

参数。
失败 & 修复 (IP 问题)
: 日志显示找不到名为
static-ext-ip1

的静态 IP。我们在
instance-templates create

命令中将
--address

参数的值从名称
static-ext-ip1

改为直接使用 IP 地址
34.39.2.90


失败 & 修复 (防火墙问题)
: 即使 IP 正确,请求仍可能被防火墙拦截。我们在
instance-templates create

命令中添加了
--tags=http-server,https-server

,以确保新创建的 VM 能匹配允许 HTTP/HTTPS 流量的防火墙规则。

3. 最终解决方案

我们最终创建了一个稳健的、自动化的 Cloud Build 管道

cloudbuild_refresh_envoy_proxy.yaml

,并为其设置了定时调度。
3.1. 最终工作流程
开发/修改
: 开发者在本地修改
configs/envoy.yaml

文件并推送到 Git 主分支。
构建镜像 (可选手动)
: 运行第一个 Cloud Build 管道 (
cloudbuild.yaml

),使用 Packer 将最新的配置烘焙到一个新的
packer-gce-envoy

虚拟机镜像中。
定时滚动更新

Cloud Scheduler 作业在每天凌晨 3 点自动激活第二个 Cloud Build 流水线(

cloudbuild_refresh_envoy_proxy.yaml

),此流水线将自动执行以下详细步骤,实现 Envoy 集群的每日自动化更新。

这一过程不仅解决了初始的服务无响应难题,还构建了一个遵循 IaC 最佳实践的、自动化的基础设施管理与部署解决方案。

3.2.

cloudbuild_refresh_envoy_proxy.yaml

代码与解析

以下是用于滚动更新的 Cloud Build 配置文件内容:

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: create_instance_template
entrypoint: 'bash'
args:
- '-c'
- |
set -e
TEMPLATE_NAME="my-envoy-template-$(date +%s)"
echo "Creating new instance template: $$TEMPLATE_NAME"
gcloud compute instance-templates create $$TEMPLATE_NAME \
--project=jason-hsbc \
--image=packer-gce-envoy \
--image-project=jason-hsbc \
--region=europe-west2 \
--machine-type=e2-medium \
--subnet=tf-vpc0-subnet0 \
--service-account=terraform@jason-hsbc.iam.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--tags=http-server,https-server \
--address=34.39.2.90
# Write the template name to a file to be used by the next step
echo $$TEMPLATE_NAME > /workspace/template_name.txt
echo "Successfully created instance template."
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: rolling_update_mig
entrypoint: 'bash'
args:
- '-c'
- |
set -e
TEMPLATE_NAME=$(cat /workspace/template_name.txt)
# Dynamically find the current MIG name
MIG_NAME=$(gcloud compute instance-groups managed list --project=jason-hsbc --filter="name~'my-envoy-'" --format="value(name)")
if [ -z "$$MIG_NAME" ]; then
echo "ERROR: No managed instance group found with prefix 'my-envoy-'"
exit 1
fi
echo "Found MIG: $$MIG_NAME. Applying new template: $$TEMPLATE_NAME"
gcloud compute instance-groups managed set-instance-template $$MIG_NAME \
--project=jason-hsbc \
--zone=europe-west2-c \
--template=$$TEMPLATE_NAME
echo "Successfully set new instance template for MIG."
# When using a custom service account, logging options must be explicitly set.
options:
logging: CLOUD_LOGGING_ONLY

代码解析

create_instance_template

步骤:基于最新的

packer-gce-envoy

镜像,创建一个包含完整配置(如网络、IP 地址、标签等)的实例模板。

rolling_update_mig

步骤:动态查找当前的 Envoy MIG,并指令其使用新创建的模板以启动滚动更新。

options

解决使用自定义服务账户时需明确设置日志记录选项的问题。

3.3. 创建定时调度任务

为了达成每日自动刷新的目标,我们建立了一个 Cloud Scheduler 任务来定期触发上述 Cloud Build 过程。

  1. 建立 Cloud Build 触发机制 (如果尚未存在)
  2. 首先,需设立一个手动的 Cloud Build 触发机制来激活

    cloudbuild_refresh_envoy_proxy.yaml
    gcloud beta builds triggers create manual \
    --name="trigger-refresh-envoy-mig" \
    --project="jason-hsbc" \
    --repo="https://github.com/nvd11/envoy-config.git" \
    --repo-type="github" \
    --branch="main" \
    --build-config="cloudbuild_refresh_envoy_proxy.yaml" \
    --region="europe-west2"
            

    (注意: 在调试过程中,我们发现需要运用

    --repository

    参数替代

    --repo

    --repo-type

    ,或确保 gcloud 版本兼容。为简化文档,这里展示的是理想化的指令。)

  3. 取得触发机制 ID
  4. gcloud beta builds triggers describe trigger-refresh-envoy-mig \
    --project=jason-hsbc \
    --region=europe-west2 \
    --format="value(id)"
            
  5. 建立 Cloud Scheduler 任务
  6. 利用上一步获得的触发机制 ID,创建一个每日执行的调度任务。

    gcloud scheduler jobs create http refresh-envoy-mig-daily \
    --project="jason-hsbc" \
    --location="europe-west2" \
    --schedule="0 3 * * *" \
    --uri="https://cloudbuild.googleapis.com/v1/projects/jason-hsbc/locations/europe-west2/triggers/[TRIGGER_ID]:run" \
    --http-method="POST" \
    --oauth-service-account-email="terraform@jason-hsbc.iam.gserviceaccount.com" \
    --description="Daily task to refresh the Envoy MIG via executing a Cloud Build trigger."
            

    (注意: 需要将

    [TRIGGER_ID]

    替换为前一步骤得到的真实 ID。)

    此任务将以

    terraform

    服务账户的身份,在每天早上 3 点向 Cloud Build API 发出一个 POST 请求,以此启动我们的循环更新过程。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群