通过jenkins pipeline部署maven项目,其中项目打包成docker镜像,镜像存储在harbor中。通过ansible-playbook在项目主机运行新构建镜像。此处不再描述jenkins pipeline部分,主要写ansible-playbook部分。
jenkins pipeline harbor docker ansible部署maven项目详见上一篇博文
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}"
'''
}
}
}
}
post {
/*任务执行成功发送邮件*/
success {
emailext (
subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_ID}]'",
body: """SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':
Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"
""",
to: "收件箱地址",
from: "发件箱地址"
)
}
/*任务执行时报发送邮件*/
failure {
emailext (
subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
body: """FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':
Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"
""",
to: "收件箱地址",
from: "发件箱地址"
)
}
}
}
def createVersion() {
// 定义一个版本号作为当次构建的版本
return new Date().format('yyyyMMddHHmmss') + "-${env.BUILD_ID}"
}
上一篇用ansible命令也可以直接链接需要运行项目的主机组进行操作。但不够灵活。直接用ansible-playbook的roles。roles可以根据业务需求灵活的进行配置
ansible用法
ansible-playbook用法
以上两篇博文总结的非常好,这两天该博客网站整改,暂时看不了哈
[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 #存放参数变量
[root@jenkins pipeline]# more pipeline.yml
- hosts: web # 主机组,默认在/etc/ansible/hosts中配置
remote_user: root # 远程执行的用户
roles:
- pipeline
- 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"
a、查找ansible的docker相关方法:
[root@jenkins ~]# ansible-doc -l | grep docker
docker_stack docker stack module
docker_config Manage docker configs
docker_swarm_info Retrieves facts about Docker Swarm cluster
docker_swarm Manage Swarm cluster
docker_container_info Retrieves facts about docker container
docker_secret Manage docker secrets
docker_volume Manage Docker volumes
docker_login Log into a Docker registry
docker_host_info Retrieves facts about docker host and lists of objects of the services
docker_swarm_service docker swarm service
docker_image Manage docker images
docker_network_info Retrieves facts about docker network
docker_container manage docker containers
docker_volume_info Retrieve facts about Docker volumes
docker_node_info Retrieves facts about docker swarm node from Swarm Manager
docker_network Manage Docker networks
docker_prune Allows to prune various docker objects
docker_image_info Inspect docker images
docker_compose Manage multi-container Docker applications with Docker Compose
docker_swarm_service_info Retrieves information about docker services from a Swarm Manager
docker_node Manage Docker Swarm node
b、本次使用三个docker方法:docker_container、docker_login、docker_image
需要在远程主机上安装python的docker
[root@node1 ~]# yum -y install python-pip #如果没有安装pip,安装epel源后直接yum安装pip
[root@node1 ~]# pip install docker
c、查看docker相关用法:
ansible在线文档
在线帮助手册上有样例,更方便
也可以直接用命令调出帮助手册:
[root@jenkins ~]# ansible-doc -s docker_image
[root@jenkins pipeline]# vim vars/main.yml
DOCKER_NAME: 你的容器名
WORK_DIR: 工作路径
HARBOR_ULR: 你的harbor地址
HARBOR_USERNAME: 你的harbor用户名
HARBOR_PASSWORD: 你的harbor密码
HARBOR_REP: 你的镜像仓库名
在pipeline中的post部分定义了任务执行成功或者失败发送邮件策略。任务执行成功发送成功邮件,ansible-playbook部分(如远程主机一台宕机)执行失败也会发送失败邮件。
配置发送邮件位置:系统管理->系统配置: Extended E-mail Notification