ezdpl Linux自動化部署實踐教程

來源:互聯網
上載者:User

申明:

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、Regex功底深厚並且願意承擔風險。檔案的好處是準確率高,便於事先審核、事後排錯。
* 在測試環境配置一套“乾淨”的系統,然後將配好的檔案複製到 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/ntpsync     ntpdate 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/temp

local_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.repo

nginx_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.repo

yum -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=$1
  if [ "$_silent" != "Y" ]; then
    if [ "$_silent" != "N" ]; then
      echo "The first parameter must be Y or N. Exit!"
      exit 1
    fi
  fi
else
  echo "silent. Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"
  exit 1
fi

if [ -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
else
  echo "ipaddress:port. Usage: ./ezdpl.sh <Silent Mode Y|N> <ip address>:[port] <app/version> [reboot Y|N(N)] [username(root)]"
  exit 1
fi

if [ -n "$3" ]; then
  _app_version=$3
else
  echo "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" ]; then
  echo
  echo "Ezdpl does things in a raw and simple way."
  echo "https://github.com/Panblack/ezdpl"
  echo
  echo "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

  # Confirmation
  read -p "Will overwrite configuration files or apps on $_ipaddress. Enter Y to continue: "
  if [ "$REPLY" != "Y" ]; then
    echo "Exit"
    exit 0
  fi

  # Confirmation again
  read -p "Are you sure? Enter Y to continue: "
  if [ "$REPLY" != "Y" ]; then
    echo "Exit"
    exit 0
  fi
fi

# Check
echo "Target Server: ${_ipaddress}..."
ssh -p $_port $_username@$_ipaddress uname > /dev/null
if [ "$?" != "0" ]; then
  echo
  echo "$_ipaddress is not reachable. "
  exit 1
fi

if [ ! -d "./$_app_version" ]; then
  echo
  echo "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" ]; then
  scp -P $_port ./$_app_version/pre.sh $_username@$_ipaddress:/tmp/
  ssh -p $_port $_username@$_ipaddress sh /tmp/pre.sh
  echo "$_username@$_ipaddress:/tmp/pre.sh executed."
fi

# Start copy app/version/files/*
if [ -d ./$_app_version/files  ]; then
  scp -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" ]; then
  scp -P $_port ./$_app_version/fin.sh $_username@$_ipaddress:/tmp/
  ssh -p $_port $_username@$_ipaddress sh /tmp/fin.sh
  echo "$_username@$_ipaddress:/tmp/fin.sh executed."
fi

# Reboot target server.
if [ "$_reboot" = "Y" ]; then
  echo
  echo "Target server will reboot..."
  echo
  ssh -p $_port $_username@$_ipaddress reboot
fi
echo "Target Server: ${_ipaddress} done!"; echo
# End of ezdpl.sh

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.