Ansible 批量部署平臺

Ansible 介紹以及基本命令

Ansible 簡介:
Ansible 和目前市面上一些其他的項目管理工具有很大的不同,它的設計初衷就是爲了更方便、快捷的進行配置管理。它易於安裝和實用,語法也非常簡單易學。可以使用 Ansible 將平常複雜的配置工作變得簡單、更加標準化和更容易控制。
Ansible 只需要在一臺普通的服務器上運行即可,不需要在被管控的服務器上安裝客戶端,因爲它是基於 SSH 的。Linux 服務器離不開 SSH,所以 Ansible 不需要爲配置工作添加額外的支持,可通過命令行來使用 Ansible,運行 Ansible 的服務器俗稱 “管理節點”,通過 Ansible 進行管理的服務器俗稱 “受控節點”。
Ansible 是一款極爲靈活的開源工具套件,能夠大大簡化 Unix 管理員的自動化配置管理與流程控制方式。它利用推送方式對客戶系統加以配置,這樣所有的工作都可以在主服務器完成。其命令行機制同樣非常強大,允許利用商業許可 Web UI 實現授權管理與配置。
Ansible 的優點:
① 輕量級,不需要去客戶端安裝 agent,更新時只需要在操作機上進行一次更新即可,採用 SSH 協議。
② 批量任務執行可以寫成腳本,而且不用分發到遠程就可以執行。
③ 使用 Python 編寫的,維護更簡單。
④ 支持 sudo 普通用戶命令。
Ansible 安裝配置:
Ansible 能夠安裝到 Linux、BSD、Mac OS 等平臺,Python 最低版本要求爲 2.6。
安裝 Ansible 之前要先安裝第三方 epel 源:

[root@ansible ~]# cat /etc/redhat-release  #  查看系統內核。
CentOS Linux release 7.3.1611 (Core) 
[root@ansible ~]# python -V   #  查看 Python 版本(Python 版本最低爲 2.6)。
Python 2.7.5
[root@ansible ~]# yum install epel-release -y    #  安裝 EPEL 源

通過 Yum 安裝 Ansible 軟件:

[root@ansible ~]# yum install ansible -y
[root@ansible ~]# cd /etc/ansible/   #  配置文件默認的路徑。
[root@ansible ansible]# ll
-rw-r--r-- 1 root root 19549 8月  17 17:06 ansible.cfg
-rw-r--r-- 1 root root  1016 8月  17 17:06 hosts
drwxr-xr-x 2 root root     6 8月  17 17:06 roles

配置之前需要通過 SSH 讓多臺服務器建立互信:(機器多的話可以用 expect 非交互式腳本實現)
非交互式創建一對密鑰對:

[root@ansible ansible]# ssh-keygen -t dsa -P "" -f ~/.ssh/id_dsa
Generating public/private dsa key pair.
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
ee:18:eb:be:bc:1e:4c:98:aa:98:e0:63:0a:2b:24:a3 root@ansible
The key's randomart image is:
+--[ DSA 1024]----+
|                 |
|                 |
|                 |
|     o           |
|    o . S        |
|o. . o .         |
|*..   + .        |
|E*   . *         |
|X..  +Xo.        |
+-----------------+
[root@ansible ansible]# cd ~
[root@ansible ~]#  ls -l .ssh/  
總用量 8
-rw------- 1 root root 668 8月  28 21:16 id_dsa
-rw-r--r-- 1 root root 602 8月  28 21:16 id_dsa.pub

分別給受控節點分發公鑰:

