[Jenkins]使用Docker容器配置编译环境

首先通过Docker容器保存好完整的开发环境,在Jenkins任务中调用容器进行工程的编译。完美~~~

章节

完成在Jenkins中使用Docker容器配置编译环境,需要解决以下几个问题:

  1. 如何在Jenkins中操作Docker
  2. 如何在任务中使用Docker容器?
  3. 如何在任务中使用自建Docker容器?

如何在Jenkins中操作Docker

当前通过容器方式启动Jenkins,为了在容器内部操作Docker,需要在启动命令时配置如下参数,将宿主机docker挂载到容器中

1
2
3
4
5
6
7
8
$ docker run -it -v "/var/run/docker.sock:/var/run/docker.sock" -v "/usr/bin/docker:/usr/bin/docker" --privileged zjykzj/ubuntu:18.04 bash
root@33d1b5a78d6e:/#
root@33d1b5a78d6e:/#
root@33d1b5a78d6e:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33d1b5a78d6e zjykzj/ubuntu:18.04 "bash" 5 seconds ago Up 4 seconds hungry_allen
45f17a91fbe5 pch18/baota "/bin/sh -c /entrypo…" 2 weeks ago Up 2 hours (unhealthy) baota
root@33d1b5a78d6e:/#

docker-compose.yml配置Jenkins如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.7"
services:
jenkins:
labels:
AUTHOR: "zhujian <zjzstu@github.com>"
container_name: jenkins
user: jenkins
image: jenkins/jenkins:latest
volumes:
- "jenkins_home:/var/jenkins_home"
- "/var/run/docker.sock:/var/run/docker.sock"
- "/usr/bin/docker:/usr/bin/docker"
ports:
- "7070:8080"
- "50000:50000"
restart: always
tty: true
stdin_open: true
privileged: true
volumes:
jenkins_home:
external: true

如何在任务中使用Docker容器

首先需要创建pipeline任务,然后在Jenkinsfile文件中配置docker容器

1
2
3
4
5
6
7
8
9
10
11
12
pipeline {
agent {
docker { image 'node:7-alpine' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}

运行日志如下,任务通过创建一个id=1000的用户(如果容器内部没有该用户,则临时创建)进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/docker-pipeline
[Pipeline] {
[Pipeline] isUnix
[Pipeline] sh
+ docker inspect -f . node:7-alpine
.
[Pipeline] withDockerContainer
Jenkins seems to be running inside container 2bb93fceca94d9f07d4bbd725627b46b54a711a2107d0feb665da63b2796c40f
$ docker run -t -d -u 1000:1000 -w /var/jenkins_home/workspace/docker-pipeline --volumes-from 2bb93fceca94d9f07d4bbd725627b46b54a711a2107d0feb665da63b2796c40f -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** node:7-alpine cat
$ docker top 334e777678d89ec4b3ca8fe8146c97da6324999afe311c827c3df5d513f76d93 -eo pid,comm
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ node --version

v7.10.1
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 334e777678d89ec4b3ca8fe8146c97da6324999afe311c827c3df5d513f76d93

$ docker rm -f 334e777678d89ec4b3ca8fe8146c97da6324999afe311c827c3df5d513f76d93
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

permission denied

执行过程中出现如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
...
[Pipeline] sh
+ docker inspect -f . node:7-alpine

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/node:7-alpine/json: dial unix /var/run/docker.sock: connect: permission denied
[Pipeline] isUnix
[Pipeline] sh
+ docker pull node:7-alpine
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/create?fromImage=node&tag=7-alpine: dial unix /var/run/docker.sock: connect: permission denied
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE

jenkins容器中以root身份可以运行docker ps,但是以jenkins身份无法运行docker ps,不知道之前为什么可以运行

找到两种解决方案,

1
$ chmod 777 /var/run/docker.sock

如何在任务中使用自建Docker容器

最简单的方式就是创建自建容器时,保证编译命令对任意用户均可操作,也就是说,其执行命令需要放置于以下路径中

1
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'

并设置其可执行权限对所有用户可操作

相关阅读