自托管GitLab Runner构建Docker镜像时无法连接Docker守护进程求助
问题详情
在Amazon Linux 2的EC2实例上部署自托管GitLab Runner,已完成git、docker、gitlab-runner的安装与注册,配置.gitlab-ci.yml用于构建Node.js应用、生成Docker镜像并部署到AWS,但执行build-docker-image-aws任务时触发错误:
ERROR: Cannot connect to the Docker daemon at [MASKED]. Is the docker daemon running?
已将ec2-user和gitlab-runner用户加入docker组,两者均能正常执行docker run hello-world;sudo service docker status显示Docker正在运行,docker.socket状态也为active,但CI任务仍失败。
相关配置文件
.gitlab-ci.yml 配置
# 修正语法:补充stages关键字 stages: - install - lint - build-nodejs-app - test - build-docker-image install_dependencies: image: node:15.6.0-alpine stage: install script: - npm install format: image: node:15.6.0-alpine stage: lint script: - npm install --global prettier - prettier --write . lint: image: node:15.6.0-alpine stage: lint script: - npm run lint build: image: node:15.6.0-alpine stage: build-nodejs-app script: - npm install - npm run build artifacts: paths: - build/ test_index_file: image: node:15.6.0-alpine stage: test script: - test -f build/index.html unit_tests: image: node:15.6.0-alpine stage: test script: - npm install - npm run test build-docker-image-aws: image: docker:stable services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" stage: build-docker-image before_script: - mkdir -p ~/.aws - echo $AWS_ACCESS_KEY_ID > ~/.aws/credentials - echo $AWS_SECRET_ACCESS_KEY >> ~/.aws/credentials script: - docker info - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - cp -R build/ app/ - docker build -t $DOCKER_IMAGE_NAME . - docker push $DOCKER_IMAGE_NAME - docker run --rm -v ~/.aws:/root/.aws amazon/aws-cli ecs update-service --cluster $ECS_CLUSTER --service $ECS_SERVICE --force-new-deployment dependencies: - build
/etc/gitlab-runner/config.toml 配置
[[runners]] name = "My Runner" url = "https://gitlab.com/" id = 0 token = REDACTED token_obtained_at = 0001-01-01T00:00:00Z token_expires_at = 0001-01-01T00:00:00Z executor = "docker" [runners.cache] MaxUploadedArchiveSize = 0 [runners.docker] tls_verify = false image = "ubuntu:latest" privileged = true disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/var/run/docker.sock:/var/run/docker.sock","/opt/gitlab-runner/cache:/cache:rw"] shm_size = 0 [[runners]] name = "Runner on AWS EC2" url = "https://gitlab.com/"
解决建议
1. 修复CI配置语法错误
原.gitlab-ci.yml开头缺失stages:关键字,这会导致GitLab无法正确解析阶段定义,直接引发任务执行异常,已在上述配置中修正。
2. 消除Docker连接方式冲突
当前配置同时混用了两种Docker运行方式:挂载宿主机docker.sock(复用宿主机Docker)和docker:dind服务(启动独立Docker守护进程),这是连接失败的核心原因,二选一即可:
方案一:复用宿主机Docker(推荐)
既然宿主机Docker已正常运行且gitlab-runner用户有权限访问,直接去掉docker:dind相关配置:
修改build-docker-image-aws任务:
build-docker-image-aws: image: docker:stable stage: build-docker-image # 移除services和DOCKER_HOST变量 before_script: - mkdir -p ~/.aws # 修正AWS凭证格式:添加[default]段 - echo "[default]" > ~/.aws/credentials - echo "aws_access_key_id = $AWS_ACCESS_KEY_ID" >> ~/.aws/credentials - echo "aws_secret_access_key = $AWS_SECRET_ACCESS_KEY" >> ~/.aws/credentials - docker --version # 验证客户端与宿主机版本兼容性 script: - docker info - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - cp -R build/ app/ - docker build -t $DOCKER_IMAGE_NAME . - docker push $DOCKER_IMAGE_NAME - docker run --rm -v ~/.aws:/root/.aws amazon/aws-cli ecs update-service --cluster $ECS_CLUSTER --service $ECS_SERVICE --force-new-deployment dependencies: - build
确保Runner的config.toml中privileged=true且挂载了/var/run/docker.sock(当前配置已满足)。
方案二:修复docker:dind配置(若坚持使用)
- 确保
docker:dind服务版本与docker:stable镜像版本匹配,避免版本不兼容 - 在
before_script中添加等待Docker守护进程启动的逻辑:- while ! docker info >/dev/null 2>&1; do sleep 1; done - 建议改用TLS连接(更安全),调整变量为:
variables: DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs"
3. 修正AWS凭证格式
原before_script中写入的AWS凭证缺少[default]段,AWS CLI无法识别,已在方案一中修正。
4. 确保用户组变更生效
重启GitLab Runner服务,让gitlab-runner用户加入docker组的变更生效:
sudo gitlab-runner restart
验证权限:
sudo -u gitlab-runner docker run hello-world
5. 检查SELinux限制
Amazon Linux 2默认启用SELinux,可能阻止容器访问宿主机docker.sock,临时关闭测试:
sudo setenforce 0
若问题解决,可添加SELinux规则永久允许访问:
sudo semanage fcontext -a -t container_file_t /var/run/docker.sock sudo restorecon -v /var/run/docker.sock
内容的提问来源于stack exchange,提问作者codestein

