自动化部署基础与shell脚本实现
关于自动化的基础知识:
1.1:当前代码部署的实现方式:
运维纯手工scp到web服务器
纯手工登录git服务器执行git pull或svn服务器执行svn update更新代码
通过xftp上传代码
开发打压缩包上传到服务器然后解压
缺点:
1.需要运维全程参与,占用大量的工作时间
2.上线时间比较慢
3.人为造成的失误较多,管理比较混乱
4.回滚复杂而且慢,还不及时
1.2:运行环境规划:
开发环境:开发者本地有自己的环境,然后运维需要设置开发环境的公用服务,例如开发数据库、redis、memcached等
测试环境:功能测试环境和性能测试环境
预生产环境:由生产环境集群中的某一个节点担任测试,此节点只做测试不对外提供服务
生产环境:直接对外提供服务的环境
为什么有预生产环境?
可能是生产环境预测试环境的数据库或数据库版本不一样导致语句出现问题
或者是生产环境调用的接口不一样,例如支付接口在测试环境无法调用
1.3:设计一套生产环境的代码自动化部署系统:
开发环境 --> 功能测试/性能测试 --> 预生产环境 --> 生产环境
1.4:总体规划流程:
一个服务的集群节点数量,是一次部署还是分次部署
一键回滚到上个版本
一键回滚到任意版本
代码保存在SVN还是Git
获取指定分支或master的指定版本号的代码,svn指定版本号,git指定tag标签,或直接拉取某个分支
配置文件差异化,即测试环境和生产环境的配置文件不一样,如IP不一样或主机名不一样或数据库连接不一样等等
代码仓库和实际的差异,即配置文件是否放在代码仓库中,如果保存在git则所有人都可以从配置文件看到数据库用户密码等信息,可以使用单独分支保存配置文件,或配置文件只在部署服务器的某个项目的目录,比如是config.example
如何更新代码,java tomcat需要重启
测试部署后的web页面是否可以正常访问是否是想要的页面
并行(saltstack)或并行(shell)的问题,涉及到分组部署重启服务
如何执行,shell执行还是web执行
1.5:总体规划如下:
获取代码(git pull拉取) --> 是否编译(java需要编译) --> 配置文件(统一和差异) --> 打包 --> scp到目标服务器(或者用saltstack) --> 将服务器移除集群 --> 解压代码包 --> 放置到目标目录(如webroot) --> scp差异文件 --> 重启服务(可选) --> 测试服务(访问web或者post请求) --> 将节点重新加入集群
二:实现代码自动化部署
2.1:通过shell脚本实现,shell脚本规划如下:
2.1.1:各web服务器添加一个uid相同的普通用户,而且所有的web服务都以此普通用户启动,默认情况下所有的wenb服务除了负载均衡之外都不能监听80端口,比如可以监听8008端口
2.1.2:部署服务器的用户登录其他服务器免密码登录,因此需要做秘钥认证,在各主机执行以下命令:
# useradd www -u 1010
# su – www
$ ssh-keygen
#将部署机www用户的公钥复制到各web服务器的 /home/www/.ssh/authorized_keys或执行ssh-copy-id www@192.168.3.13
$ chmod 600 /home/www/.ssh/authorized_keys
2.1.3:测试部署服务器是否可以免秘钥用www用户登录各个web服务器
2.2:编写shell脚本:
2.2.1:完成框架编写:
#!/bin/bash #shell env SHELL_NAME="deploy.sh" SHELL_DIR="/home/www/" # 脚本路径 SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log" # 脚本执行日志 # code env 代码变量 CODE_DIR="/deploy/code/deploy" # 代码目录 CONFIG_DIR="/deploy/config" # 配置文件目录 TMP_DIR="/deploy/tmp" # 临时目录 TAR_DIR="/deploy/tar" # 打包目录 LOCK_FILE="/tmp/deploy.lock" # 锁文件标示 # 使用帮助函数 usage(){ echo $"Usage: $0 [ deploy | rollback ]" } shell_lock(){ touch ${LOCK_FILE} } shell_unlock(){ rm -f ${LOCK_FILE} } code_get(){ echo "code_get" sleep 60 } code_build(){ echo "code_build" } code_config(){ echo "code_config" } code_tar(){ echo "code_tar" } code_scp(){ echo "code_scp" } cluster_node_remove(){ echo "cluster_node_remove" } code_deploy(){ echo "code_deploy" } config_diff(){ echo "config_diff" } code_test(){ echo "code_test" } cluster_node_in(){ echo