利用 Ansible 来做 tomcat 应用的持续交付

2019 年 7 月 15 日 DevOps时代

在做持续交付这件事,想必大家都是用 Jenkins 这款程序来做基石。当然,我们这次也是用 Jenkins作为承载工具,Jenkins强大的插件是有目共睹的,有些 ansible 做起来不容易的事情交给 Jenkins 反而简单有效。下面我会详细说明怎么持续交付tomcat应用。

应用架构

本次使用的应用架构是常见的负载均衡实例。

软件版本

os:centos 6.7 X64
ansible: 2.3.1.0
python: 2.6.6
ant: 10.1
java: 1.8.0_13
tomcat: 8.5.14
Jenkins: 2.73

服务器角色

主机 角色
node1 nginx,jenkins
node130 tomcat
node131 tomcat

集群搭建

本次使用anisble playbook

---

- hosts: node130 node131
vars:
- java_version: "1.8"
- tomcat_version: "8.5.14"
- iptables_allowed_tcp_ports: ["8080"]
roles:
- java
- { role: tomcat, java_home: "/usr/java/jdk1.8.0_131" }
- iptables

- hosts: node1
vars:
- java_version: "1.8"
- nginx_version: "1.12.1"
- nginx_upstreams:
- name: upstremtest
servers:
- 192.168.77.130:8080 max_fails=2 fail_timeout=2
- 192.168.77.131:8080 max_fails=2 fail_timeout=2
- nginx_vhosts:
- listen: 80
locations:
- name: /
proxy_pass: http://upstremtest
- jenkins_version: "2.73"
- jenkins_plugins_extra:
- ansible
- ansicolor
- iptables_allowed_tcp_ports: ["80","8080"]
roles:
- ant
- java
- nginx
- jenkins
- iptables
tasks:
- name: install ansible
package: name=ansible

确保正常访问以下服务:

  • nginx http://192.168.77.129/lework

  • jenkins http://192.168.77.129:8080 帐号密码:admin/admin

  • tomcat http://192.168.77.130:8080/lework http://192.168.77.131:8080/lework

node1服务器操作

在服务器上配置 ansible playbook

# cd /etc/ansible/
# cat tomcat-deploy.yml
---

- hosts: all
serial: 1
roles:
- deploy-tomcat

# cat hosts
[node130]
192.168.77.130

[node131]
192.168.77.131

[testservers:children]
node130
node131

[testservers:vars]
ansible_ssh_user=root
ansible_ssh_pass=123456

# git clone https://github.com/kuailemy123/Ansible-roles.git /etc/ansible/roles/
# chown jenkins.jenkins /etc/ansible/

jenkins 操作

登录jenkins之后,设置工具
点击“系统管理”==》“Global Tool Configuration”

创建发布项目

配置参数化构建

配置源码仓库地址

repo: https://github.com/kuailemy123/AntSpringMVC.git

配置构建环境

配置编译

配置ansible

配置ansible变量

这里就不配置邮件通知了。

创建回滚项目

配置参数化构建

配置构建环境

配置ansible

配置anisble变量

测试

执行tomcat_deploy任务

选择发布的节点,默认all

任务执行的日志

Started by user admin
Building in workspace /var/lib/jenkins/workspace/tomcat_deploy
Cloning the remote Git repository
Cloning repository https://github.com/kuailemy123/AntSpringMVC.git
> git init /var/lib/jenkins/workspace/tomcat_deploy # timeout=10
Fetching upstream changes from https://github.com/kuailemy123/AntSpringMVC.git
> git --version # timeout=10
> git fetch --tags --progress https://github.com/kuailemy123/AntSpringMVC.git +refs/heads/*:refs/remotes/origin/*
> git config remote.origin.url https://github.com/kuailemy123/AntSpringMVC.git # timeout=10
> git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
> git config remote.origin.url https://github.com/kuailemy123/AntSpringMVC.git # timeout=10
Fetching upstream changes from https://github.com/kuailemy123/AntSpringMVC.git
> git fetch --tags --progress https://github.com/kuailemy123/AntSpringMVC.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 989ea3a6549e16e3dd4cd329ab969b47658c9d67 (refs/remotes/origin/master)
Commit message: "Create README.md"
> git config core.sparsecheckout # timeout=10
> git checkout -f 989ea3a6549e16e3dd4cd329ab969b47658c9d67
First time build. Skipping changelog.
[tomcat_deploy] $ ant -file build.xml -Ddeploy_node=all
Buildfile: /var/lib/jenkins/workspace/tomcat_deploy/build.xml

clean:
[delete] Deleting directory /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes

init:
[mkdir] Created dir: /var/lib/jenkins/workspace/tomcat_deploy/target
[mkdir] Created dir: /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes

