平台架构设计
1.1 整体规划
1.1.1 架构图
图:自动化平台架构
1.1.2 设计思想
Git作为目前最流行的代码托管系统,具有强大的功能,而Ansible是运维圈内评价非常高的轻量级自动化平台,要实现更加轻松便捷高效的自动化,就需要将开发使用的git平台与运维使用的Ansible平台有机结合。Jenkins正是提供了这一持续集成工具,通过Jenkins将git与Ansible持续集成。
1.1.3 实现原理
按照自动化平台的架构图和设计思想,产品的自动发布过程分为三个步骤,期间分别使用到了Git、Ansible和Jenkins等平台:
- 代码上传至Git托管;
- 通过Jenkins平台pull代码;
- 通过Jenkins平台maven插件打包项目;
通过Jenkins平台调用Ansible的playbook脚本完成发布;
1.2 Git介绍
1.2.1 Git简介
Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
1.2.2 Git特点
直接记录快照,而非差异比较
近乎所有操作都是本地执行
时刻保持数据完整性
多数操作仅添加数据
1.3 Ansible介绍
1.3.1 Ansible简介
图:Ansible架构
Ansible是新出现的自动化运维工具,基于Python开发,集合了众多老牌运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。主要包括:
连接插件connection plugins:负责和被管控端实现通信;
host inventory:指定操作的主机,是一个配置文件里面定义管控的主机;
各种模块核心模块、command模块、自定义模块;
借助于插件完成记录日志邮件等功能;
playbook:剧本执行多个任务时,可以让被管控端一次性运行多个任务。
1.3.2 Ansible特点
no agents:不需要在被管控主机上安装任何客户端;
no server:无服务器端,使用时直接运行命令即可;
modules in any languages:基于模块工作,可使用任意语言开发模块;
yaml,not code:使用yaml语言定制剧本playbook;
ssh by default:基于SSH工作;
strong multi-tier solution:可实现多级指挥。
1.4 Jenkins介绍
1.4.1 Jenkins简介
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成(CI)工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
1.4.2 Jenkins特点
易安装:仅仅一个java -jar jenkins.war,从官网下载该文件后,直接运行,无需额外的安装,更无需安装数据库;
易配置:提供友好的GUI配置界面;
变更支持:Jenkins能从代码仓库(SVN/GIT)中获取并产生代码更新列表并输出到编译输出信息中;
支持永久链接:用户是通过web来访问Jenkins的,而这些web页面的链接地址都是永久链接地址,你可以在各种文档中直接使用该链接;
集成E-Mail:当完成一次集成时,可通过这些工具实时告诉你集成结果;
JUnit/TestNG测试报告:也就是用以图表等形式提供详细的测试报表功能;
支持分布式构建:Jenkins可以把集成构建等工作分发到多台计算机中完成;
文件指纹信息:Jenkins会保存哪次集成构建产生了哪些jars文件,哪一次集成构建使用了哪个版本的jars文件等构建记录;
支持第三方插件:使得 Jenkins 变得越来越强大;
一、 平台部署
2.1 Git环境部署
2.1.1 Git命令安装
YUM安装git命令即可:
yum install git
2.1.2 mvn环境安装
maven为代码打包环境,必须安装,在Apache官网下载maven压缩包,解压至指定目录后,添加环境变量生效,官网地址:https://maven.apache.org/download.cgi
tar xvf apache-maven-3.5.3-bin.tar.gz –C /usr/local/
vi /etc/profile
set maven environment
MAVEN_HOME=/usr/local/apache-maven-3.5.2
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
source /etc/profile
mvn -v
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T15:58:13+08:00)
Maven home: /usr/local/apache-maven-3.5.2
Java version: 1.8.0_151, vendor: Oracle Corporation
Java home: /usr/local/jdk1.8.0_151/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-696.10.2.el6.x86_64", arch: "amd64", family: "unix"
2.1.3 Gradle环境安装
Gradle为另一个打包环境,主要用于网站项目打war包,也必须安装。在gradle官网下载gradle安装包,解压至指定目录后,添加环境变量生效,官网地址如下:https://gradle.org/
tar xvf gradle-4.4.1-bin.tar.gz –C /usr/local/
vi /etc/profile
set gradle environment
export GRADLE_HOME=/usr/local/gradle-4.4.1
export PATH=$GRADLE_HOME/bin:$PATH
source /etc/profile
gradle –v
Gradle 4.4.1
Build time: 2017-12-20 15:45:23 UTC
Revision: 10ed9dc355dc39f6307cc98fbd8cea314bdd381c
Groovy: 2.4.12
Ant: Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM: 1.8.0_151 (Oracle Corporation 25.151-b12)
OS: Linux 2.6.32-696.10.2.el6.x86_64 amd64
2.1.4 配置私有仓库
将研发提供的settings.xml文件放到~/.m2/目录下。
ll ~/.m2/settings.xml
-rw-r--r-- 1 root root 11564 Dec 13 17:46 /root/.m2/settings.xml
2.2 Ansible安装部署
2.1.5 Ansible安装
安装方法大致分为三类,各有优劣,介绍如下:
1、YUM安装:
配置epel源后,执行yum install安装
yum install ansible
优点:安装简单,无依赖问题;
缺点:需要外网环境,且安装路径无法控制,版本过低。
2、PIP安装:
安装pip:
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
pip -V #查看pip版本
或者:
yum install python-pip python-devel
安装ansible
pip install ansible
优点:安装简单,无依赖问题,版本较新;
缺点:需要外网环境,且安装路径无法控制。
3、源码安装:
./configure
make
make install
优点:无需外网,版本可选,路径可选;
缺点:需要解决依赖问题。
在和留言系统内,采用yum安装的方式,配置文件位于/etc/ansible/。
2.1.6 Ansible配置
通常情况下,保持原有主配置文件/etc/ansible/ansible.cfg不变即可,但有两个配置项建议进行修改:
1、 host_key_checking = False
关闭第一次使用ansible连接客户端是输入命令提示。
2、 log_path = /var/log/ansible.log
打开日志配置,便于追溯。
配置主机清单,该配置比较重要,配置文件位于/etc/ansible/hosts,在该配置文件中可以配置远程主机、远程用户、用户密码等信息(密码信息非常敏感,不建议写入配置文件),示例如下:
[slivr]
10.1.99.16 ansible_ssh_user=user01
10.1.99.[30:32] ansible_ssh_user=user01
10.1.99.39 ansible_ssh_user=user01
10.1.99.[85:87] ansible_ssh_user=user01
10.1.99.[113:116] ansible_ssh_user=user01
[slmsg]
10.1.99.[31:32] ansible_ssh_user=user01
10.1.99.[39:41] ansible_ssh_user=user01
10.1.99.[84:87] ansible_ssh_user=user01
建议对远程主机做普通用户免密,方法如下:
ssh-copy-id [email protected]
键入密码,完成免密配置。
测试能否操作远程主机:
显示如上则正常。
2.3 Jenkins安装部署
2.2.1 环境准备
配置java环境:
vi /etc/profile
set java environment
JAVA_HOME=/usr/java/jdk1.8.0_111
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
除java外,还需要前文章节所述的maven和gradle环境。
2.2.2 Jenkins安装
YUM安装:
配置好源,执行yum install安装
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install jenkins
优点:安装简单,自带启动关闭脚本,无依赖问题;
缺点:需要外网环境。
TOMCAT发布:
部署好tomcat之后,将官方jenkins.war放置到tomcat的webapps目录下做发布,官网地址:http://jenkins.io/
优点:无需外网,安装简单,可利用tomcat做启动关闭;
缺点:需要先安装tomcat,本身无法启动关闭,性能受tomcat影响。
JAVA命令发布:
下载官方jenkins.war,用原生java命令进行启动和关闭
nohup java -jar jenkins.war --httpPort=8088 &
优点:无需外网,安装简单,目录可自定义;
缺点:没有完善的启动关闭脚本。
现有平台采用yum安装方法,业务目录为/var/lib/jenkins,配置文件为/etc/sysconfig/jenkins
2.2.3 Jenkins配置
配置文件为/etc/sysconfig/jenkins,大部分配置项保持原有即可。有几处重要的配置可以做修改。
JENKINS_USER="root"
Jenkins的启动用户需要更改为root,否则会因权限不足而出错,配置如下:
JENKINS_PORT="8080"
启动端口
JENKINS_HOME="/var/lib/jenkins"
jenkins工作目录,按照实际修改
配置完成后,启动jenkins,打开jenkins页面:
/etc/init.d/jenkins start
二、 操作方法
3.1 编写playbooks脚本
3.1.1 Playbooks常见模块
copy:远程拷贝
-a "src=/usr/local/xxx dest=/usr/local/yyy mode=0755 owner=user group=group"
file:文件操作
-a "path=/usr/local/xxx state=absent"
-a "path=/usr/local/yyy/ state=directory"
yum:yum安装/卸载
-a "name=telnet state=present"
service:服务操作
-a "name=redis state=restart"
-a "name=redis enabled=yes"
unarchive:解压
-a "src=/usr/local/xxx.tar.gz dest=/opt/yyy"
shell:远程执行shell命令
-a "cat /dev/null > /var/log/nginx/access.log"
3.1.2 Playbooks示例
Playbooks脚本的编写需要不断的练习,不可能仅看文档便能掌握,以下给出示例供参考:
---
- hosts: slivr
become: yes
become_method: sudo
gather_facts: no
tasks:name: ping slivr
ping:name: get current date
shell: date +"%Y%m%d"
register: timename: check backupdir
shell: ls -d /usr/local/vvm/slivr/bak/
register: exist
ignore_errors: Truename: mkdir bak
file: path=/usr/local/vvm/slivr/bak state=directory
when: exist.stdout == ""name: check backupfile
shell: ls -l /usr/local/vvm/slivr/bak/{{time.stdout}}.tar.gz
register: exist
ignore_errors: Truename: backup file
shell: cd /usr/local/vvm/slivr && tar czvf /usr/local/vvm/slivr/bak/{{time.stdout}}.tar.gz lib conf --remove-files
when: exist.stdout == ""name: remove old lib
file: path=/usr/local/vvm/slivr/lib state=absentname: remove old conf
file: path=/usr/local/vvm/slivr/conf state=absentname: fetch jar
unarchive: src=/var/lib/jenkins/workspace/slivr_update/target/slivr-1.0-assembly.tar.gz dest=/tmp/name: replace lib
shell: \cp -rf /tmp/slivr-1.0/lib /usr/local/vvm/slivr/name: replace conf
shell: \cp -rf /tmp/slivr-1.0/conf /usr/local/vvm/slivr/- name: confirm replace succeed
shell: ls -l /usr/local/vvm/slivr/lib/slivr-1.0.jar
register: result debug: msg='{{result.stdout}}'
- name: restart service
shell: sh /usr/local/vvm/slivr/bin/restart.sh
register: output debug: msg={{output.stdout}}
name: remove tmpfile
file: path=/tmp/slivr-1.0 state=absentname: remove overduce bakupfile
shell: find /usr/local/vvm/slivr/bak/ -mtime +30 -type f | xargs rm -rf
...
3.2 创建Jenkins任务
3.2.1 Jenkins安装插件
点击系统管理->管理插件:
在可选插件里选择需要的插件进行安装,比较重要且不可或缺的插件有如下:
Git plugin
Maven Integration plugin
Gradle Plugin
Timestamper
3.2.2 Jenkins配置工具
点击系统配置->全局工具配置:
配置JDK环境:
配置Git环境:
配置gradle环境:
配置maven环境:
最后保存提交。
3.2.3 创建新的ITEM
登录后点击新建item:
选择项目风格:常用的项目风格有maven、freestyle,如果没有对应风格的项目,可以直接选择freestyle,通常maven项目用于打jar包,使用freestyle也可。
选择好代码来源,填写仓库地址,账号密码,最后指定分支,通过该部分配置,可以实现从git仓库pull代码:
配置构建触发器,建议以镜像方式构建:
配置构建环境,只需为控制台输出添加时间戳即可,其他不做勾选:
构建配置,填写maven打包时的参数,由研发提供:
项目完成打包后将代码分发至对应节点并重启项目的操作,由Jenkins通过shell的调用playbooks脚本来实现:
三、 常见异常处理
按照目前产品发布自动化的流程设计,大体分为三个步骤:拉取代码、打包代码、发布代码。因此,这三个步骤中,都会出现一些常见问题,下面做简单介绍供参考。
4.1 Pull源代码问题
4.1.1 连接不到Git
因Git关闭或者网络中断,都有可能导致连接不到Git,从而无法pull代码,该类问题较为罕见,但是排查和解决难度并不大,遇到时恢复网络连接或者恢复Git正常工作即可解决。
4.2 代码打包问题
4.2.1 缺少pom.xml文件
pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和licenses,以及其他所有的项目相关因素,是项目级别的配置文件。
4.2.2 代码错误
开发人员提交的代码如果有错误,在打包过程中会导致报错而退出构建,此问题需要开发人员查到报错原因并修改后重新提交代码。
4.3 代码发布问题
代码的发布过程,是出问题最多的步骤,这个非常考验playbook的编写质量,如果脚本不够健壮或者出现逻辑错误或者有细节疏漏,便会出现产品发布的失败。本文仅举几个例子做介绍。
4.3.1 路径填写错误
playbook脚本中写明的,需要访问的路径,在实际环境中并不存在。
4.3.2 文件名填写有误
因项目打包后的文件名没有严格规范要求,通常执行完mvn命令后产生的压缩文件名并没有固定格式或规律,因此需要确认文件名后再写入playbook脚本内。
4.3.3 程序重启失败
在执行最后一步服务重启操作时,常有出现重启失败的情况,该问题最彻底的解决办法,是改造项目使之在普通用户权限下运行,而不是超级管理员用户运行。