ezdpl Linux自动化部署实战

最近把ezdpl在生产环境中实施了,再加上这段时间的一些修改,一并介绍一下。

再次申明:

  • ezdpl不是开箱即用的,需要根据自己的应用环境定制。对初学者来说使用起来反倒困难更多、风险更大。
  • 它不是一个通用的项目,更多的是提供一种思路,将繁琐的操作变得简单易行,而且是用最原始的上传文件、执行脚本的方式。但是要享受简单,首先要做艰苦的准备和测试工作。

地址: https://github.com/Panblack/ezdpl


一、说明
1、组成
1) ezdpl.sh 主脚本,批量部署用的 auto.sh 脚本
2) 应用目录,可以包含任意个版本目录
3) 版本目录,含files和可选的 pre.sh、fin.sh 脚本

2、工作目录

├── 应用A
│   ├── 版本1
│   │    ├── files
│   │    │   ├── etc
│   │    │   ├── usr
│   │    │   └── opt
│   │    ├── pre.sh
│   │    └── fin.sh
│   ├── 版本2
│   │    └── fin.sh
│   ├── 版本3
│   │    └── files
├── 应用B
│   └── 版本1
│        └── files
├──ezdpl.sh
└──auto.sh

 
3、流程
首先操作机需要能无密码登录所有目标服务器,指令 ' ssh-keygen -t rsa ; ssh-copy-id 用户名@目标服务器 ' 。
主脚本有2/3是判断参数和目标服务器是否合法,真正的操作部分只有三处:
1) 如果有 pre.sh 脚本,就上传并在目标服务器执行;
2) 复制 files 目录下的所有文件到目标服务器的根目录 /;
3) 如果有 fin.sh 脚本,就上传并在目标服务器执行;
最后判断是否要重启目标服务器。

为什么要有两个脚本呢?很简单,复制文件之前可能需要对系统进行配置,有些系统配置需要特定文件上传之后。
具体怎么用?看您心情。

4、用法

./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]

 主脚本共 5 个参数
<Silent Mode Y|N>      Y - 静默模式, N - 需要手工确认,只能是 Y 或 N 。
<ip address>:[port]    目标服务器 IP地址:端口,如果目标服务器sshd端口不是默认的 22,就需要指明。
<app/version>          工作目录下的应用目录和版本,比如 orders/20151012 。
[reboot Y|N(N)]        执行完 fin.sh 脚本后是否重启,一般新装系统往往需要重启。默认为 N,可省略。
[username(root)]       执行远程登录的用户名,默认是 root,可省略。


5、最佳实践
* 能用文件解决的就尽量不用脚本,除非你的sed、awk、正则表达式功底深厚并且愿意承担风险。文件的好处是准确率高,便于事先审核、事后排错。
* 在测试环境配置一套“干净”的系统,然后将配好的文件复制到 ezdpl 工作目录。记住文件需要带完整路径,用' cp --parents '就可以了。
* 如果有软连接则必须压缩打包再传输,因为 scp 会将软连接复制成目标文件。
* 稳定版本保持不动,用' chattr +i ' 指令保护起来,或者打包备份,防止意外修改。微小变更也要建立新的版本并加以说明,以便跟踪变更历史,而且利于回退。
* 累积的小变更定期合并到新的稳定版。

cp --parents 示例,我们要从服务器 webserver1 上复制出 httpd 的配置文件:

[root@webserver1:/etc/httpd]# cp -r --parents ./conf /tmp/files

 结果会得到:

/tmp/files/etc/httpd/conf/ (含conf内的文件和目录)

 
顺便说一下,要让 CentOS 在提示符显示全路径,在 /root/.bash_profile 末尾添上这一行:

PS1='[\u@\h:$PWD]# '

注意大小写、单引号并且井号后面有个空格。
再执行

source /root/.bash_profile

 
如果要让新建用户也具备这个特性,在 /etc/skel/.bash_profile 末尾添上这一行:

PS1='[\u@\h:$PWD]$ '

 注意要用美元符 。


二、范例
1、场景
为新装操作系统准备的应用服务器初始化环境,“应用/版本” 为 appserver/current 。

[root@operation:/opt/ezDpl]# ll
total 28
-rw-r--r-- 1 root root  304 Oct 24 18:49 auto.sh
-rw-r--r-- 1 root root 3383 Oct 24 18:57 ezdpl.sh
drwxr-xr-x 3 root root 4096 Oct 24 13:48 appserver
drwxr-xr-x 3 root root 4096 Oct 24 13:49 loadbalance
drwxr-xr-x 3 root root 4096 Oct 24 13:49 orders
drwxr-xr-x 3 root root 4096 Oct 24 13:49 stocks
drwxr-xr-x 3 root root 4096 Oct 24 13:49 crm

 
2、appserver目录结构

