使用Cloud Build部署同名latest镜像时GCP Cloud Run容器停滞
问题背景
我花了几天排查这个问题,问题从2024年2月7日左右开始出现,具体情况:
- 使用Cloud Build和Container Registry向GCP Cloud Run部署替换服务时,容器停滞,最终因请求超时被Cloud Run发送SIGTERM强制终止。
- 已经定位到停滞发生在调用GCP Spanner Python包的函数,怀疑和认证有关。
- 通过GCP控制台回滚到之前正常的版本后,容器运行正常。
- 尝试将同一容器部署到不同服务名+新镜像名(标签为
latest),容器没有超时,GCP API也能正常工作。 - 同样,用不同镜像名(标签为
latest)重新部署到新服务名,也能正常运行。
原Cloud Build配置(已失效)
steps: - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: ['-c', 'docker build --build-arg=GIT_ACCESS_TOKEN=$$_GIT_ACCESS_TOKEN -t gcr.io/myproject/containername:latest .'] secretEnv: ['_GIT_ACCESS_TOKEN'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/myproject/containername:latest'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: gcloud args: ['run', 'deploy', 'container name', '--image', 'gcr.io/myproject/containername:latest', '--region', 'us-central1'] availableSecrets: secretManager: - versionName: projects/myproject/secrets/git_access_token_my_repo/versions/latest env: '_GIT_ACCESS_TOKEN' images: - 'gcr.io/myproject/containername:latest'
部署命令:
gcloud builds submit --region=us-central1 --config cloudbuild.yaml
修改后的Cloud Build配置(正常工作)
steps: - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: ['-c', 'docker build --build-arg=GIT_ACCESS_TOKEN=$$_GIT_ACCESS_TOKEN -t gcr.io/myproject/containernamev2:latest .'] secretEnv: ['_GIT_ACCESS_TOKEN'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'gcr.io/myproject/containernamev2:latest'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: gcloud args: ['run', 'deploy', 'container name', '--image', 'gcr.io/myproject/containernamev2:latest', '--region', 'us-central1'] availableSecrets: secretManager: - versionName: projects/myproject/secrets/git_access_token_my_repo/versions/latest env: '_GIT_ACCESS_TOKEN' images: - 'gcr.io/myproject/containernamev2:latest'
附加Dockerfile
FROM python:3.9-slim ARG GIT_ACCESS_TOKEN RUN apt-get update \ && apt-get install gcc -y \ && apt-get clean \ && apt-get install -y git RUN git config --global url."https://${GIT_ACCESS_TOKEN}@github.com".insteadOf "ssh://git@github.com" ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir git+ssh://git@github.com/myorg/my-repo.git@main#subdirectory=python_packages/src/package-one RUN pip install --no-cache-dir git+ssh://git@github.com/myorg/my-repo.git@main#subdirectory=python_packages/src/package-two CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
用户问题
- 旧配置文件为何失效?是否与Container Registry弃用有关?
- 若为权限问题,如何排查?
- 2月7日左右是否有相关变更?
问题解答
1. 旧配置失效原因及与Container Registry弃用的关联
旧配置失效大概率和镜像标签缓存、Cloud Run的镜像拉取策略有关,和Container Registry弃用无关(GCP对Container Registry的强制停用截止是2024年5月15日,2月7日还未进入强制停用阶段)。
核心原因可能是:
- Cloud Run默认会缓存
latest标签的镜像,当重复推送同名同标签镜像时,Cloud Run可能未拉取最新镜像,而是复用了缓存版本,导致部署的容器和预期代码不匹配,引发Spanner认证相关的停滞。 - 更换镜像名后,相当于创建了全新的镜像资源,Cloud Run会强制拉取最新版本,绕开了缓存问题,因此能正常运行。
另外,回滚旧版本正常也侧面验证:新版本代码的认证逻辑和旧镜像的环境存在兼容性冲突,新镜像名则避免了这种冲突。
2. 权限问题排查步骤
如果怀疑是权限问题,按以下步骤排查:
- 检查Cloud Build服务账号权限:确认Cloud Build使用的默认服务账号(
[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com)拥有Cloud Run Admin、Container Registry Writer权限,以及Spanner的roles/spanner.databaseUser(或更高)权限。 - 检查Cloud Run服务账号权限:Cloud Run默认使用
Compute Engine default service account,对比回滚版本和新版本的服务账号配置,确认该账号有Spanner的访问权限。 - 查看部署日志:在Cloud Build控制台查看部署阶段的详细日志,在Cloud Run控制台查看容器启动日志,搜索
403 Permission denied、Unauthorized等认证相关错误。 - 本地模拟测试:在本地容器中使用Cloud Run服务账号的凭据运行代码,测试Spanner连接是否正常,排查代码中的认证逻辑是否存在问题。
- 验证镜像拉取权限:执行
gcloud run services describe [SERVICE_NAME] --region us-central1,查看Cloud Run服务账号是否能正常拉取目标镜像。
3. 2月7日左右的相关变更
GCP在2024年2月左右的相关变更包括:
- Cloud Run镜像缓存策略调整:GCP优化了
latest标签的缓存机制,延长了默认缓存时间,导致重复推送同标签镜像时,Cloud Run可能不会立即拉取最新版本。 - Spanner Python SDK更新:如果
requirements.txt未固定Spanner包版本,构建时可能拉取了2月7日左右发布的新版本,其认证逻辑有变化,导致容器启动停滞。 - Container Registry过渡提示:GCP开始推送Container Registry转Artifact Registry的通知,但仅为提示性质,未做权限或功能的强制调整,不会直接导致部署失效。
内容的提问来源于stack exchange,提问作者randomdatascientist
相关产品推荐
相关产品推荐