resolve:
[echo] Getting dependencies...
[ivy:retrieve] :: Apache Ivy 2.4.0 - 20141213170938 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/usr/local/ant/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache#WebProject;working@node1
[ivy:retrieve] confs: [compile, runtime, test]
[ivy:retrieve] found org.slf4j#slf4j-api;1.7.6 in public
[ivy:retrieve] found jstl#jstl;1.2 in public
[ivy:retrieve] found ch.qos.logback#logback-classic;1.1.2 in public
[ivy:retrieve] found ch.qos.logback#logback-core;1.1.2 in public
[ivy:retrieve] found org.springframework#spring-core;4.1.3.RELEASE in public
[ivy:retrieve] found commons-logging#commons-logging;1.2 in public
[ivy:retrieve] found org.springframework#spring-beans;4.1.3.RELEASE in public
[ivy:retrieve] found org.springframework#spring-context;4.1.3.RELEASE in public
[ivy:retrieve] found org.springframework#spring-aop;4.1.3.RELEASE in public
[ivy:retrieve] found aopalliance#aopalliance;1.0 in public
[ivy:retrieve] found org.springframework#spring-expression;4.1.3.RELEASE in public
[ivy:retrieve] found org.springframework#spring-web;4.1.3.RELEASE in public
[ivy:retrieve] found org.springframework#spring-webmvc;4.1.3.RELEASE in public
[ivy:retrieve] downloading https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar ...
[ivy:retrieve] ............ (28kB)
[ivy:retrieve] .. (0kB)
..... 省略下载的信息
[ivy:retrieve] :: resolution report :: resolve 74135ms :: artifacts dl 120701ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| compile | 13 | 13 | 13 | 0 || 13 | 13 |
| runtime | 13 | 13 | 13 | 0 || 13 | 13 |
| test | 13 | 13 | 13 | 0 || 13 | 13 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#WebProject
[ivy:retrieve] confs: [compile, runtime, test]
[ivy:retrieve] 13 artifacts copied, 0 already retrieved (5920kB/79ms)

compile:
[javac] Compiling 1 source file to /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes
copy-resources:
[copy] Copying 1 file to /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes
package:
[ivy:retrieve] :: retrieving :: org.apache#WebProject
[ivy:retrieve] confs: [runtime]
[ivy:retrieve] 0 artifacts copied, 13 already retrieved (0kB/5ms)
[war] Building war: /var/lib/jenkins/workspace/tomcat_deploy/target/helloproject-20170819172002.war

main:

BUILD SUCCESSFUL
Total time: 3 minutes 19 seconds
[tomcat_deploy] $ /usr/bin/ansible-playbook /etc/ansible/tomcat-deploy.yml -i /etc/ansible/hosts -l all -f 5 -e deploy_port=8080 -e deploy_file=/var/lib/jenkins/workspace/tomcat_deploy/target/helloproject-*.war

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/new)
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/pre)
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.130]

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/new)
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/pre)
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.131]

PLAY RECAP *********************************************************************
192.168.77.130 : ok=14 changed=8 unreachable=0 failed=0
192.168.77.131 : ok=14 changed=7 unreachable=0 failed=0

Finished: SUCCESS

执行tomcat_rollback任务

选择回滚的节点,默认all

执行的日志

Started by user admin
Building in workspace /var/lib/jenkins/workspace/tomcat_rollback
[tomcat_rollback] $ /usr/bin/ansible-playbook /etc/ansible/tomcat-deploy.yml -i /etc/ansible/hosts -l all -f 5 -e deploy_rollback=true

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/new)
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/pre)
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
fatal: [192.168.77.130]: FAILED! => {"changed": true, "cmd": "/etc/init.d/tomcat start", "delta": "0:00:20.035003", "end": "2017-08-19 17:24:47.586469", "failed": true, "rc": 1, "start": "2017-08-19 17:24:27.551466", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.130]

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/new)
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/pre)
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.131]

PLAY RECAP *********************************************************************
192.168.77.130 : ok=8 changed=4 unreachable=0 failed=0
192.168.77.131 : ok=8 changed=4 unreachable=0 failed=0

Finished: SUCCESS

至此,持续交付实验就完成了,但是持续之路还是很漫长了。望大家永远前进。大家也可在发的过程中,测试发布是否是灰度发布。

for i in `seq 10000`;do curl -s -I http://192.168.77.129 | head -1;sleep 1;done;

本文转自简书,作者 lework,来源:https://www.jianshu.com/p/fca8f91ae223

近期好文推荐:

火箭还是飞机?DevOps 的两种模式

程序员自己写测试了,还要测试人员做什么?

DevOps 中高效测试基础架构的最佳实践

登录查看更多
0

相关内容

Git 是一个为了更好地管理 Linux 内核开发而创立的分布式版本控制和软件配置管理软件。 国内外知名 Git 代码托管网站有: GitHub.com Coding.net code.csdn.net ...
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
【白皮书】“物联网+区块链”应用与发展白皮书-2019
专知会员服务
93+阅读 · 2019年11月13日
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
MIT新书《强化学习与最优控制》
专知会员服务
275+阅读 · 2019年10月9日
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
Linux挖矿病毒的清除与分析
FreeBuf
14+阅读 · 2019年4月15日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
百度开源项目OpenRASP快速上手指南
黑客技术与网络安全
5+阅读 · 2019年2月12日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
占坑!利用 JenKins 持续集成 iOS 项目时遇到的问题
开源巨献:阿里巴巴最热门29款开源项目
算法与数据结构
5+阅读 · 2017年7月14日
Continual Unsupervised Representation Learning
Arxiv
7+阅读 · 2019年10月31日
Arxiv
3+阅读 · 2018年8月27日
Arxiv
3+阅读 · 2017年7月6日
VIP会员
相关资讯
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
Linux挖矿病毒的清除与分析
FreeBuf
14+阅读 · 2019年4月15日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
百度开源项目OpenRASP快速上手指南
黑客技术与网络安全
5+阅读 · 2019年2月12日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
占坑!利用 JenKins 持续集成 iOS 项目时遇到的问题
开源巨献:阿里巴巴最热门29款开源项目
算法与数据结构
5+阅读 · 2017年7月14日
Top
微信扫码咨询专知VIP会员