Jenkins+Ansible+Gitlab自动化部署
Jenkins+Ansible+Gitlab自动化部署
推荐Jenkins和Ansible可以安装到同一个环境作为部署server, Gitlab作为版本控制系统可单独部署在另一台server.
总结:
Jenkins首先从Gitlab去抓取我们写好的具体产品的playbook, 并使用virtualenv下的Ansible相关命令, 保证我们在一个clean的环境下使用stable version去批量部署我们的产品到远程client.
Let's go.....
一. 安装环境
System: CentOS 6.7 x64 (deploy.example.com) Jenkins: Jenkins ver. 1.650 Ansible: Ansible 2.1.0 Gitlab: GitLab 7.14.3
二. Jenkins配置
我们创建deploy用户作为jenkins_user, workspace为deploy家目录下的jenkins目录.
# su - root # adduser deploy # wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo # rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key # yum install jenkins -y # vi /etc/sysconfig/jenkins ... JENKINS_HOME="/home/deploy/jenkins" JENKINS_USER="deploy" ...
# service jenkins start
浏览器访问Jenkins页面
http://deploy.example.com:8080
安装完成, 以下是我已经配置好的一些Jenkins Job.
这里我们使用一个国内PHP网站模板phpcms作为我们需要部署的产品进行本次范例演示, 在进行最终的Build前我们需要做一些准备工作, 稍后我们会回到这个界面.
三. Ansible配置
这里我们需要配置virtualenv去隔离我们ansible的发行版本为最新版本2.1.0, 默认pip或者yum安装的1.9版本因为BUG以及对windows不兼容的原因, 这里不推荐使用.
配置步骤传送门: http://www.showerlee.com/archives/1862
Ansible-playbook范例传送门: http://www.showerlee.com/archives/1649
四. Gitlab配置
部署并使用传送门: http://www.showerlee.com/archives/1285
我们最终会创建一个ansible playbook仓库 git@git.example.cn:showerlee/Ansible-showerlee.git, 并在本地编写好我们的规则, 最终commit到这个仓库, 以便Jenkins去调用我们的部署规则.
这里博主单独clone出来一份部署phpcms的playbook仓库, 算是给大家的福利:
https://git.showerlee.com/showerlee/leon-playbook-phpcms1.1
五.最终部署
准备工作完毕, 我们接下来给大家介绍Jenkins Job配置.
1.创建一个new item
2. 创建一个freestyle Job, 命名规则"产品名-环境", 这里我们为Phpcms-Dev
3. Job配置
1). 定制Build参数.
这里Dynamic Choice Parameter用来通过Groovy脚本来抓取这个git仓库的所有branch, 并作为一个多选项, 方便我们在最终Build前去选择我们需要的这个产品Branch分支.
Groovy抓取Git branch代码:
def gettags = ("git ls-remote -h git@git.showerlee.com:showerlee/phpcms.git").execute() gettags.text.readLines().collect { it.split()[1].replaceAll('refs/heads/', '') }.unique()
Choice Parameter也是用来给我们Job定制Build前的可选参数, 不过这里的参数可以直接写死
deploy_environment为我们的参数名, 定义我们的部署环境名, prod, qa为我们具体的可选项, 定义我们产品的两个环境.
我们可以利用Jenkins内置的Source Code Management工具去抓取远程Git或者SVN仓库的代码到本地, 这里我们抓取存放在我们Gitlab上的Playbook到Jenkins的workspace目录, 用来进行后续部署工作, 这个仓库如需认证, 我们可以在Credentials add这个仓库的用户账号密码, 其余均保持默认即可(默认Jenkins default不支持Git, 需要到其后台安装Git插件)
这个Build模块下的Execute shell方法是Jenkins比较常用并非常核心的功能, 用来执行我们部署过程中核心的命令.
开头和结尾的set +x, set -x用来打开和关闭该部分的扩展参数及命令
开启virtualenv和加载ansible环境变量
# source /home/deploy/.virtualenv/bin/activate # . /home/deploy/.virtualenv/ansible/hacking/env-setup -q
进入该Job的workspace目录下保存该playbook的仓库子目录下, 检查ansible版本, 并执行最终的部署命令.
cd $WORKSPACE/leon-playbook-phpcms1.1 ansible --version ansible-playbook -i inventory/$deploy_environment ./deploy.yml -e project=phpcms -e branch=$branch_selector -e env=$deploy_environment
注: -i 用来自定义ansible host文件路径, ./deploy.yml为ansible-playbook入口文件, -e 后可跟给当前session添加的环境变量.
这里$deploy_environment $branch_selector 为该Job定义好的可选参数, 详见3-1)
配置完毕后, save保存.
4. 执行Job.
选择master分支和prod环境
查看该Job最终的console output, 也就是显示我们实际在CLI下的输出结果.
Console Output
Started by user Leon Li Building in workspace /home/deploy/jenkins/workspace/Phpcms-Dev > git rev-parse --is-inside-work-tree # timeout=10 Fetching changes from the remote Git repository > git config remote.origin.url git@git.showerlee.com:showerlee/Ansible-showerlee.git # timeout=10 Fetching upstream changes from git@git.showerlee.com:showerlee/Ansible-showerlee.git > git --version # timeout=10 > git fetch --tags --progress git@git.showerlee.com:showerlee/Ansible-showerlee.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 6bf787dcad68219d8eee09cecb83cbca36edbef1 (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f 6bf787dcad68219d8eee09cecb83cbca36edbef1 > git rev-list 6bf787dcad68219d8eee09cecb83cbca36edbef1 # timeout=10 [Phpcms-Dev] $ /bin/sh -xe /tmp/hudson7452069223867148990.sh + set +x ansible 2.1.0 (devel 6ddea3e915) last updated 2016/02/16 16:13:32 (GMT +800) lib/ansible/modules/core: (detached HEAD 8d126bd877) last updated 2016/02/16 16:19:09 (GMT +800) lib/ansible/modules/extras: (detached HEAD f6c5ed987f) last updated 2016/02/16 16:19:40 (GMT +800) config file = /home/deploy/jenkins/workspace/Phpcms-Dev/leon-playbook-phpcms1.1/ansible.cfg configured module search path = /home/deploy/active-ansible-modules/ PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [127.0.0.1] TASK [deploy : Backup current source code] ************************************* changed: [127.0.0.1] cmd: mv /data/deploy_dir/phpcms /data/deploy_dir/phpcms_master_1457681152 start: 2016-03-11 15:25:54.774716 end: 2016-03-11 15:25:54.927415 delta: 0:00:00.152699 TASK [deploy : Get new source code] ******************************************** changed: [127.0.0.1] TASK [deploy : Check if caches/configs/database.php exists] ******************** ok: [127.0.0.1] TASK [deploy : Check if test_dir exists] *************************************** ok: [127.0.0.1] TASK [deploy : debug] ********************************************************** ok: [127.0.0.1] => { "msg": "/data/deploy_dir/phpcms_master_1457681152/caches/configs/database.php exists" } msg: /data/deploy_dir/phpcms_master_1457681152/caches/configs/database.php exists TASK [deploy : debug] ********************************************************** ok: [127.0.0.1] => { "msg": "/data/deploy_dir/phpcms_master_1457681152/test_dir exists" } msg: /data/deploy_dir/phpcms_master_1457681152/test_dir exists TASK [deploy : Copy remote necessary original config to new release when Product env] *** changed: [127.0.0.1] => (item={u'name': u'db_config', u'dir': u'caches/configs/database.php'}) changed: [127.0.0.1] => (item={u'name': u'version_config', u'dir': u'caches/configs/version.php'}) msg: All items completed results: [ { "src": "/data/deploy_dir/phpcms_master_1457681152/caches/configs/database.php", "changed": true, "group": "deploy", "uid": 606, "dest": "/data/deploy_dir/phpcms/caches/configs/database.php", "checksum": "91869c2faa244f8c5de8a586636c6b4f3c0a2817", "md5sum": "fd88a78a4629bca012a79d22fdcecadd", "owner": "deploy", "_ansible_no_log": false, "item": { "name": "db_config", "dir": "caches/configs/database.php" }, "state": "file", "gid": 608, "mode": "0644", "invocation": { "module_args": { "src": "/data/deploy_dir/phpcms_master_1457681152/caches/configs/database.php", "directory_mode": null, "force": true, "remote_src": true, "dest": "/data/deploy_dir/phpcms/caches/configs/database.php", "selevel": null, "seuser": null, "setype": null, "group": null, "content": null, "serole": null, "original_basename": null, "delimiter": null, "mode": "0644", "regexp": null, "owner": null, "follow": false, "validate": null, "backup": false } }, "size": 302 }, { "src": "/data/deploy_dir/phpcms_master_1457681152/caches/configs/version.php", "changed": true, "group": "deploy", "uid": 606, "dest": "/data/deploy_dir/phpcms/caches/configs/version.php", "checksum": "d0eaedb46a36303eb3f3e2a77cc2a623062eff3c", "md5sum": "7917d8199b7c6d5bc87ff3035a72670e", "owner": "deploy", "_ansible_no_log": false, "item": { "name": "version_config", "dir": "caches/configs/version.php" }, "state": "file", "gid": 608, "mode": "0644", "invocation": { "module_args": { "src": "/data/deploy_dir/phpcms_master_1457681152/caches/configs/version.php", "directory_mode": null, "force": true, "remote_src": true, "dest": "/data/deploy_dir/phpcms/caches/configs/version.php", "selevel": null, "seuser": null, "setype": null, "group": null, "content": null, "serole": null, "original_basename": null, "delimiter": null, "mode": "0644", "regexp": null, "owner": null, "follow": false, "validate": null, "backup": false } }, "size": 127 } ] TASK [deploy : Copy dir test_dir to new release when Product env] ************** changed: [127.0.0.1] cmd: cp -a /data/deploy_dir/phpcms_master_1457681152/test_dir /data/deploy_dir/phpcms/ start: 2016-03-11 15:26:16.966237 end: 2016-03-11 15:26:17.069705 delta: 0:00:00.103468 TASK [deploy : Get php version] ************************************************ changed: [127.0.0.1 -> localhost] cmd: python /home/deploy/jenkins/workspace/Phpcms-Dev/leon-playbook-phpcms1.1/roles/deploy/files/get_php_version.py http://www.showerlee.com start: 2016-03-11 15:26:17.468311 end: 2016-03-11 15:26:51.560313 delta: 0:00:34.092002 stdout: PHP/5.4.13 TASK [deploy : debug] ********************************************************** ok: [127.0.0.1] => { "msg": { "changed": true, "cmd": "python /home/deploy/jenkins/workspace/Phpcms-Dev/leon-playbook-phpcms1.1/roles/deploy/files/get_php_version.py http://www.showerlee.com", "delta": "0:00:34.092002", "end": "2016-03-11 15:26:51.560313", "rc": 0, "start": "2016-03-11 15:26:17.468311", "stderr": "", "stdout": "PHP/5.4.13", "stdout_lines": [ "PHP/5.4.13" ], "warnings": [] } } msg: { "changed": true, "end": "2016-03-11 15:26:51.560313", "stdout": "PHP/5.4.13", "cmd": "python /home/deploy/jenkins/workspace/Phpcms-Dev/leon-playbook-phpcms1.1/roles/deploy/files/get_php_version.py http://www.showerlee.com", "start": "2016-03-11 15:26:17.468311", "delta": "0:00:34.092002", "stderr": "", "rc": 0, "stdout_lines": [ "PHP/5.4.13" ], "warnings": [] } TASK [deploy : debug] ********************************************************** ok: [127.0.0.1] => { "msg": "PHP/5.4.13" } msg: PHP/5.4.13 PLAY RECAP ********************************************************************* 127.0.0.1 : ok=12 changed=5 unreachable=0 failed=0 Finished: SUCCESS
这样我们就利用Jenkins+Ansible+Gitlab, 成功部署phpcms到远程Client.