appserver/
├── current
│   ├── files
│   │   │   ├── cron.daily
│   │   │   │   └── ntpsync
│   │   │   ├── profile
│   │   │   ├── profile.d
│   │   │   │   └── colorls.sh
│   │   │   ├── security
│   │   │   │   └── limits.conf
│   │   │   ├── skel
│   │   │   │   └── .bash_profile
│   │   │   ├── sysconfig
│   │   │   │   └── iptables
│   │   │   └── sysctl.conf
│   │   ├── opt
│   │   │   ├── jdk1.8.0_65
│   │   │   │   └── bin
│   │   │   ├── logs
│   │   │   ├── packages
│   │   │   └── tomcat8
│   │   │      ├── bin
│   │   │      ├── conf
│   │   │      ├── lib
│   │   │      ├── temp
│   │   │      ├── webapps
│   │   │      └── work
│   │   └── usr
│   │      └── local
│   │         └── bin
│   ├── fin.sh
│   └── pre.sh
└──20151012└── fin.sh

 
上述目录结构中,etc目录下是已经改写好的配置文件,分别为

etc/cron.daily/ntpsyncntpdate 0.pool.ntp.org 1.pool.ntp.org 自动获取网络时间
etc/profile设置java环境变量
etc/profile.d/colorls.sh用 2015-10-12 09:00 的格式显示文件日期时间,alias ll='ls -l --color=auto --time-style=long-iso' 2>/dev/null
etc/security/limits.conf修改ulimits值以适应高并发
etc/skel/.bash_profile设定新建用户的环境
etc/sysconfig/iptables防火墙设置
etc/sysctl.conf内核参数

opt里面是基础应用,比如 jdk,调整好的 tomcat 等,上传到目标服务器的 /opt 目录。
usr/local/bin 里面是平常使用的服务器管理脚本,上传到目标服务器的 /usr/local/bin 目录。

3、pre.sh 脚本
作用:为无法连接外网的服务器配置内部 yum 源(源必须事先准备好,本例中源所在服务器为10.6.1.200),安装必要的包,备份原始配置文件。