[root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub root@localhost
[root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub [email protected]
[root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub [email protected]

測試互信是否成功:【成功】

[root@ansible ~]# ssh -p 22 [email protected] "cat /etc/redhat-release" 
CentOS Linux release 7.3.1611 (Core) 
[root@ansible ~]# ssh -p 22 [email protected] "cat /etc/redhat-release" 
CentOS Linux release 7.3.1611 (Core) 

開始配置並通過 Ansible 管理其他節點:

[root@ansible ~]# cd /etc/ansible/
[root@ansible ansible]# ll
總用量 24
-rw-r--r-- 1 root root 19549 8月  17 17:06 ansible.cfg
-rw-r--r-- 1 root root  1016 8月  17 17:06 hosts
drwxr-xr-x 2 root root     6 8月  17 17:06 roles
[root@ansible ansible]# cp hosts hosts.bak
[root@ansible ansible]# vim hosts
[root@ansible ansible]# cat hosts   #  默認 hosts 內容可以分組甚至分文件。
[local]
localhost         #  本機。
[webservers]
192.168.193.132   #  受控節點一。
[dbservers]
192.168.193.133   #  受控節點二。

通過命令使用 Ansible:

[root@ansible ~]# ansible -i /etc/ansible/hosts all -a "date"   
192.168.136.183 | SUCCESS | rc=0 >>
2018年 08月 28日 星期二 21:41:46 EDT

192.168.136.182 | SUCCESS | rc=0 >>
2018年 08月 28日 星期二 21:41:46 EDT

localhost | SUCCESS | rc=0 >>
2018年 08月 28日 星期二 21:41:47 EDT
[root@ansible ~]# ansible all -a "ping baidu.com -c 1"
192.168.136.183 | SUCCESS | rc=0 >>
192.168.136.182 | SUCCESS | rc=0 >>
localhost | SUCCESS | rc=0 >>

[root@ansible ~]# ansible all -m ping 
192.168.136.182 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.136.183 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
localhost | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

Ansible 主要參數:
Ansible 批量部署平臺
Ansible 正則表達式的使用:

[root@ansible ~]# ansible 192.168.* -m command -a "df -h"
192.168.193.132 | SUCCESS | rc=0 >>
文件系統        容量  已用  可用 已用% 掛載點
/dev/sda2        16G  1.7G   15G   11% /
devtmpfs        483M     0  483M    0% /dev
tmpfs           493M     0  493M    0% /dev/shm
tmpfs           493M  6.8M  486M    2% /run
tmpfs           493M     0  493M    0% /sys/fs/cgroup
tmpfs            99M     0   99M    0% /run/user/0

192.168.193.133 | SUCCESS | rc=0 >>
文件系統        容量  已用  可用 已用% 掛載點
/dev/sda2        16G  1.6G   15G   10% /
devtmpfs        483M     0  483M    0% /dev
tmpfs           493M     0  493M    0% /dev/shm
tmpfs           493M   13M  480M    3% /run
tmpfs           493M     0  493M    0% /sys/fs/cgroup
tmpfs            99M     0   99M    0% /run/user/0

[root@ansible ~]# ansible 192.168.136.* -m shell -a "df -h"   # 此處換成 shell 同上 command。  

Ansible 遠程批量拷貝文件或目錄:

[root@ansible ~]# ansible all -m copy -a 'src=/etc/hosts dest=/home/ mode=755 owner=root'
# 拷貝文件到所有受控節點的 /home/ 目錄下。
192.168.193.132 | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/home/hosts", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0755", 
    "owner": "root", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1538574556.34-237168714952191/source", 
    "state": "file", 
    "uid": 0
}
localhost | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/home/hosts", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0755", 
    "owner": "root", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1538574556.32-40315963626608/source", 
    "state": "file", 
    "uid": 0
}
192.168.193.133 | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/home/hosts", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0755", 
    "owner": "root", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1538574556.29-213260987463029/source", 
    "state": "file", 
    "uid": 0
}
[root@ansible ~]# mkdir /root/hehe
[root@ansible ~]# cd /root/hehe/ 
[root@ansible hehe]# touch {1..5}    
[root@ansible ~]# ansible all -m copy -a 'src=/root/hehe dest=/tmp/ mode=755 owner=root’
#  將 /root/hehe 目錄拷貝到所有受控節點的 /tmp 目錄下(目錄後面加 / 則會拷貝目錄下文件)。
192.168.136.182 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/root/hehe"
}
192.168.136.183 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/root/hehe"
}
localhost | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/root/hehe"
}

Ansible YUM 遠程批量安裝:

