Shell脚本推送Docker镜像至GCR失败,但终端执行正常求排查
Docker镜像推送到GCR时权限验证失败(脚本执行出错,手动命令正常)
问题描述
我在通过Shell脚本将Docker镜像推送到Google Container Registry(GCR)时,持续收到以下错误:
unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials
但跳过WSL2直接在PowerShell中执行命令docker --debug push gcr.io/PROJECT_ID/IMAGE_NAME:latest时,镜像可以正常推送。奇怪的是,在同一个PowerShell窗口中运行该Shell脚本仍会触发上述错误。我已经按照GCR高级认证文档操作过,但问题依旧。
相关脚本代码如下:
#!/bin/bash set -e set -ex # Define variables PROJECT_ID="XXXXX" IMAGE_NAME="XXXXX" SERVICE_NAME="XXXXX" REGION="XXXXX" function load_env_vars() { local env_file="$1" local env_vars="" while IFS="=" read -r key value; do env_vars="${env_vars} --set-env-vars ${key}=${value}" done < "${env_file}" echo "${env_vars}" } # Authenticate to GCP gcloud auth configure-docker # Build the Docker image docker build -t gcr.io/${PROJECT_ID}/${IMAGE_NAME} . # Push the Docker image to Google Container Registry docker --debug push gcr.io/${PROJECT_ID}/${IMAGE_NAME}:latest # Load environment variables from .env file env_vars=$(load_env_vars ".env") # Deploy the image to Cloud Run gcloud run deploy ${SERVICE_NAME} \ --image gcr.io/${PROJECT_ID}/${IMAGE_NAME} \ --region ${REGION} \ --platform managed \ --verbosity=debug \ --allow-unauthenticated \ ${env_vars}
可能的原因及解决方法
1. WSL2与PowerShell的Docker上下文不一致
PowerShell中的Docker可能连接的是Windows本地的Docker Desktop守护进程,而WSL2脚本中的Docker可能使用的是WSL2内部的守护进程,导致认证配置未同步。
- 解决:在WSL2中执行
docker context use default切换到与PowerShell一致的上下文;同时确保Docker Desktop已开启"Use the WSL 2 based engine",并勾选对应的WSL发行版。
2. gcloud auth configure-docker配置不完整
脚本中执行的认证命令可能未指定GCR域名,或者WSL2环境下的gcloud账号与PowerShell不一致。
- 解决:在脚本中明确指定项目并重新配置Docker认证:
同时执行gcloud config set project ${PROJECT_ID} gcloud auth configure-docker gcr.io --quietgcloud auth list对比WSL2和PowerShell中的登录账号,确保一致。
3. 环境变量传递问题
PowerShell中的DOCKER_CONFIG环境变量未传递到WSL2脚本中,导致Docker读取的认证配置路径错误。
- 解决:在脚本开头添加环境变量同步,替换为你的Windows用户目录路径:
export DOCKER_CONFIG=/mnt/c/Users/你的用户名/.docker
4. set -e的隐性退出影响
脚本开启了set -e(出错即退出),可能gcloud auth configure-docker执行时存在隐性错误未被捕获,导致后续push失败。
- 解决:暂时注释
set -e,或给认证命令添加--quiet参数避免交互式提示:gcloud auth configure-docker --quiet
修改后的脚本参考
#!/bin/bash set -x # Define variables PROJECT_ID="XXXXX" IMAGE_NAME="XXXXX" SERVICE_NAME="XXXXX" REGION="XXXXX" function load_env_vars() { local env_file="$1" local env_vars="" while IFS="=" read -r key value; do # 跳过空行和注释行 [[ -z "$key" || "$key" =~ ^# ]] && continue env_vars="${env_vars} --set-env-vars ${key}=${value}" done < "${env_file}" echo "${env_vars}" } # 同步Windows Docker配置路径(替换为你的实际路径) export DOCKER_CONFIG=/mnt/c/Users/你的用户名/.docker # 配置GCP项目及Docker认证 gcloud config set project ${PROJECT_ID} gcloud auth configure-docker gcr.io --quiet # 构建镜像(添加版本标签) docker build -t gcr.io/${PROJECT_ID}/${IMAGE_NAME}:latest . # 推送镜像到GCR docker --debug push gcr.io/${PROJECT_ID}/${IMAGE_NAME}:latest # 加载.env环境变量 env_vars=$(load_env_vars ".env") # 部署到Cloud Run gcloud run deploy ${SERVICE_NAME} \ --image gcr.io/${PROJECT_ID}/${IMAGE_NAME}:latest \ --region ${REGION} \ --platform managed \ --verbosity=debug \ --allow-unauthenticated \ ${env_vars}
内容的提问来源于stack exchange,提问作者Victor Valar
相关产品推荐
相关产品推荐