#!/bin/bash
mkdir -p /etc/yum.repos.d/temp
mv /etc/yum.repos.d/* /etc/yum.repos.d/templocal_repo="
[Local]
name=Local repo
baseurl=http://10.6.1.200/centos6
gpgcheck=0
enabled=1
"
echo -e "$local_repo" > /etc/yum.repos.d/local.reponginx_repo="
[nginx]
name=nginx repo
baseurl=http://10.6.1.200/nginx
gpgcheck=0
enabled=1
"
echo -e "$nginx_repo" > /etc/yum.repos.d/nginx.repoyum -y install telnet man vim wget zip unzip ntpdate tree gcc iptraf tcpdump bind-utils
yum -y install nginx
echo
echo "Packages installed..."
echo
/bin/cp /etc/sysconfig/iptables         /etc/sysconfig/iptables.`date +%Y%m%d`
/bin/cp /etc/security/limits.conf       /etc/security/limits.conf.`date +%Y%m%d`
/bin/cp /etc/sysctl.conf                /etc/sysctl.conf.`date +%Y%m%d`
#....(其余文件备份指令省略)


4、fin.sh    创建用户,并成为应用程序目录所有者

#!/bin/bash
useradd operuser && echo HisPassWord | passwd --stdin operuser
chown -R operuser:operuser /opt


5、auto.sh    
将appserver的current版本依次部署到10.6.1.x等五台服务器上。简单吧?

#!/bin/bash
sh ezdpl.sh Y 10.6.1.11 appserver/current Y
sh ezdpl.sh Y 10.6.1.12 appserver/current Y
sh ezdpl.sh Y 10.6.1.13 appserver/current Y
sh ezdpl.sh Y 10.6.1.14 appserver/current Y
sh ezdpl.sh Y 10.6.1.15 appserver/current Y


为了达到并行的目的,auto.sh脚本可以稍加修改,比如:

sh ezdpl.sh Y 10.6.1.11 appserver/current Y > /tmp/10.6.1.11.log &
sh ezdpl.sh Y 10.6.1.12 appserver/current Y > /tmp/10.6.1.12.log &
sh ezdpl.sh Y 10.6.1.13 appserver/current Y > /tmp/10.6.1.13.log &
...

 
6、变更
服务器运行一段时间后需要统一修改 operuser 的密码,并且将该用户加入到 developing 组。
将指令写入 fin.sh 脚本(pre.sh 也行,因为此项变更不涉及到上传文件,所以没有前后之分)。

#!/bin/bash
echo HisNewPassWord | passwd --stdin operuser
usermod -aG developing operuser


修改auto.sh脚本并执行。

#!/bin/bash
sh ezdpl.sh Y 10.6.1.11 appserver/20151012 Y > /tmp/10.6.1.11.log &
sh ezdpl.sh Y 10.6.1.12 appserver/20151012 Y > /tmp/10.6.1.12.log &
sh ezdpl.sh Y 10.6.1.13 appserver/20151012 Y > /tmp/10.6.1.13.log &
sh ezdpl.sh Y 10.6.1.14 appserver/20151012 Y > /tmp/10.6.1.14.log &
sh ezdpl.sh Y 10.6.1.15 appserver/20151012 Y > /tmp/10.6.1.15.log &

也很简单对吧?

 

7、回退

部署了应用orders的版本20151018,但是应用出现新的BUG,要回退到版本20151012。

部署:(部署时的 pre.sh 一般要包含删除服务器当前版本的指令)

sh ezdpl.sh Y 10.6.1.11 orders/20151018 Y > /tmp/10.6.1.11.log &
sh ezdpl.sh Y 10.6.1.12 orders/20151018 Y > /tmp/10.6.1.12.log &
sh ezdpl.sh Y 10.6.1.13 orders/20151018 Y > /tmp/10.6.1.13.log &
...

 回退:(相当于部署上一个版本,当然,pre.sh 脚本会先删除有BUG的 版本20151018。还是很简单吧?)

sh ezdpl.sh Y 10.6.1.11 orders/20151012 Y > /tmp/10.6.1.11.log &
sh ezdpl.sh Y 10.6.1.12 orders/20151012 Y > /tmp/10.6.1.12.log &
sh ezdpl.sh Y 10.6.1.13 orders/20151012 Y > /tmp/10.6.1.13.log &
...

 
但是,依旧强烈建议在生产环境实施之前,要做充分的测试

三、ezdpl.sh 版本1.1
 

#!/bin/bash
# https://github.com/Panblack/ezdpl

# Check Parameters
#echo $1
#echo $2
#echo $3
#echo
if [ -n "$1" ]; then_silent=$1if [ "$_silent" != "Y" ]; thenif [ "$_silent" != "N" ]; thenecho "The first parameter must be Y or N. Exit!"exit 1fifi
elseecho "silent. Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"exit 1
fiif [ -n "$2" ]; then#Detailed param check will be needed._ipaddress=$(echo $2|awk -F':' '{print $1}')_port=$(echo $2|awk -F':' '{print $2}')if [ ${#_port} -eq 0 ]; then_port="22"fi
elseecho "ipaddress:port. Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"exit 1
fiif [ -n "$3" ]; then_app_version=$3
elseecho "app/version. Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"exit 1
fi# Optional parameters
if [ -n "$4" ]; then_reboot=$4
else_reboot="N"
fi
if [ -n "$5" ]; then_username=$5
else_username="root"
fi# Silent mode or not
if [ "$_silent" != "Y" ]; thenechoecho "Ezdpl does things in a raw and simple way."echo "https://github.com/Panblack/ezdpl"echoecho "Will initialize a new server, or deploy apps to a certain server, or upgrade a production server."echo "Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"echo "Manually Initialize 10.1.1.1:         ./ezdpl.sh N 10.1.1.1 common/current Y"echo "Silently Deploy app_a to 10.1.1.1:     ./ezdpl.sh Y 10.1.1.1:22 app_a/current Y root"echo "Silently Upgrade 10.1.1.2's app_a:    ./ezdpl.sh Y 10.1.1.2:2222 app_a/20150720"echo "Manually Upgrade 10.1.1.2's conf:    ./ezdpl.sh N 10.1.1.2:2222 app_a/2015-10-12"echo# Confirmationread -p "Will overwrite configuration files or apps on $_ipaddress. Enter Y to continue: "if [ "$REPLY" != "Y" ]; thenecho "Exit"exit 0fi# Confirmation againread -p "Are you sure? Enter Y to continue: "if [ "$REPLY" != "Y" ]; thenecho "Exit"exit 0fi
fi# Check
echo "Target Server: ${_ipaddress}..."
ssh -p $_port $_username@$_ipaddress uname > /dev/null
if [ "$?" != "0" ]; thenechoecho "$_ipaddress is not reachable. "exit 1
fiif [ ! -d "./$_app_version" ]; thenechoecho "There is no $_app_version configured here !"exit 1
fi# Everything seems OK. Go!
# Run pre.sh on the target server
if [ -f "./$_app_version/pre.sh" ]; thenscp -P $_port ./$_app_version/pre.sh $_username@$_ipaddress:/tmp/ssh -p $_port $_username@$_ipaddress sh /tmp/pre.shecho "$_username@$_ipaddress:/tmp/pre.sh executed."
fi# Start copy app/version/files/*
if [ -d ./$_app_version/files  ]; thenscp -P $_port -r ./$_app_version/files/* $_username@$_ipaddress:/echo "./$_app_version/files/* copied."
fi# Run fin.sh on the target server
if [ -f "./$_app_version/fin.sh" ]; thenscp -P $_port ./$_app_version/fin.sh $_username@$_ipaddress:/tmp/ssh -p $_port $_username@$_ipaddress sh /tmp/fin.shecho "$_username@$_ipaddress:/tmp/fin.sh executed."
fi# Reboot target server.
if [ "$_reboot" = "Y" ]; thenechoecho "Target server will reboot..."echossh -p $_port $_username@$_ipaddress reboot
fi
echo "Target Server: ${_ipaddress} done!"; echo
# End of ezdpl.sh

 




转载于:https://www.cnblogs.com/panblack/p/ezdpl_practice.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无法打开输入文件mysql_错误LNK1181,pip安装“无法打开输入文件”mysqlclient.lib'...

我是Python新手&#xff0c;正在尝试安装mysql模块&#xff0c;但是在解决了其他5个问题之后&#xff0c;我现在遇到了一个问题&#xff0c;当我尝试安装该模块时&#xff0c;会出现以下日志&#xff1a;PS C:\Users\poste> pip install mysqlCollecting mysqlUsing cached …

俄罗斯将封杀LinkedIn 推动个人数据本地化

北京时间11月11日上午消息&#xff0c;莫斯科一家法院本周四支持了在俄罗斯封杀职业社交网站LinkedIn的决定。 俄罗斯联邦通信监管局&#xff08;Roskomnadzor&#xff09;之前要求国内外企业从2015年9月开始&#xff0c;必须将所有俄罗斯用户的个人数据存储在该国境内。Linked…

python的datetime举例_Python datetime模块的使用示例

1、获取当前年月日时分秒# -*- encodingutf-8 -*-import datetimenow datetime.datetime.now()print("now:{}".format(now))year now.yearprint("year:{}".format(year))month now.monthprint("month:{}".format(month))day now.dayprint(&q…

vs2015 去除 git 源代码 绑定,改成向tfs添加源码管理

除了下文的方法是将源码管理从git改成tfs之外&#xff0c;还要做以下几步即可 向tfs添加源码 打开源码管理(管理连接)&#xff0c;双击打开你要向其中添加的tfs连接选中该解决方案&#xff0c;右键 将解决方案添加到源码管理嵌入完毕vs2015 去除 git 源代码 绑定 第一次碰到这个…

HDU 4609 FFT

题目大意 给定n条边的边值&#xff0c;求任意取三条边能组成三角形的概率 这里概率 P valid/tot tot (n-2)*(n-1)*n/6是没问题的 valid表示合法的方式 先考虑&#xff0c;任意两条边组合形成方法的总数 因为边值在100000的范围内&#xff0c;这里组合用fft计算 得到最后形成和…

《日志管理与分析权威指南》一2.3 良好日志记录的标准

本节书摘来华章计算机《日志管理与分析权威指南》一书中的第2章 &#xff0c;第2.3节&#xff0c;&#xff08;美&#xff09; Anton A. Chuvakin Kevin J. Schmidt Christopher Phillips 著 姚 军 简于涵 刘 晖 等译更多章节内容可以访问云栖社区“华章计算机”公众号查…

Python【01】【基础部分】- A

一、WHATS PYTHON ? 1、python 简介 Python&#xff08;英语发音&#xff1a;/ˈpaɪθən/&#xff09;, 是一种面向对象、解释型计算机程序设计语言&#xff0c;由Guido van Rossum于1989年发明&#xff0c;第一个公开发行版发行于1991年。Python是纯粹的自由软件&#xff0…

java的自增自减_Java中自增和自减操作符(++/--)的那些事

自增()和自减(--)运算符在JAVA语言中存在着很多运算符&#xff0c;但是在实际开发中我们或许很少用到它们&#xff0c;在初次学习中却时常出现它们的身影&#xff0c;对于这些运算符的含义和用法&#xff0c;是否还记得呢&#xff1f;1. 概述自增操作符()和自减操作符(--)是对变…

Finished yeah!

终于到了最后的博客阶段&#xff0c;这时候才知道博客此时此刻是多么的惬意&#xff0c;它成了书写心声的自由平台&#xff01;耗时一天完成这作业说起来也是蛮辛苦的&#xff0c;编译器需要新装&#xff0c;IDE需要熟悉&#xff0c;当然最主要的是之前浅入浅出的C功底在此次作…

《Python语言程序设计》——1.6 开始学习Python

本节书摘来自华章计算机《Python语言程序设计》一书中的第1章&#xff0c;第1.6节,作者&#xff1a;&#xff3b;美&#xff3d;梁勇&#xff08;Y. Daniel Liang&#xff09; 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.6 开始学习Python 关键点&#xff1a;…

Tomcat性能调优

1、集成apache 虽然Tomcat也可以作web服务器&#xff0c;但是处理静态html的速度比不上apache&#xff0c;且其作为web服务器的功能远不如Apache&#xff0c;因此把apache和tomcat集成起来&#xff0c;讲html和jsp功能部分进行明确的分工&#xff0c;让tomcat只处理jsp部分&…

【转】sip中的subscribe和notify扩展应用技术

http://blog.csdn.net/hwz119/article/details/3965322转载于:https://www.cnblogs.com/matthew-2013/p/4917207.html

再读《被神化的框架》

开发框架&#xff0c;构件&#xff0c;组件非常地多&#xff0c;而且&#xff0c;趋势是越来越多&#xff0c;特别是在java中。当然也不是说其它平台的少。而特别是框架越来越被神化了&#xff0c;似乎用之解决一切问题&#xff0c;不用就要敲坏键盘。对于老衲这样的打字员来说…

河南推出近万亿PPP投资计划 郑州实现智慧城市全覆盖

1 近万亿PPP项目启动 眼下&#xff0c;国内财经新闻的热点聚焦在PPP开发上&#xff0c;这与PPP支撑国内经济平衡运行的一支强劲力量正被政府看好。就连二级市场也出现了PPP概念的抢筹现象。 9月27日&#xff0c;股市再一次遭遇抛售&#xff0c;大盘创出阶段性新低&#xff0c;然…

java基础实例代码_Java基础实例

打印等腰三角形代码public class ForForTest{public static void main(String []args){for(int x0;x<5;x){for(int yx1;y<5;y){System.out.print(" ");}for(int z0;zSystem.out.print("* ");}System.out.println();}}}折半查找代码&#xff1a;//练习…

###《Effective STL》--Chapter3

点击查看Evernote原文。 #author: gr #date: 2014-09-13 #email: forgeruigmail.com Chapter3 关联容器 Topic 22: 切勿直接修改set或multiset中的键 修改元素的值可以通过下面五步操作&#xff0c;避免作类型转换。 struct IDNumberLess : public binary…

如何获取网络资源?

# encodingutf-8 #python 2.7.10 #xiaodeng #如何获取网络资源&#xff1f; #HTTP权威指南 26页#url就是因特网资源的标准化名称&#xff0c;他指向每一条电子信息&#xff0c;告诉你他们位于何处&#xff0c;以及如何与之交互。 #URL是浏览器寻找信息时所需的资源位置。 #一个…

Loadrunner多服务器连接问题

今天用想增加一个压力机,在服务器管理列表里怎么也连不上,后来解决方法如下:1. 关闭所有loadrunner组件,并手动结束lr_开头的进程2.找到惠普loadrunner安装目录(C:\Program Files\HP\LoadRunner\bin),手动运行magentproc.exe即可最新内容请见作者的GitHub页&#xff1a;http://…

java 常量存储_JAVA 存储空间 寄存器 堆栈 堆 常量存储 非RAM存储

&#xff11;.寄存器这是最快的存储区&#xff0c;因为它位于处理器内部&#xff0c;数量极其有限&#xff0c;所以寄存器根据需求进行分配&#xff0c;你不能直接控制&#xff0c;也不能在程序中感 觉到寄存器存在的任何迹象。2.堆栈位于通用RAM(随机访问存储器)中&#xff0…

物联网安防技术融合在细分领域的应用分析

物联网的核心是业务和应用的创新。物联网技术与智能化技术的深度融合&#xff0c;加快了行业的智能化发展&#xff0c;促使了行业需求在应用层上的落地。安防技术架构是物联网架构的一个子集&#xff0c;传统安防是一个相对保守的行业。现代安防和物联网在业务和技术上的融合发…