环境信息
- Jenkins jenkinsci/blueocean:2.346.3
- GitLab Community Edition 13.9.6
- Docker 19.03.15
本文档记录 GitLab 上面的代码更新时,使用 Jenkins 自动构建 Docker 镜像的过程。
配置过程
使用 docker 启动 Jenkins 容器
docker run -d -p 8080:8080 --name jenkins \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /data/JenkinsData_blueocean/:/var/jenkins_home/ \ -u root \ jenkinsci/blueocean
|
Jenkins 配置
以下分别记录使用 freestyle
和 Pipeline
类型的构建镜像的配置过程
创建 freestyle
类型的 Item 构建镜像
在 源码管理(Source Code Management)
中配置 git 地址,并配置认证
默认情况下,在构建时,Jenkins 会先从配置的 Git 地址拉取代码到 Jenkins 目录: /var/jenkins_home/workspace/${PROJECT_NAME}
在 构建(Build)
中 Add build step
,选择构建类型为 Execute shell
,此处构建的示例项目代码结构如下,其中 Dockerfile 路径为 k8s/server/Dockerfile
.: index.html k8s
./k8s: server
./k8s/server: Dockerfile
|
使用如下 shell 脚本
#!/bin/sh
DATA=`date +%Y%m%d%H%M`
DIR='.'
LOG=${DIR}/docker_build_result.log
DOCKER_REGISTRY='harbor.a.com'
DOCKER_REGISTRY_PROJECT='test'
PROJECT='test_project' ENV='uat'
docker build -t ${PROJECT}-${ENV}-${Branch}:${DATA} -f k8s/server/Dockerfile ${DIR} | tee ${LOG}
docker tag ${PROJECT}-${ENV}-${Branch}:${DATA} ${DOCKER_REGISTRY}/${DOCKER_REGISTRY_PROJECT}/${PROJECT}-${ENV}-${Branch}:${DATA}
docker login -u admin -p Harbor12345 ${DOCKER_REGISTRY}
docker push ${DOCKER_REGISTRY}/${DOCKER_REGISTRY_PROJECT}/${PROJECT}-${ENV}-${Branch}:${DATA}
RESULT=`cat ${LOG} | tail -n 1`
grep "Successfully tagged " ${LOG}
exit $?
|
其中的 ${Branch}
来自 参数化的构建
使用 Jenkins Pipeline 构建镜像
创建 Pipeline
类型的工程
Advanced Project Options
中选择 Pipeline from SCM
,并配置 Git 的 url 及认证信息。Script Path
默认为 Jenkinsfile
(位于代码根目录)
Jenkinsfile
内容如下:
Jenkinsfilepipeline { agent any environment { PROJECT='test_admin' HARBOR_CREDENTIALS = credentials('habor') GIT_CREDENTIALS = credentials('git') GIT_URL = "http://${GIT_CREDENTIALS_USR}:${GIT_CREDENTIALS_PSW}@git.wkctrlsys.com:18081/jiafeimao/api.git" DATA="${sh(script: 'date +%Y%m%d%H%M', returnStdout:true)}" LOG='./docker_build_result.log' DOCKER_REGISTRY='harbor.my.com' DOCKER_REGISTRY_PROJECT='test' BRANCH = "${params.Branch}" DIR = '.' TAG = "${PROJECT}-${BRANCH}:${DATA}" } stages { stage('CHECKOUT') { steps { // 清空 workspace sh "rm -rf ${env.WORKSPACE}/*" sh "rm -rf ${env.WORKSPACE}/.git" sh "git clone -b ${BRANCH} ${GIT_URL} ." } } stage('BUILD') { steps { sh 'docker build -t ${TAG} -f k8s/server/Dockerfile ${DIR} | tee ${LOG}' } } stage('PUSH') { steps { sh 'docker tag ${TAG} ${DOCKER_REGISTRY}/${DOCKER_REGISTRY_PROJECT}/${TAG}' sh 'docker login -u ${HARBOR_CREDENTIALS_USR} -p ${HARBOR_CREDENTIALS_PSW} ${DOCKER_REGISTRY}' sh 'docker push ${DOCKER_REGISTRY}/${DOCKER_REGISTRY_PROJECT}/${TAG}' } } } }
|
常见错误
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
错误场景
使用 Docker 部署的 Jenkins,在构建 Docker 镜像时,Jenkins 中的 docker 为客户端,使用的 Server 端是宿主机的 Docker Daemon,默认情况下,docker 客户端是通过 unix:///var/run/docker.sock
连接 Docker 服务端,此文件在 Jenkins 容器中不能直接访问,所以导致出现上述错误。
解决思路
针对此种情况,需要让 docker 客户端可以正确的连接到 docker 服务端
解救方法
为 docker 客户端指定 docker 服务端,可以采取以下方法
- 将宿主机的
/var/run/docker.sock
挂载到 Jenkins 容器docker run -d -p 8080:8080 --name jenkins -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
|
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
错误场景
使用 Docker 部署的 Jenkins,默认情况下,容器中使用 jenkins
用户运行,无权限访问 /var/run/docker.sock
,可以使用如下命令,在启动容器时使用 root
用户运行
docker run -d -p 8080:8080 --name jenkins \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /data/JenkinsData_blueocean/:/var/jenkins_home/ \ -u root \ jenkinsci/blueocean
|
WorkflowScript: 3: Invalid agent type “docker” specified. Must be one of [any, label, none]
错误原因
没有 docker 相关的插件导致,安装插件 Docker Pipeline