jenkins定制docker镜像


1、官方镜像

github:https://github.com/jenkinsci/jenkins

官网下载地址:https://www.jenkins.io/download/

image-20200805141836889

docker官方仓库:https://hub.docker.com/r/jenkins/jenkins/tags

image-20200805141858372

2、jenkins访问主机docker

1
docker pull jenkins/jenkins:lts-alpine

alpine镜像仓库:https://pkgs.alpinelinux.org/packages

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir -p /etc/docker
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://k8spv7nq.mirror.aliyuncs.com"]
}

systemctl daemon-reload
systemctl restart docker

cat /etc/group | grep docker
# docker:x:994:

mkdir -p /data/jenkins && cd /data/jenkins
vi Dockerfile

2.1、Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM jenkins/jenkins:lts-alpine
USER root
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update \
&& apk add -U tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk add sshpass \
&& apk add git \
&& apk add docker

RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN mkdir -p /opt/maven/repository

2.2、构建镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker build --build-arg dockerGid=`cat /etc/group | grep docker | cut -d ':' -f3` -t cz-jenkins:lts-alpine .
docker build -t cz-jenkins:lts-alpine .

docker run -it -d --name jenkins \
-p 8081:8080 -p 50000:50000 \
-v /data/jenkins/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
cz-jenkins:lts-alpine

docker logs -f jenkins

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# eeb8ac6da55e4d58b5dec50bc9d093c8

firewall-cmd --permanent --add-port=8081/tcp

http://172.18.1.51:8081/pluginManager/advanced
# 修改为:
# http://mirror.serverion.com/jenkins/updates/update-center.json

http://172.18.1.51:8081/reload
http://172.18.1.51:8081/

3、jenkins-slave访问主机docker

3.1、构建Jenkins Slave镜像环境准备

构建Jenkins Slave镜像环境准备:
代码拉取:git,安装git命令
单元测试:忽略,这不是我们擅长的,如果公司有可以写进来
代码编译:maven,安装maven包
构建镜像:Dockerfile文件、docker命令(通过挂载宿主机docker)
推送镜像:docker命令(通过挂载宿主机docker)
镜像启动后支持slave: 下载官方slave.jar包(获取:http://10.40.6.213:30006/jnlpJars/slave.jar
启动 slave.ja包:jenkins-slave启动脚步(通过参考文档URL)
maven配置文件:settings.xml (这里配置阿里云的仓库源)

获取相关文件:
Dockerfile
jenkins-slave 启动脚步
settings.xml
slave.jar

1
2
mkdir -p /data/jenkins-slave && cd /data/jenkins-slave
wget http://172.18.1.51:8081/jnlpJars/slave.jar

3.2、jenkins-slave启动脚本

1
[root@centos7cz jenkins-slave]# vi jenkins-slave
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# cat jenkins-slave
#!/usr/bin/env sh

if [ $# -eq 1 ]; then

# if `docker run` only has one arguments, we assume user is running alternate command like `bash` to inspect the image
exec "$@"

else

# if -tunnel is not provided try env vars
case "$@" in
*"-tunnel "*) ;;
*)
if [ ! -z "$JENKINS_TUNNEL" ]; then
TUNNEL="-tunnel $JENKINS_TUNNEL"
fi ;;
esac

# if -workDir is not provided try env vars
if [ ! -z "$JENKINS_AGENT_WORKDIR" ]; then
case "$@" in
*"-workDir"*) echo "Warning: Work directory is defined twice in command-line arguments and the environment variable" ;;
*)
WORKDIR="-workDir $JENKINS_AGENT_WORKDIR" ;;
esac
fi

if [ -n "$JENKINS_URL" ]; then
URL="-url $JENKINS_URL"
fi

if [ -n "$JENKINS_NAME" ]; then
JENKINS_AGENT_NAME="$JENKINS_NAME"
fi

if [ -z "$JNLP_PROTOCOL_OPTS" ]; then
echo "Warning: JnlpProtocol3 is disabled by default, use JNLP_PROTOCOL_OPTS to alter the behavior"
JNLP_PROTOCOL_OPTS="-Dorg.jenkinsci.remoting.engine.JnlpProtocol3.disabled=true"
fi

