使用 docker 运行 jenkins 的安装配置及使用

版本信息

  • Centos-7 3.10.0-1160
  • Docker Engine 19.03.15
  • jenkinsci/blueocean Jenkins 2.346.3

安装步骤

下载镜像

官方镜像仓库 中搜索 jenkinsci/blueocean,下载最新镜像

docker pull jenkinsci/blueocean

启动 jenkins 容器

创建数据目录

mkdir /data/JenkinsData_blueocean
chmod 777 /data/JenkinsData_blueocean

启动 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
  • -v /var/run/docker.sock:/var/run/docker.sock - 在需要使用 Jenkins 构建 Docker 镜像时,Jenkins 容器中的 docker 客户端需要连接到宿主机的 Docker server
  • -v /data/JenkinsData_blueocean/:/var/jenkins_home/ - 数据持久化到宿主机目录
  • -u root - 容器中使用 root 用户运行,要使用 Jenkins 构建 Docker 镜像时,默认的 jenkins 用户无权限访问 /var/run/docker.sock

防火墙开放端口

iptables -I INPUT 7 -p tcp -m multiport --dports 8080 -j ACCEPT -m comment --comment "Jenkins"

查看初始密码

初始密码会打印在日志里面

$ docker logs jenkins
...
*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

acafa239f38043e6a54a0fde448


使用日志中显示的密码登陆 web。

Jenkins pipeline script 语法

Jenkins pipeline script 基本格式如下

pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo "Hello World"'
sh '''
echo "Multiline shell steps works too"
ls -lah
'''
}
}
stage() {
...
}
}
post {
always {
echo 'This will always run'
}
success {
echo 'This will run only if successful'
}
failure {
echo 'This will run only if failed'
}
unstable {
echo 'This will run only if the run was marked as unstable'
}
changed {
echo 'This will run only if the state of the Pipeline has changed'
echo 'For example, if the Pipeline was previously failing but is now successful'
}
}
}

agent 命令

agent 指令告诉 Jenkins 在哪里以及如何执行 Pipeline 或者 Pipeline 子集。 所有的 Pipeline 都需要 agent 指令。 [2]

下面的 pipeline 使用 docker 做为执行环境,并指定 docker 镜像,当执行 Pipelin e时,Jenkins 将会自动运行指定的容器,并执行 Pipeline 中已经定义好的步骤 steps

pipeline {
agent {
docker { image 'node:7-alpine' }
}
stages {
stage('Test') {
steps {
sh 'node --version'
}
}
}
}

agent any 指令指示 Jenkins 为整个流水线分配一个执行器 (在 Jenkins 环境中的任何可用代理/节点上)和工作区

环境变量

环境变量(environment)可以设置为全局的,也可以是阶段(stage)级别的,阶段(stage)级别的环境变量只能在定义变量的阶段(stage)使用 [3]

Jenkins 流水线通过全局变量 env 提供全局环境变量,它在 Jenkinsfile 文件的任何地方都可以使用。Jenkins 流水线中可访问的完整的环境变量列表记录在 ${YOUR_JENKINS_URL}/pipeline-syntax/globals#env

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}

如果你使用 Build with Parameters 选项将流水线配置为接受参数,这些参数将作为 params 变量的成员被访问。 [5]

假设在 Jenkinsfile 中配置了名为 Greeting 的字符串参数,它可以通过 ${params.Greeting} 访问该参数

**引用环境变量时,如果使用引号,需要使用 "(双引号),不能使用 '(单引号) **

post 命令

因为 post 部分保证在 Pipeline 结束的时候运行, 所以我们可以添加通知或者其他的步骤去完成清理、通知或者其他的 Pipeline 结束任务。 [4]

pipeline {
agent any
stages {
stage('No-op') {
steps {
sh 'ls'
}
}
}
post {
always {
echo 'One way or another, I have finished'
deleteDir() /* clean up our workspace */
}
success {
echo 'I succeeeded!'
}
unstable {
echo 'I am unstable :/'
}
failure {
echo 'I failed :('
}
changed {
echo 'Things were different before...'
}
}
}

常见用法

凭证使用方法

Usernames and passwords

Manage Jenkins -> Manage Credentials 中添加 kindUsername with password 的凭据。

在 Pipeline 中配置环境变量,使用方法 credentials() 调用已配置的凭据,需要的参数为 credentials 的 ID 信息

Jenkinsfile
pipeline {
agent any

environment {
harbor_credentials = credentials('harbor.my.com')
}

stages {

stage('login harbor') {
steps {

sh 'docker login -u ${harbor_credentials_USR} -p ${harbor_credentials_PSW} ${DOCKER_REGISTRY}'

}

}
}
}

stages 中可以通过 ${harbor_credentials_USR}${harbor_credentials_PSW} 分别调用 usernamepassword [1]

environment 中变量的值为其他命令的输出

environment 中需要定义变量,变量的值为其他命令的输出,等同于 shell 中的如下定义

DATE=`date +%Y%m%d%H%M`

在 Jenkins 的 environment 中需要使用以下方式

Jenkinsfile
environment {

DATE="${sh(script: 'date +%Y%m%d%H%M', returnStdout:true)}".trim()

}

.trim() 去除变量最后的换行。

配置文件管理插件 Config File Provider

多个配置中如果有公共的配置,可以将其进行统一管理,使用 Config File Provider 插件,安装后管理页面(Manage Jenkins)会多出 Managed files 菜单项,进入后 Add a new Config 可以添加配置,同时指定 idName

示例内容,格式为 yaml,调用用时可以使用 readYaml file:"${CONFIG_FILE}" 读取内容

system:
docker_harbor_url: https://harbor.my.com
docker_hub_cre_id: habor
project:
- name: app-0
git_url: http://gitlab.my.com/app1/app.git
git_cre_id: git
- name: app-1
git_url: http://gitlab.my.com/app2/app.git
git_cre_id: git

调用方式

configFileProvider(
[configFile(fileId: 'config-yaml', variable: 'CONFIG_FILE')]) {
jenkins_props = readYaml file:"${CONFIG_FILE}"
}
echo jenkins_props.project[0].name / 输出内容: app-0 /
echo jenkins_props.project[1].git_url / 输出内容: http://gitlab.my.com/app2/app.git /
  • fileId - 为创建配置时的 id
  • variable - 将配置文件内容临时存储于指定的文件名中
  • targetLocation - 将配置文件拷贝到 ${WORKSPACE}/${targetLocation}

脚本式 Pipeline 语法中执行 shell 命令

在脚本式 Pipeline 语法中,需要执行 shell 命令及获取命令输出时,可以通过 sh 指令执行

git_commit = sh(returnStdout: true, script: "git rev-parse HEAD").trim()
echo git_commit

常见错误

find: /usr/share/jenkins/ref: No such file or directory

使用 Docker 运行 Jenkins,启动 Jenkins 容器时报错: find: /usr/share/jenkins/ref: No such file or directory,Jenkins 容器无法启动。

可能原因及解决办法

可能是因为不小心删除了某些文件导致,删除本地镜像,重新拉取镜像,启动正常。

参考链接

使用Docker安装Jenkins

脚注