在过去几年的DevOps的浪潮中,自动化、持续集成这两个概念早已深刻人心(互联网技术人)。比尔盖茨先生曾经都说过:“任何技术在一个业务中使用的第一条规则就是,将自动化应用到一个高效的操做上将会放大高效。第二条就是自动化应用到一个低效操做上,则放大了低效率。”php
自动化部署也逐渐成为各中小型企业追求的方向,那么,今天民工哥就自动化部署的概述、自动化部署的工具、自动化部署的流程、自动化部署实践等4个方面,与你们一同来讨论、交流一下关于中小企业自动部署的问题。前端
一句简单的话归纳:部署的过程当中全部的操做所有自动化,无需人工手工干预。java
传统的部署方式以下:linux
运维人员手工使用Scp、Xftp等方式来传输数据git
手工登陆服务器执行git pull 、svn update等命令进行更新代码的操做web
开发人员手工编译打包,而后经过内网传输给运维人员shell
看似很是简单,也不是很麻烦,可是一旦项目多,部署频繁,这种状况下就会大大下降工做效率。民工哥以前工做中就有这类体验,公司的活动类项目高达100+,不少都是须要快速上线及下线、或者更新的,手工部署真的累。后端
传统的部署方式有如下的缺点:centos
整个过程都须要人员参与,占用大量的时间,效率低下api
上线、更新、回滚速度慢
因此,自动化部署的优点就经过这种对比显现出来了!!
有自动动部署的概念,就须要自动化部署的工具,今天来介绍下一些这方面的工具给你们,怎么用?如何用?你们根据实际需求来定,一切不以需求来定的工具、流程、方法等都是耍流氓。
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工做,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。Jenkins应该说是目前最好用的持续集成工具之一,它的插件很是多,安装也很方便,功能至关的强大、灵活,最大的缺点就是学习成本较高。
ElectricFlow 是一个发布自动化工具,提供免费的社区版本,你能够在VirtualBox上运行。ElecticFlow支持大量插件和基于Groovy的 DSL,CLI,APIs。
微软DevOps产品的基础之一是 Visual Studio。 Visual Studio容许用户定义版本定义,自动化运行,跟踪版本等等。
Octopus Deploy建立目的是为了.NET应用的自动化部署。你能够在一台服务器安装或在Azure里作成实例。
2013年被IBM公司收购,UrbanCode 自动化部署到本地或云环境。
Amazon的自动化部署工具CodeDeploy,有着使人印象深入的客户名单、平台与语言无关。
DeployBot 能够连接任何Git存储库,而且容许手动或自动部署到多种环境。DeployBot提供大量集成,包括经过Slack部署的能力。
Shippable 规定了它们本身的“DevOps支柱”和它们本身的CI平台,运行依靠称为minions的基于Docker的容器。
TeamCity 是一个来自Jet Brains的CI服务器。TeamCity 有智能的配置功能和拥有官方Docker镜像服务器和代理。
Bamboo Server 是CI,由来自在Atlassian的人们提供,他们是Jira和Confluence的制造者。Bamboo公布“integrations that matter”并提供一个“small teams”包,捐赠给 Room to Read慈善事业。
Codar 是一个HP的持续部署解决方案。部署使用Jenkins触发。
CircleCI 是一个CI解决方案,强调灵活性、可靠性和速度。CircleCI提供从资源到建立到部署的解决方案,而且支持大量的语言和应用。
Gradle 是一个被一些业内最有名的例如LinkedIn, Netflix, 和Adobe所使用的建立工具。Gradle使用Groovy建立脚本,按惯例构建框架,并认为构建工具同时做为Apache的Ant的通用工具。
Automic 试图应用DevOps原理给一些后端应用,容许他们从已经在过去几年里许多前端、基于web的应用相同的实践上受益。
Distelli 专门在任何地方部署Kubernetes集群,除了能够在任何云或物理服务器上使用。根据TechCrunch这篇文章,Distelli 在2015年12月得到了280万美圆的资金,是由前AWS员工Rahul Singh创立的。
XL Deploy 是一个来自XebiaLabs的应用发布自动化工具,支持大量插件和环境,使用无代理架构。
Codeship是服务器托管CI解决方案,经过原生Docker支持定制。
一个CD服务器,强调可视化工做流,GoCD 是一个开源项目,由ThoughtWorks公司赞助开发。
Capistrano 是一个开源部署工具,使用Ruby开发。Capistrano 文档具备脚本语言和“理智的,富有表现力的API。”
Travis CI 能够同步到你的GitHub帐户,容许自动化测试和部署。Travis CI是一个免费的开源项目。
BuildBot 是一个开源的基于Python的持续集框架,自称为“内含有电池的框架”。BuildBot是面向罐装的解决方案用例,目前还不够灵活。
大概的流程步骤以下:
获取代码
编译打包
移除目标服务器
解压文件到目标目录
拷贝差别化文件
重启服务
测试
从新加入集群
若是在测试时出现问题,则须要回滚到上一次稳定版本。
通常能够将须要回滚的版本先列出来,而后将现有的软连接文件删除,从新将上一个版本的源文件生成一个软连接至目标目录,而后从新启动服务,进行自动化测试,最终加入集群。
说完了一堆的理论东东,接下来就是须要实践操做了,我以前也写过一个自动化的脚本,以下图:
这里列举两个实例,这两个实例是由网友西门飞冰投稿提供,具体的实例以下:
脚本使用环境:
一、操做系统:centos 6.5 64位
二、代码使用gitlab进行管理
三、代码每次上线经过tag控制
四、前端使用haproxy实现负载均衡,使用haproxy socat实现RS的平滑上下线
五、WEB container使用tomcat实现
六、项目构建使用maven
使用脚本注意事项:
一、 发布机器须要可以解析web服务器主机名,而且配置ssh通讯
二、 变量中的目录以及用户等信息须要本身建立,脚本没有作判断本身建立。我这里web服务器是使用ansible进行部署的,相关目录和用户都会自动建立。
三、代码的部署使用tag,可是代码的更新使用软链接来控制,回滚则切换到上一个软链接
四、因为java是编译型语言,咱们使用maven来进行编译,因此须要安装maven环境。
五、关于环境配置文件:配置文件为本身手动维护,每次都是删除git仓库拉取下来的配置文件,把对应环境的代码文件复制进编译目录进行编译。
脚本代码大概的步骤以下:
#!/bin/bash # 设置时间变量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 项目名称,建议和gitlab仓库名称一致 project= # 本地代码目录(gitlab拉取代码后存放目录) CODE_DIR=/data/gitlab/"$project" # 临时代码目录,用来修改配置文件和编译打包代码 TMP_DIR=/data/tmp/"$project" # 用来存放war包 WAR_DIR=/data/war/"$project" # 对应环境配置文件 deploy_conf=/data/conf/pro/"$project"/* # 代码中的配置文件路径 local_conf=$TMP_DIR/src/main/resources/config # 远程主机名称 REMOTE_HOST="tomcat-01 tomcat-02" # 远程主机代码目录 REMOTE_CODE_DIR=/data/webapps/"$project" # 远程主机用户 REMOTE_USER=root # 远程主机war包存放目录 REMOTE_WAR_DIR=/data/war/ # 代码临时目录 CODE_TMP=/data/code_tmp/ # 上线日志 DEPKOY_LOG=/data/log/pro_log.log # 脚本使用帮助 usage(){ echo $"Usage: $0 [deploy tag | rollback_list | rollback_pro ver]" } # 拉取代码 git_pro(){ if [ $# -lt 1 ];then echo "请传入tag" exit 1 fi tag=$1 cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代码失败" exit 10 fi cd $CODE_DIR && git pull 2>/dev/null >/dev/null # 推送代码到临时目录 rsync -avz --delete $CODE_DIR/ $TMP_DIR/ 2>/dev/null >/dev/null } # 设置代码的配置文件 config_pro(){ echo "设置代码配置文件" rm -f $local_conf/config.properties ......... } # 打包代码 tar_pro(){ echo "本地打包代码" cd $TMP_DIR && /usr/local/maven/bin/mvn clean compile war:war && cp target/"$project".war "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war } # 推送war包到远端服务器 rsync_pro(){ echo "推送war包到远端服务器" for host in $REMOTE_HOST;do scp "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war $REMOTE_USER@$host:$REMOTE_WAR_DIR done } # 解压代码包 solution_pro(){ echo "解压代码包" for host in $REMOTE_HOST;do ssh $REMOTE_USER@$host "unzip "$REMOTE_WAR_DIR""$project"_"$tag"_"$CTIME".war -d "$CODE_TMP""$project"_"$tag"_"$CTIME"" 2>/dev/null >/dev/null done } # api测试 test_pro(){ # 运行api测试脚本,若是api测试有问题,则退出部署 if [ $? != 0 ];then echo "API测试存在问题,退出部署" exit 10 fi } # 部署代码 deploy_pro(){ echo "部署代码" ................... sleep 3 # 执行api测试 test_pro ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 列出能够回滚的版本 rollback_list(){ echo "------------可回滚版本-------------" ssh $REMOTE_USER@$REMOTE_HOST "ls -r "$CODE_TMP" | grep -o $project.*" } # 回滚代码 rollback_pro(){ echo "回滚中" for host in $REMOTE_HOST;do ............................. sleep 3 ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 记录日志 record_log(){ echo "$CTIME 主机:$REMOTE_HOST 项目:$project tag:$1" >> $DEPKOY_LOG } # 代码执行选项设置 main(){ case $1 in deploy) git_pro $2; config_pro; tar_pro; rsync_pro; solution_pro; deploy_pro; record_log $2; ;; rollback_list) rollback_list; ;; rollback_pro) rollback_pro $2; record_log; ;; *) usage; esac } main $1 $2
脚本适应环境:
一、操做系统:centos 6.5 64位
二、代码使用gitlab进行管理
三、代码每次上线和回滚经过tag控制
补充:若是须要在你的企业使用个人这种部署方式,还须要有相应环境规范以及git分支管理规范。
一、 发布机器须要可以解析web服务器主机名,而且配置ssh通讯
二、 变量中的目录以及用户等信息须要本身建立,脚本没有作判断本身建立。我这里web服务器是使用ansible进行部署的,相关目录和用户都会自动建立。
三、代码的部署使用tag,回滚原则为回滚到上个tag版本,因此部署脚本自己没有备份代码。
四、若是须要过滤一些临时目录或者日志目录,能够在rsync推送代码的时候使用–exclude选项进行过滤,示例脚本中过滤了.git目录和config.php文件是不会部署的。
#!/bin/bash # 设置时间相关变量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 项目名称,建议和gitlab仓库名称一致 project=test # 本地代码目录(gitlab拉取代码后存放目录) CODE_DIR=/data/gitlab/pro/$project/ # 远程主机 REMOTE_HOST="LNMP-01.fblinux.com LNMP-02.fblinux.com" # 远程主机代码目录 REMOTE_DIR=/data/www/fblinux/ # 远程主机用户 REMOTE_USER=root # 远程主机代码执行用户 CODE_USER=php # 上线日志 DEPKOY_LOG=/data/log/pro_log.log #脚本使用帮助 usage(){ echo $"Usage: $0 [deploy tag]" } #拉取代码 git_pro(){ if [ $# -lt 1 ];then echo "请传入tag" exit 1 fi echo "拉取代码" cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代码失败" exit 10 fi cd $CODE_DIR && git pull } #推送代码服务器 rsync_pro(){ for host in $REMOTE_HOST;do echo "推送代码到服务器$host" rsync -rPv -P --delete --exclude="config.php" --exclude=".git" $CODE_DIR -e 'ssh -p 22' $REMOTE_USER@$host:$REMOTE_DIR if [ $? != 0 ];then echo "推送代码失败" exit 10 fi echo "代码受权" ssh $REMOTE_USER@$host "chown -R $CODE_USER $REMOTE_DIR" if [ $? != 0 ];then echo "代码受权失败" exit 10 fi done } #记录日志 record_log(){ echo "$CTIME 主机:$REMOTE_HOST 项目:$project tag:$1" >> $DEPKOY_LOG } main(){ case $1 in deploy) git_pro $2; rsync_pro; record_log $2; ;; *) usage; esac } main $1 $2
以上就是两个实际的生产部署实例的配置环境、注意事项及代码等讲解。
读者若是须要上述两个实例的完整代码请在 民工哥技术之路 公众号后台回复 “自动化部署”来获取脚本完整代码的下载地址。
参考资料以下:
https://dzone.com/articles/21-automated-deployment-tools-you-should-know