# If both required options are defined, do not pass the parameters
OPT_JENKINS_SECRET=""
if [ -n "$JENKINS_SECRET" ]; then
case "$@" in
*"${JENKINS_SECRET}"*) echo "Warning: SECRET is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_SECRET="${JENKINS_SECRET}" ;;
esac
fi

OPT_JENKINS_AGENT_NAME=""
if [ -n "$JENKINS_AGENT_NAME" ]; then
case "$@" in
*"${JENKINS_AGENT_NAME}"*) echo "Warning: AGENT_NAME is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_AGENT_NAME="${JENKINS_AGENT_NAME}" ;;
esac
fi

#TODO: Handle the case when the command-line and Environment variable contain different values.
#It is fine it blows up for now since it should lead to an error anyway.

exec java $JAVA_OPTS $JNLP_PROTOCOL_OPTS -cp /usr/share/jenkins/slave.jar hudson.remoting.jnlp.Main -headless $TUNNEL $URL $WORKDIR $OPT_JENKINS_SECRET $OPT_JENKINS_AGENT_NAME "$@"
fi

3.3、maven源配置文件settings.xml

maven源配置文件settings.xml,这里配置阿里云的源。

1
[root@centos7cz jenkins-slave]# vi settings.xml
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
# cat settings.xml
<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<pluginGroups>
</pluginGroups>

<proxies>
</proxies>

<servers>
</servers>

<mirrors>
<mirror>
<id>central</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>

<profiles>
</profiles>

</settings>

3.4、Dockerfile

1
[root@centos7cz jenkins-slave]# vi Dockerfile
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
FROM alpine:latest
USER root

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update
RUN apk add -U tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
&& wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-2.31-r0.apk \
&& apk add glibc-2.31-r0.apk
RUN apk add openjdk8 \
&& apk add maven \
&& apk add protoc \
&& apk add grpc \
&& apk add git \
&& apk add docker

RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers

COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave

ENTRYPOINT ["jenkins-slave"]

3.5、构建镜像

1
2
3
docker build --build-arg dockerGid=`cat /etc/group | grep docker | cut -d ':' -f3` -t cz-jenkins-slave:lts-alpine .

docker run --net=host -v /var/run/docker.sock:/var/run/docker.sock cz-jenkins-slave:lts-alpine docker ps

4、定制maven镜像

4.1、Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM alpine:latest
USER root

ENV LANG C.UTF-8
ENV TZ Asia/Shanghai

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update

RUN apk add -U tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone

RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
&& wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-2.31-r0.apk \
&& apk add glibc-2.31-r0.apk

RUN apk add openjdk8 \
&& apk add maven \
&& apk add protoc \
&& apk add grpc \
&& apk add docker

为了调用protoc,一定要安装glibc

https://github.com/sgerrand/alpine-pkg-glibc

否则会碰到如下问题:

https://github.com/xolstice/protobuf-maven-plugin/issues/23

用Alpine跑了JDK8的镜像结果发现,JDK还是无法执行.后来翻阅文档才发现
Java是基于GUN Standard C library(glibc)
Alpine是基于MUSL libc(mini libc)

所以Alpine需要安装glibc的库,以下是官方给出wiki
https://wiki.alpinelinux.org/wiki/Running_glibc_programs

1
2
> > [ERROR] Failed to execute goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.6.1:compile (default) on project nacos-grpc-iface: An error occurred while invoking protoc: Error while executing process.: Cannot run program "/var/jenkins_home/workspace/nacos-grpc-k8s@2/nacos-grpc-iface/target/protoc-plugins/protoc-3.12.2-linux-x86_64.exe": error=2, No such file or directory -> [Help 1]
> >
1
2
3
4
5
6
7
docker build -t czharbor.com/devops/cz-maven:3.6.3-alpine .

docker run -it czharbor.com/devops/cz-maven:3.6.3-alpine
java -version
mvn -v

docker push czharbor.com/devops/cz-maven:3.6.3-alpine

1