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.pswp.cn/news/258159.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258159.shtml
英文地址,請注明出處:http://en.pswp.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;傳統安防是一個相對保守的行業。現代安防和物聯網在業務和技術上的融合發…