1、目标
通过jenkins pipeline部署maven项目,其中项目打包成docker镜像,镜像存储在harbor中。通过ansible-playbook在项目主机运行新构建镜像。此处不再描述jenkins pipeline部分,主要写ansible-playbook部分。
jenkins pipeline harbor docker ansible部署maven项目详见上一篇博文
2、pipeline代码
pipeline {
agent {
label "master"
}
environment {
DOCKER_NAME='你的容器名'/*运行的docker容器名称*/
DOCKER_TAG=createVersion()/*时间戳,作为版本*/
HARBOR_URL='你的harbor地址'/*harbor地址*/
HARBOR_REP='你的仓库名'/*镜像仓库名*/
HARBOR_CRT='你的harbor凭证'/*jenkins上配置的harbor凭证*/
}
stages {
stage('git pull'){
steps {
sh 'pwd'
/*jenkins上配置的git凭证和地址*/
git credentialsId: '你的git凭证', url: '你的git地址'
}
}
stage('mvn install') {
steps {
script {
try {
sh 'pwd'
sh 'mvn --version'
/*用maven打包项目,此处掉过单元测试*/
sh 'mvn clean install -DskipTests'
currentBuild.result="SUCCESS"
} catch (e) {
currentBuild.result="FAILURE"
throw e
} finally {
}
}
}
}
stage('image build') {
steps {
script {
/*在harbor上有更多镜像,构建主机只保留最后一次构建镜像。$是groovy的特殊字符,需要用\转义*/
sh """docker rmi \$(docker images | grep ${DOCKER_NAME} | sed -n '1,\$p' | awk '{print \$3}') || true"""
def customImage=docker.build("${HARBOR_URL}/${HARBOR_REP}/${DOCKER_NAME}:${DOCKER_TAG}")
sh 'pwd'
withDockerRegistry(url: "http://${HARBOR_URL}", credentialsId: "${HARBOR_CRT}") {
/* Push the container to the custom Registry */
customImage.push()
}
}
}
}
stage('restart docker container') {
steps {
script {
sh 'pwd'
/*指定ansible-playbook的yml文件和DOCKER_TAG参数。其他参数在ansible-playbook的vars中维护,也可以全部都传参*/
sh '''
ansible-playbook /etc/ansible/roles/pipeline/pipeline.yml -e "DOCKER_TAG=${DOCKER_TAG}"
'''
}
}
}
}
}
def createVersion() {
// 定义一个版本号作为当次构建的版本,输出结果 20201116165759_1
return new Date().format('yyyyMMddHHmmss') + "-${env.BUILD_ID}"
}
3、ansible-playbook部分
上一篇用ansible命令也可以直接链接需要运行项目的主机组进行操作。但ansible不够灵活。直接用ansible-playbook的roles。roles可以根据业务需求灵活的进行配置
ansible用法
ansible-playbook用法
以上两篇博文总结的非常好,这两天该博客网站整改,暂时看不了哈
3.1、ansible-playbook roles目录结构
[root@jenkins pipeline]# pwd
/etc/ansible/roles/pipeline # 在roles先新建的一个名为pipeline的roles
[root@jenkins pipeline]# tree
.
├── default
├── files # 存放用来在远程主机执行包、可执行程序等
├── handlers # 存放handlers
├── meta
├── pipeline.yml # ansible-playbook入口yml文件
├── tasks
│ └── main.yml # 核心ansible任务文件
├── templates #存放配置临时文件
└── vars
└── main.yml #存放参数变量
3.2、ansible-playbook入口yml文件
[root@jenkins pipeline]# more pipeline.yml
- hosts: web # 主机组,默认在/etc/ansible/hosts中配置
remote_user: root # 远程执行的用户
roles:
- pipeline
3.3、tasks的yml文件
步骤:
- name: stop container #
docker_container: #用docker_container停止容器
name: "{{ DOCKER_NAME }}"
state: absent #使用absent停止容器
- name: create working_dir directory
file:
path: "{{ WORK_DIR }}"
- name: docker login
docker_login: #用docker_login登录harbor
registry: "{{ HARBOR_ULR }}"
username: "{{ HARBOR_USERNAME }}"
password: "{{ HARBOR_PASSWORD }}"
reauthorize: yes
- name: pull image
docker_image: #用docker_image从harbor拉取镜像
name: "{{ HARBOR_ULR }}/{{ HARBOR_REP }}/{{ DOCKER_NAME }}:{{ DOCKER_TAG }}"
source: pull
- name: run containers
docker_container: #用docker_container运行容器
name: "{{ DOCKER_NAME }}"
image: "{{ HARBOR_ULR }}/{{ HARBOR_REP }}/{{ DOCKER_NAME }}:{{ DOCKER_TAG }}"
ports: "8080:8080" #映射端口
volumes:
- "{{ WORK_DIR }}:/var/local/java"
- "/etc/localtime:/etc/localtime:ro"#解决docker时区问题,映射成和主机相同时区
- name: delete old image#删除旧镜像,使用shell脚本,其中true防止没有旧镜像是出错
shell: "docker images | grep {{ DOCKER_NAME }} | sed -n '3, $p' | awk '{print $3}' | xargs docker rmi | true"
3.3、vars参数
[root@jenkins pipeline]# vim vars/main.yml
DOCKER_NAME: 你的容器名
WORK_DIR: 工作路径
HARBOR_ULR: 你的harbor地址
HARBOR_USERNAME: 你的harbor用户名
HARBOR_PASSWORD: 你的harbor密码
HARBOR_REP: 你的镜像仓库名