You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

CircleCI通过Cloud Run部署至GKE时gcloud认证失败求助

解决CircleCI GCP GCR Orb 解析服务账号JSON失败的问题

问题背景

我尝试通过CircleCI结合Google Cloud Run将应用部署到GKE,使用官方GCP Orbs来简化配置,但在initialize gcloud步骤中始终报错:

ERROR: (gcloud.auth.activate-service-account) Could not read json file /root/gcloud-service-key.json: No JSON object could be decoded

错误原因分析

从配置和报错信息来看,主要有两个关键问题:

  1. 环境变量写入语法错误:在Prepare env vars步骤中,echo 'export GOOGLE_COMPUTE_ZONE=us-east1-b' >> BASH_ENV 缺少了$符号,应该是$BASH_ENV,这会导致这条环境变量无法正确加载,后续步骤可能读取到无效内容。
  2. 服务账号密钥传递流程冗余且易出错:你把GCP_PROJECT_KEY写入文件后,再将文件内容导出为GOOGLE_CLOUD_KEYS,这个过程容易出现格式损坏(比如换行符丢失、转义字符处理异常),导致生成的gcloud-service-key.json不是有效的JSON结构。另外,你已经在CircleCI项目设置中配置了GCLOUD_SERVICE_KEY,完全可以直接使用这个变量,不需要额外的文件读写操作。

修正后的配置方案

以下是调整后的config.yaml,重点修正了环境变量处理和服务账号密钥的传递方式:

version: 2.1
orbs:
  gcp-gcr: circleci/gcp-gcr@0.6.1
  cloudrun: circleci/gcp-cloud-run@1.0.2
executors:
  node-executor:
    docker:
      - image: node:12.8.1-stretch
  gcloud-executor:
    docker:
      - image: google/cloud-sdk
  machine-executor:
    machine: true
jobs:
  build:
    description: initial build
    executor: machine-executor
    steps:
      - checkout
  build_push_image_cloud_run_mangaged:
    executor: node-executor
    steps:
      - checkout
      - setup_remote_docker:
          docker_layer_caching: false
      - run:
          name: Prepare env vars
          command: |
            echo 'export PATH=$PATH:$HOME/.local/bin' >> $BASH_ENV
            echo 'export GOOGLE_PROJECT_ID=$GCLOUD_PROJECT' >> $BASH_ENV
            echo 'export GOOGLE_COMPUTE_ZONE=us-east1-b' >> $BASH_ENV
            echo 'export TAG=${CIRCLE_SHA1}' >> $BASH_ENV
            echo 'export IMAGE_NAME=$CIRCLE_PROJECT_REPONAME' >> $BASH_ENV
            source $BASH_ENV
      # 直接使用CircleCI项目配置的GCLOUD_SERVICE_KEY环境变量
      - gcp-gcr/gcr-auth:
          gcloud-service-key: GCLOUD_SERVICE_KEY
          google-project-id: GOOGLE_PROJECT_ID
          google-compute-zone: GOOGLE_COMPUTE_ZONE
      - gcp-gcr/build-image:
          dockerfile: Dockerfile
          google-project-id: GOOGLE_PROJECT_ID
          image: $IMAGE_NAME
          registry-url: "gcr.io"
          tag: $CIRCLE_SHA1
      - gcp-gcr/push-image:
          google-project-id: GOOGLE_PROJECT_ID
          image: $IMAGE_NAME
          registry-url: "gcr.io"
          tag: $CIRCLE_SHA1
      - cloudrun/init:
          gcloud-service-key: GCLOUD_SERVICE_KEY
          google-project-id: GOOGLE_PROJECT_ID
          google-compute-zone: GOOGLE_COMPUTE_ZONE
      - cloudrun/deploy:
          cluster: "new-cluster"
          cluster-location: "us-east1-b"
          platform: "gke"
          image: "gcr.io/$GOOGLE_PROJECT_ID/$IMAGE_NAME:$TAG"
          service-name: "orb-gcp-cloud-run"
workflows:
  build_gcloud_deploy:
    jobs:
      - build
      - build_push_image_cloud_run_mangaged:
          requires:
            - build

关键修正点说明

  • 修复环境变量写入错误:把BASH_ENV改为$BASH_ENV,确保环境变量正确写入到当前shell的配置文件中。
  • 简化服务账号密钥传递:直接使用CircleCI项目设置中已配置的GCLOUD_SERVICE_KEY环境变量,跳过手动写入文件再读取的步骤,避免格式损坏。
  • 完善镜像标签:在cloudrun/deploy步骤的image参数中加上:$TAG,确保部署的是刚构建的特定版本镜像,避免使用旧镜像。

额外建议

如果后续需要手动处理服务账号JSON,建议先对JSON内容进行base64编码后再存储到CircleCI环境变量中,解码时可以用如下命令:

echo $GCLOUD_SERVICE_KEY | base64 --decode > $HOME/gcloud-service-key.json

不过使用官方GCP Orbs的话,直接传递编码后的环境变量即可,Orb会自动处理解码逻辑。

内容的提问来源于stack exchange,提问作者vijayakumarpsg587

火山引擎 最新活动