[root@ansible ~]# ansible 192.168.* -m yum -a "name=sysstat,screen,ntpdate state=installed"
#  通過 yum 爲 IP 以 192.168.* 開頭的受控節點安裝命令,輸出省略若干。
192.168.136.182 | SUCCESS => {
192.168.136.183 | SUCCESS => {

Playbook 配置管理:

我們使用如上這些命令可以快速利用 Ansible 的工具編寫腳本,從而以非常簡便的方式實現任務處理的自動化與流程化。除此之外我們還可以創建 Ansible Playbook 以收集命令與任務集,這樣能夠大大降低管理工作的複雜程度。
Playbook 採用 YAML 語法結構,因此它們一般比較易於閱讀並加以配置。
案例一:使用 Playbook 實現在客戶端安裝 screen 軟件:

[root@uncle_drew tmp]# rpm -qa|grep screen 
screen-4.1.0-0.25.20120314git3c2946.el7.x86_64
[root@uncle_drew ~]# yum remove screen   #  先把 182 上面的 screen 軟件卸載掉。
[root@uncle_drew tmp]# rpm -qa|grep screen   #  此時該服務器上面的 screen 沒有了。
[root@ansible ansible]# cd /etc/ansible/  
#  在 /etc/ansible/ 目錄下,新建 screen.yaml 文件,內容如下:
[root@ansible ansible]# vim screen.yaml 
[root@ansible ansible]# cat screen.yaml   #  提示:每個冒號後面都要有空格。
- hosts: 192.168.136.182  #  定義主機。
  remote_user: root    #  遠程用戶名。
  tasks:
  - name: +++++++++yum install screen+++++++++  #  顯示的任務名稱。
    shell: yum install screen -y    
#  指定需要在遠程客戶端執行的命令(可多個命令,中間用分號隔開)。
[root@ansible ansible]# ansible-playbook screen.yaml  #  運行這個 Playbook 的命令。
#  以下內容表示執行完畢(忽略警告)。
PLAY [192.168.136.182] *************************** 
TASK [Gathering Facts] **************************** 
ok: [192.168.136.182]
TASK [+++++++++yum install screen+++++++++] ** 
 [WARNING]: Consider using the yum module rather than running yum.  If you need to use command
because yum is insufficient you can add warn=False to this command task or set
command_warnings=False in ansible.cfg to get rid of this message.
changed: [192.168.136.182]
PLAY RECAP ************************** 
192.168.136.182            : ok=2    changed=1    unreachable=0    failed=0   
[root@uncle_drew ~]# rpm -qa|grep screen  # 到 IP 182 的客戶端即可看到安裝的 screen。
screen-4.1.0-0.25.20120314git3c2946.el7.x86_64  

案例二:定義源碼安裝 Nginx 軟件:

[root@ansible ansible]# cd /etc/ansible/  
[root@ansible ansible]# vim nginx.yaml 
[root@ansible ansible]# cat nginx.yaml 
- hosts: 192.168.136.182
  remote_user: root
  tasks:
  - name: +++++++++Install nginx web version 1.6.1++++++++++
    shell: wget http://nginx.org/download/nginx-1.6.1.tar.gz ;tar zxf nginx-1.6.1.tar.gz ;cd nginx-1.6.1 ;./configure --prefix=/usr/local/nginx ;make ;make install
[root@ansible ansible]# ansible-playbook nginx.yaml   #  執行該 Playbook。

Ansible 批量部署 tomcat 項目

1、項目需求
公司有4臺機器,需要將 jdk8 和 tomcat8 兩個包同時上傳到四臺機器的 /opt/ 目錄下,並進行安裝 。安裝成功後讓四臺機器通過郵件的方式通知運維人員,郵件格式爲:IP+hostname+servername。
2、項目計劃
通過 Ansible 批量部署
3、部署方案
3.1、四臺機器的基本信息
Ansible 批量部署平臺
3.2、在 ansible 的主機清單中定義一個主機組,指定需要部署的機器的 IP

[root@ansible ~]# cat /etc/ansible/hosts
[websrvs]
192.168.24.129
192.168.24.130
192.168.24.131
192.168.24.132

3.3、目錄結構

[root@ansible ~]# tree /etc/ansible/
├── files
│   ├── apache-tomcat-8.0.27.tar.gz # tomcat 包
│   ├── jdk-8u60-linux-x64.tar.gz       # jdk 包
│   ├── notice.txt                  # 腳本里的文件
│   ├── tomcat_ini.sh               # tomcat 服務的配置文件
│   └── tomcat_mail.sh              # 發郵件腳本
├── hosts                       # 主機清單
├── tomcat.yml                  # 批量部署 tomcat 服務的 ansible-palybook 腳本

3.4、文件詳細內容

[root@ansible ~]# cd /etc/ansible/files/
[root@ansible ansible]# ll
總用量 185912
-rw-r--r-- 1 root root   9128610 11月  6 07:47 apache-tomcat-8.0.27.tar.gz
-rw-r--r-- 1 root root 181238643 7月  23 03:49 jdk-8u60-linux-x64.tar.gz
-rw-r--r-- 1 root root      1465 11月 10 08:02 tomcat_ini.sh
[root@ansible files]# cat tomcat_ini.sh         # 腳本詳細內容
#!/bin/sh  
# chkconfig: 345 99 10  
# description: Auto-starts tomcat  
# /etc/init.d/tomcatd  
# Tomcat auto-start  
# Source function library.  
#. /etc/init.d/functions  
# source networking configuration.  
#. /etc/sysconfig/network  
RETVAL=0
export JAVA_HOME=/application/jdk
export JAVA_HOME
export CATALINA_HOME=/application/tomcat  
export CATALINA_BASE=/application/tomcat
start()  
{  
        if [ -f $CATALINA_HOME/bin/startup.sh ];  
          then  
            echo $"Starting tomcat"  
                $CATALINA_HOME/bin/startup.sh  
            RETVAL=$?  
            echo " OK"  
            return $RETVAL  
        fi  
}  
stop()  
{  
        if [ -f $CATALINA_HOME/bin/shutdown.sh ];  
          then  
            echo $"Stopping tomcat"  
                $CATALINA_HOME/bin/shutdown.sh  
            RETVAL=$?  
            sleep 1  
            ps -fwwu root | grep tomcat|grep -v grep | grep -v PID | awk '{print $2}'|xargs kill -9  
            echo " OK"  
            # [ $RETVAL -eq 0 ] && rm -f /var/lock/...  
            return $RETVAL  
        fi  
}  

case "$1" in  
 start)   
        start  
        ;;  
 stop)    
        stop  
        ;;  

 restart)  
         echo $"Restaring tomcat"  
         $0 stop  
         sleep 1  
         $0 start  
         ;;  
 *)  
        echo $"Usage: $0 {start|stop|restart}"  
        exit 1  
        ;;  
