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 源:java
[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 軟件:python
[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 非交互式腳本實現)
非交互式建立一對密鑰對:linux
[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
分別給受控節點分發公鑰:nginx
[root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub root@localhost [root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub root@192.168.193.132 [root@ansible ~]# ssh-copy-id -i .ssh/id_dsa.pub root@192.168.193.133
測試互信是否成功:【成功】git
[root@ansible ~]# ssh -p 22 root@192.168.193.132 "cat /etc/redhat-release" CentOS Linux release 7.3.1611 (Core) [root@ansible ~]# ssh -p 22 root@192.168.193.133 "cat /etc/redhat-release" CentOS Linux release 7.3.1611 (Core)
開始配置並經過 Ansible 管理其餘節點:web
[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 正則表達式的使用:shell
[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 遠程批量拷貝文件或目錄:apache
[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 遠程批量安裝:vim
[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 => {
咱們使用如上這些命令能夠快速利用 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。
一、項目需求
公司有4臺機器,須要將 jdk8 和 tomcat8 兩個包同時上傳到四臺機器的 /opt/ 目錄下,並進行安裝 。安裝成功後讓四臺機器經過郵件的方式通知運維人員,郵件格式爲:IP+hostname+servername。
二、項目計劃
經過 Ansible 批量部署
三、部署方案
3.一、四臺機器的基本信息
3.二、在 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.三、目錄結構
[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.四、文件詳細內容
[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" 872523367@qq.com
[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.五、執行過程
[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.六、查看結果
[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