GitLab CI无法推送Docker镜像至ECR的问题排查与方案咨询
错误原因
你使用的registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest镜像仅预装了AWS CLI等云部署工具,没有内置Docker守护进程(daemon),也未配置与GitLab Runner宿主机Docker服务的连接。之前不用该镜像能正常执行Docker命令,是因为你使用的镜像要么自带Docker daemon,要么Runner默认挂载了宿主机的Docker socket,让容器内的Docker CLI能调用宿主机的daemon。
正确实现方案
以下两种方案可同时满足AWS权限认证和Docker镜像构建推送的需求:
方案1:挂载宿主机Docker Socket复用daemon
直接将GitLab Runner宿主机的Docker socket挂载到aws-base容器内,让容器里的Docker CLI调用宿主机的daemon执行命令。需要先确认aws-base镜像是否包含Docker CLI,如果没有,要在job里安装:
deploy: image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest variables: # 配置Web Identity AssumeRole的环境变量,比如AWS_ROLE_ARN、AWS_WEB_IDENTITY_TOKEN_FILE等 before_script: # 如果aws-base镜像没有Docker CLI,安装它(以Debian/Ubuntu基础镜像为例) - apt-get update && apt-get install -y docker.io script: # 执行AWS身份认证(Web Identity AssumeRole) - aws sts assume-role-with-web-identity --role-arn $AWS_ROLE_ARN --role-session-name gitlab-ci --web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE # 登录ECR - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY # 构建并推送镜像 - docker build -t $ECR_REGISTRY/$IMAGE_NAME:$TAG . - docker push $ECR_REGISTRY/$IMAGE_NAME:$TAG # 挂载宿主机Docker socket volumes: - /var/run/docker.sock:/var/run/docker.sock # 确保Runner配置了允许挂载本地卷 tags: - docker # 指定支持挂载socket的Runner标签
方案2:使用Docker-in-Docker(DinD)服务
通过GitLab CI的services启动独立的Docker daemon,让aws-base镜像内的Docker CLI连接到该服务。这种方式不需要依赖宿主机的Docker,适合隔离性要求高的场景:
deploy: image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest services: - name: docker:dind alias: docker variables: # 配置Docker CLI连接到DinD服务 DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" DOCKER_TLS_VERIFY: 1 DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client" # AWS相关环境变量 AWS_ROLE_ARN: your-role-arn AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token AWS_DEFAULT_REGION: your-region before_script: # 安装Docker CLI到aws-base镜像 - apt-get update && apt-get install -y docker.io script: # 执行Web Identity AssumeRole认证 - aws sts assume-role-with-web-identity --role-arn $AWS_ROLE_ARN --role-session-name gitlab-ci --web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE # 登录ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY # 构建推送镜像 - docker build -t $ECR_REGISTRY/$IMAGE_NAME:$TAG . - docker push $ECR_REGISTRY/$IMAGE_NAME:$TAG # 需要Runner开启privileged模式 tags: - privileged-docker # 指定支持privileged模式的Runner标签
额外提示
- 优先选择方案1,因为复用宿主机Docker daemon更高效,无需额外资源启动DinD;
- 如果aws-base镜像已经包含Docker CLI,可以省略
before_script里的安装步骤; - 确保GitLab Runner的配置允许挂载卷(方案1)或启用privileged模式(方案2)。
内容的提问来源于stack exchange,提问作者zilcuanu
相关产品推荐
相关产品推荐