esac  
exit $RETVAL
[root@ansible ansible]# cat files/tomcat_mail.sh        # 郵件腳本詳細內容
#!/bin/bash
File=/etc/ansible/files/notice.txt
if [ ! -f $File ]
then
        touch $File
fi
> $File
for n in `seq 129 131`
do
        number=`ansible -m shell 192.168.24.$n -a 'netstat -lntup|grep 8080|wc -l'|sed -n '2p'`
        if [ $number -eq 1 ]
        then
                ansible 192.168.24.$n -a 'hostname -I' >> $File
                ansible 192.168.24.$n -a 'hostname' >> $File
                echo "tomcat success" >> $File
        else
                ansible 192.168.24.$n -a 'hostname -I' >> $File
                ansible 192.168.24.$n -a 'hostname' >> $File
                echo "tomcat failed" >> $File
        fi
done
grep -v "192.168.24.* | SUCCESS | rc=0 >>" $File|mail -s "tomcat state" [email protected]
[root@ansible ansible]# cat tomcat.yml          # 批量部署 tomcat 服務 ansible-playbook 腳本詳細內容
---
- hosts: websrvs
  remote_user: root

  tasks:
############Install JDK################
    - name: copy jdk-8u60-linux-x64.tar.gz
      copy: src=files/jdk-8u60-linux-x64.tar.gz dest=/opt/jdk-8u60-linux-x64.tar.gz
    - name: tar jdk
      command: /bin/tar xf /opt/jdk-8u60-linux-x64.tar.gz -C /application
    - name: rename jdk
      shell: mv /application/jdk1.8.0_60 /application/jdk
    - name: add /etc/profile
      shell: sed -i.ori '$a export JAVA_HOME=/application/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
    - name: add /etc/profile
      shell: echo 'export TOMCAT_HOME=/application/tomcat'>>/etc/profile
    - name: source profile
      shell: source /etc/profile
############Install Tomcat################
    - name: copy apache-tomcat-8.0.27.tar.gz
      copy: src=files/apache-tomcat-8.0.27.tar.gz dest=/opt/apache-tomcat-8.0.27.tar.gz
    - name: tar tomcat
      command: /bin/tar xf /opt/apache-tomcat-8.0.27.tar.gz -C /application
    - name: softlink tomcat
      file: src=/application/apache-tomcat-8.0.27/ dest=/application/tomcat state=link
    - name: create group
      group: name=tomcat
    - name: create user
      user: name=tomcat group=tomcat system=yes shell=/sbin/nologin 
    - name: push conf file
      template: src=/application/tomcat/conf/tomcat-users.xml dest=/application/tomcat/conf/
      notify: restart tomcat
    - name: copy startup.sh
      copy: src=files/tomcat_ini.sh dest=/etc/init.d/tomcat mode=0755
    - name: start tomcat
      shell: /etc/init.d/tomcat start

  handlers:
    - name: restart tomcat
      shell: /etc/init.d/tomcat restart

3.5、執行過程

[root@ansible ansible]# ansible-playbook tomcat.yml 

PLAY [websrvs] ********************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.24.131]
ok: [192.168.24.130]
ok: [192.168.24.129]

TASK [copy jdk-8u60-linux-x64.tar.gz] *********************************************
changed: [192.168.24.129]
changed: [192.168.24.130]
changed: [192.168.24.131]

TASK [tar jdk] ********************************************************************
 [WARNING]: Consider using the unarchive module rather than running tar.  If you
need to use command because unarchive is insufficient you can add warn=False to
this command task or set command_warnings=False in ansible.cfg to get rid of this
message.
changed: [192.168.24.130]
changed: [192.168.24.129]
changed: [192.168.24.131]

TASK [rename jdk] *****************************************************************
changed: [192.168.24.129]
changed: [192.168.24.130]
changed: [192.168.24.131]

TASK [add /etc/profile] ***********************************************************
 [WARNING]: Consider using the replace, lineinfile or template module rather than
running sed.  If you need to use command because replace, lineinfile or template
is insufficient you can add warn=False to this command task or set
command_warnings=False in ansible.cfg to get rid of this message.
changed: [192.168.24.129]
changed: [192.168.24.131]
changed: [192.168.24.130]

TASK [add /etc/profile] ***********************************************************
changed: [192.168.24.129]
changed: [192.168.24.130]
changed: [192.168.24.131]

TASK [source profile] *************************************************************
changed: [192.168.24.130]
changed: [192.168.24.131]
changed: [192.168.24.129]

TASK [copy apache-tomcat-8.0.27.tar.gz] *******************************************
changed: [192.168.24.129]
changed: [192.168.24.131]
changed: [192.168.24.130]

TASK [tar tomcat] *****************************************************************
changed: [192.168.24.129]
changed: [192.168.24.130]
changed: [192.168.24.131]

TASK [softlink tomcat] ************************************************************
changed: [192.168.24.130]
changed: [192.168.24.131]
changed: [192.168.24.129]

TASK [create group] ***************************************************************
ok: [192.168.24.129]
ok: [192.168.24.131]
ok: [192.168.24.130]

TASK [create user] ****************************************************************
ok: [192.168.24.130]
ok: [192.168.24.129]
ok: [192.168.24.131]

TASK [push conf file] *************************************************************
ok: [192.168.24.129]
ok: [192.168.24.131]
ok: [192.168.24.130]

TASK [copy startup.sh] ************************************************************
changed: [192.168.24.129]
changed: [192.168.24.131]
changed: [192.168.24.130]

TASK [start tomcat] ***************************************************************
changed: [192.168.24.129]
changed: [192.168.24.130]
changed: [192.168.24.131]

PLAY RECAP ************************************************************************
192.168.24.129             : ok=15   changed=11   unreachable=0    failed=0   
192.168.24.130             : ok=15   changed=11   unreachable=0    failed=0   
192.168.24.131             : ok=15   changed=11   unreachable=0    failed=0   

[root@ansible ansible]# sh files/tomcat_mail.sh     # 執行發郵件的腳本

3.6、查看結果

[root@ansible ansible]# ansible all -m shell -a 'netstat -lntup|grep java'
192.168.24.131 | SUCCESS | rc=0 >>
tcp6       0      0 :::8080                 :::*                    LISTEN      4092/java           
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      4092/java           
tcp6       0      0 :::8009                 :::*                    LISTEN      4092/java           
192.168.24.129 | SUCCESS | rc=0 >>
tcp6       0      0 :::8080                 :::*                    LISTEN      38742/java          
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      38742/java          
tcp6       0      0 :::8009                 :::*                    LISTEN      38742/java          
192.168.24.130 | SUCCESS | rc=0 >>
tcp6       0      0 :::8080                 :::*                    LISTEN      31653/java          
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      31653/java          
tcp6       0      0 :::8009                 :::*                    LISTEN      31653/java  

Ansible 批量部署平臺

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章