自動化運維—ansible

自動化運維—ansible

1、Ansible介紹

Ansilbe是一個部署一羣遠程主機的工具。遠程的主機能夠是遠程虛擬機或物理機, 也能夠是本地主機。javascript

Ansilbe經過SSH協議實現遠程節點和管理節點之間的通訊,不須要安裝客戶端。css

Ansible基於模塊工做,模塊能夠由任何語言開發html

Ansible不只支持命令行使用模塊,也支持編寫yaml格式的playbook,易於編寫和閱讀java

Ansible的安裝十分簡單,centos上可直接經過yum安裝。python

Ansible有提供命令行版本,免費。也有提供UI(瀏覽器圖形化)版本,網址: www.ansible.com/tower,可是收費的。 官方文檔: http://docs.ansible.com/ansible/latest/index.htmlmysql

Ansible已經被redhat公司收購,它在github上是一個很是受歡迎的開源軟件,github地址https://github.com/ansible/ansiblelinux

一本不錯的入門電子書 https://ansible-book.gitbooks.io/ansible-first-book/nginx

2、ansible安裝和遠程執行命令

查看ansible 的yum清單,安裝ansible ansible-docgit

[root@ying01 salt]# yum list | grep ansible
ansible.noarch                            2.6.3-1.el7                  epel     
ansible-doc.noarch                        2.6.3-1.el7                  epel     
ansible-inventory-grapher.noarch          2.4.4-1.el7                  epel     
ansible-lint.noarch                       3.4.21-1.el7                 epel     
ansible-openstack-modules.noarch          0-20140902git79d751a.el7     epel     
ansible-review.noarch                     0.13.4-1.el7                 epel     
kubernetes-ansible.noarch                 0.6.0-0.1.gitd65ebd5.el7     epel     
python2-ansible-runner.noarch             1.0.1-1.el7                  epel     
python2-ansible-tower-cli.noarch          3.3.0-2.el7                  epel    

[root@ying01 salt]# yum -y install ansible  ansible-doc

查看ying01 主機上是否有公鑰存在,若不存在則要生成,生成祕鑰命令: ssh-keygengithub

[root@ying01 ~]# ls /root/.ssh/
authorized_keys  id_rsa  id_rsa.pub  known_hosts
[root@ying01 ~]# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+X/2tfggcYIe/3qp98blHj4ySD0GbVmP5QfU7tXXMbE/+FnktHOA3l9+noxXxNXFpaDjc4k+R9TV1R4yG8U0+bx8zucaVTSQWgFCiwDlKhY4pUgfQePtNX+AVUo7yf0+ysz7P3cyUTIInHORB2R/DoKzcxMEM9AHkb//G/UtLaRBhLLWhNGz/R8S5ZhdsC3+X+yKKDVffua8RWkAqevntf4lWz6KEYbuTjxzM7cOXOrHx0/w3/qtvD/Vee+I7vZHkCdqwMfQxn9pTh6c3RwBwcx9jzbJJ7YLV5KmOx0QqSK8qHylgjuO2ZS1wF1+eTdO1D2zP2aEykF6dDNhzQRb5 root@ying01

把此公鑰分別 存放在ying0一、ying0二、ying03機器 的authorized_keys 文件下;

#ansible
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+X/2tfggcYIe/3qp98blHj4ySD0GbVmP5QfU7tXXMbE/+FnktHOA3l9+noxXxNXFpaDjc4k+R9TV1R4yG8U0+bx8zucaVTSQWgFCiwDlKhY4pUgfQePtNX+AVUo7yf0+ysz7P3cyUTIInHORB2R/DoKzcxMEM9AHkb//G/UtLaRBhLLWhNGz/R8S5ZhdsC3+X+yKKDVffua8RWkAqevntf4lWz6KEYbuTjxzM7cOXOrHx0/w3/qtvD/Vee+I7vZHkCdqwMfQxn9pTh6c3RwBwcx9jzbJJ7YLV5KmOx0QqSK8qHylgjuO2ZS1wF1+eTdO1D2zP2aEykF6dDNhzQRb5 root@ying01

編輯/etc/ansible/hosts文件,添加如下語句

[root@ying01 ~]# vim /etc/ansible/hosts 

[testhost]                //主機名稱
127.0.0.1                 //主機IP
ying01                    //主機的ID
ying02
ying03

以上寫IP也能夠,要是寫ID,就須要在 /etc/hosts 裏面定義;由於以前已經定義ID

[root@ying01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
113.108.182.52  www.hao123.com www.baidu.com
127.0.0.1  ying.com
192.168.112.136 ying01
192.168.112.138 ying02
192.168.112.139 ying03

測試如下127.0.0.1主機是否聯通

[root@ying01 ~]# ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:ZQlXi+kieRwi2t64Yc5vUhPPWkMub8f0CBjnYRlX2Iw.
ECDSA key fingerprint is MD5:ff:9f:37:87:81:89:fc:ed:af:c6:62:c6:32:53:7a:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
Last login: Tue Sep 11 11:49:11 2018 from 192.168.112.1
[root@ying01 ~]# w
 13:30:28 up 13:31,  2 users,  load average: 0.12, 0.09, 0.07
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.112.1    11:49    4.00s  0.45s  0.01s ssh 127.0.0.1
root     pts/1    127.0.0.1        13:30    4.00s  0.06s  0.00s w
[root@ying01 ~]# logout
Connection to 127.0.0.1 closed.

在行testhost主機上,執行命令

[root@ying01 ~]# ansible testhost -m command -a 'wc -l /etc/passwd'
ying03 | SUCCESS | rc=0 >>
25 /etc/passwd

ying02 | SUCCESS | rc=0 >>
30 /etc/passwd

127.0.0.1 | SUCCESS | rc=0 >>
53 /etc/passwd

ying01 | SUCCESS | rc=0 >>
53 /etc/passwd

[root@ying01 ~]# ansible 127.0.0.1 -m command -a 'wc -l /etc/passwd'   //能夠針對IP
127.0.0.1 | SUCCESS | rc=0 >>
53 /etc/passwd

[root@ying01 ~]# ansible 'ying03' -m command -a 'wc -l /etc/passwd'   //能夠針對單個定義ID
ying03 | SUCCESS | rc=0 >>
25 /etc/passwd

語句釋義:ansible 批量執行命令,testhost 是主機的集合,-m後面接調用module的名字, -a後面接調用module的參數

shell模塊也能夠執行命令

[root@ying01 ~]# ansible  testhost -m shell -a 'wc -l /etc/passwd'
127.0.0.1 | SUCCESS | rc=0 >>
53 /etc/passwd

ying03 | SUCCESS | rc=0 >>
25 /etc/passwd

ying02 | SUCCESS | rc=0 >>
30 /etc/passwd

ying01 | SUCCESS | rc=0 >>
53 /etc/passwd

[root@ying01 ~]# ansible  testhost -m shell -a 'hostname'
ying01 | SUCCESS | rc=0 >>
ying01

127.0.0.1 | SUCCESS | rc=0 >>
ying01

ying03 | SUCCESS | rc=0 >>
ying03

ying02 | SUCCESS | rc=0 >>
ying02

[root@ying01 ~]# ansible 'ying01' -m shell -a 'wc -l /etc/passwd'
ying01 | SUCCESS | rc=0 >>
53 /etc/passwd

[root@ying01 ~]# ansible 127.0.0.1 -m shell -a 'wc -l /etc/passwd'
127.0.0.1 | SUCCESS | rc=0 >>
53 /etc/passwd

錯誤解決

錯誤: "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"

解決: yum install -y libselinux-python

3、 ansible拷貝文件或目錄

ansible ying02 -m copy -a "src=/etc/ansible dest=/tmp/ansibletest owner=root group=root mode=0755"

  • ying02 : 指定認證主機,能夠是testhost集合,也能夠是ying0三、127.0.0.1等;
  • copy -a "定義內容" :複製定義的內容
  • src=/etc/ansible :定義複製的源目錄及文件
  • dest=/tmp/ansibletest :定義要複製到的位置
  • owner=root :定義uid爲root
  • group=root :組爲root
  • mode=0755 :權限爲755

整個語句意思爲:把master機器的/etc/ansible目錄複製到遠程機器ying02上的/tmp/ansibletest目錄,並指定全部者、全部組及其權限;

[root@ying01 ~]# ansible ying02 -m copy -a "src=/etc/ansible  dest=/tmp/ansibletest owner=root group=root mode=0755"
ying02 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/ansibletest/", 
    "src": "/etc/ansible"
}

在ying02上,查看複製結果

[root@ying02 ~]# ls -la /tmp/ansibletest
總用量 4
drwxr-xr-x   3 root root   21 9月  11 17:35 .
drwxrwxrwt. 17 root root 4096 9月  11 17:35 ..
drwxr-xr-x   3 root root   51 9月  11 17:35 ansible
[root@ying02 ~]# tree /tmp/ansibletest
/tmp/ansibletest
└── ansible
    ├── ansible.cfg
    ├── hosts
    └── roles

2 directories, 2 files

ying02上未指定目錄,會自動建立目錄

[root@ying01 ~]# ansible ying02 -m copy -a "src=/etc/ansible  dest=/tmp/  owner=root group=root mode=0755"
ying02 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/etc/ansible"
}

在ying02上,查看複製結果

[root@ying02 ~]# ls -ld /tmp/ansible
drwxr-xr-x 3 root root 51 9月  11 17:40 /tmp/ansible

[root@ying02 ~]# tree /tmp/ansible
/tmp/ansible
├── ansible.cfg
├── hosts
└── roles

1 directory, 2 files

注意:

  • 源目錄會放到目標目錄下面去,
  • 若是目標指定的目錄不存在,它會自動建立。
  • 若是拷貝的是文件,dest指定的名字和源若是不一樣,而且它不是已經存在的目錄,至關於拷貝過去後又重命
  • 但相反,若是desc是目標機器上已經存在的目錄,則會直接把文件拷貝到該目錄下面。

4、 ansible遠程執行腳本

建立test.sh腳本

[root@ying01 ~]# vim /tmp/test.sh 

#!/bin/bash
 echo `date` > /tmp/ansible_test.txt   //建立ansible_test.txt文件

把此腳本複製到ying03主機上,並更名爲test1.sh

[root@ying01 ~]# ansible ying03 -m copy -a "src=/tmp/test.sh  dest=/tmp/test1.sh  owner=root group=root mode=0755"
ying03 | SUCCESS => {
    "changed": true, 
    "checksum": "1a6e4af02dba1bda6fc8e23031d4447efeba0ade", 
    "dest": "/tmp/test1.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "edfaa4371316af8c5ba354e708fe8a97", 
    "mode": "0755", 
    "owner": "root", 
    "size": 48, 
    "src": "/root/.ansible/tmp/ansible-tmp-1536660710.3-139886566503496/source", 
    "state": "file", 
    "uid": 0
}
[root@ying01 ~]# ansible ying03 -m shell -a "/tmp/test1.sh"  //遠程執行test1.sh腳本
ying03 | SUCCESS | rc=0 >>

查看ansible_test.txt內容及相關狀況

[root@ying03 ~]# cat /tmp/ansible_test.txt
2018年 09月 11日 星期二 18:12:56 CST
[root@ying03 ~]# ls -l  /tmp/ansible_test.txt
-rw-r--r-- 1 root root 43 9月  11 18:12 /tmp/ansible_test.txt

注意:-m command 不支持管道符,而-m shell 支持管道

-m command 不支持管道

[root@ying01 ~]# ansible testhost  -m command -a 'cat /etc/passwd |wc -l'
ying03 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code

ying02 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code

ying01 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code

127.0.0.1 | FAILED | rc=1 >>
cat:無效選項 -- l
Try 'cat --help' for more information.non-zero return code

-m shell 支持管道

[root@ying01 ~]# ansible testhost  -m shell -a 'cat /etc/passwd |wc -l'
ying02 | SUCCESS | rc=0 >>
30

ying03 | SUCCESS | rc=0 >>
25

127.0.0.1 | SUCCESS | rc=0 >>
53

ying01 | SUCCESS | rc=0 >>
53

5、ansible管理任務計劃

  • 新建管理任務計劃

給ying02機器,建立名爲test cron 的管理認爲計劃

[root@ying01 ~]# ansible ying02 -m cron -a "name='test cron' job='/bin/touch /tmp/1212.txt' weekday=6"
ying02 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]

用crontab -l查看此管理計劃

[root@ying02 ~]# crontab -l
# Lines below here are managed by Salt, do not edit
#Ansible: test cron
* * * * 6 /bin/touch /tmp/1212.txt
  • 管理計劃任務

state=absent 定義狀態爲無,便可刪除此計劃任務

[root@ying01 ~]# ansible ying02 -m cron -a "name='test cron' state=absent"
ying02 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}

在ying02上驗證,此時已經無任務計劃,說明刪除成功

[root@ying02 ~]# crontab -l
# Lines below here are managed by Salt, do not edit

注意:由ansible管理的計劃任務 (crontab -e),請不要手動修改,不然會致使ansible沒法再管理相應的計劃任務

6、ansible安裝包和管理服務

刪除httpd模塊

[root@ying01 ~]# ansible ying02 -m yum -a "name=httpd state=removed" 
ying02 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加載插件:fastestmirror\n正在解決依賴關係\n--> 正在檢查事務\n---> 軟件包 httpd.x86_64.0.2.4.6-80.el7.centos.1 將被 刪除\n--> 正在處理依賴關係 httpd = 2.4.6-80.el7.centos.1,它被軟件包 httpd-devel-2.4.6-80.el7.centos.1.x86_64 須要\n--> 正在檢查事務\n---> 軟件包 httpd-devel.x86_64.0.2.4.6-80.el7.centos.1 將被 刪除\n--> 解決依賴關係完成\n\n依賴關係解決\n\n================================================================================\n Package          架構        版本                          源             大小\n================================================================================\n正在刪除:\n httpd            x86_64      2.4.6-80.el7.centos.1         @updates      9.4 M\n爲依賴而移除:\n httpd-devel      x86_64      2.4.6-80.el7.centos.1         @updates      749 k\n\n事務概要\n================================================================================\n移除  1 軟件包 (+1 依賴軟件包)\n\n安裝大小:10 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在刪除    : httpd-devel-2.4.6-80.el7.centos.1.x86_64                    1/2 \n  正在刪除    : httpd-2.4.6-80.el7.centos.1.x86_64                          2/2 \n  驗證中      : httpd-devel-2.4.6-80.el7.centos.1.x86_64                    1/2 \n  驗證中      : httpd-2.4.6-80.el7.centos.1.x86_64                          2/2 \n\n刪除:\n  httpd.x86_64 0:2.4.6-80.el7.centos.1                                          \n\n做爲依賴被刪除:\n  httpd-devel.x86_64 0:2.4.6-80.el7.centos.1                                    \n\n完畢!\n"
    ]
}

在ying02機器上,查看httpd是否刪除

[root@ying02 ~]# rpm -qa httpd                   
[root@ying02 ~]# netstat -lnpt |grep httpd

安裝httpd

[root@ying01 ~]# ansible ying02 -m yum -a "name=httpd" 
ying02 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: centos.ustc.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-80.el7.centos.1 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package      Arch          Version                        Repository      Size\n================================================================================\nInstalling:\n httpd        x86_64        2.4.6-80.el7.centos.1          updates        2.7 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-2.4.6-80.el7.centos.1.x86_64                           1/1 \n  Verifying  : httpd-2.4.6-80.el7.centos.1.x86_64                           1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-80.el7.centos.1                                          \n\nComplete!\n"
    ]
}

啓動httpd

[root@ying01 ~]# ansible ying02 -m service -a "name=httpd state=started enabled=no" 
ying02 | SUCCESS => {
    "changed": true, 
    "enabled": false, 
    "name": "httpd", 
    "state": "started", 
    篇幅緣由,省略

在ying02機器上,驗證httpd是否啓動

[root@ying02 ~]# netstat -lnpt |grep httpd
tcp6       0      0 :::80                   :::*                    LISTEN      31897/httpd         
[root@ying02 ~]# ps aux |grep httpd
root     31897  0.0  0.2 224020  4996 ?        Ss   20:53   0:00 /usr/sbin/httpd -DFOREGROUND
apache   31898  0.0  0.1 224020  2952 ?        S    20:53   0:00 /usr/sbin/httpd -DFOREGROUND
apache   31899  0.0  0.1 224020  2952 ?        S    20:53   0:00 /usr/sbin/httpd -DFOREGROUND
apache   31900  0.0  0.1 224020  2952 ?        S    20:53   0:00 /usr/sbin/httpd -DFOREGROUND
apache   31901  0.0  0.1 224020  2952 ?        S    20:53   0:00 /usr/sbin/httpd -DFOREGROUND
apache   31902  0.0  0.1 224020  2952 ?        S    20:53   0:00 /usr/sbin/httpd -DFOREGROUND
root     32086  0.0  0.0 112720   984 pts/0    S+   21:01   0:00 grep --color=auto httpd

注意:這裏的name是centos系統裏的服務名,能夠經過chkconfig --list查到。

ansible-doc -l : 列出全部的模塊

[root@ying01 ~]# ansible-doc -l|grep httpd
apache2_mod_proxy                                    Set and/or get members' attributes of an Apache httpd 2.4 mod_proxy balancer pool                  
bigip_device_httpd                                   Manage HTTPD related settings on BIG-IP

ansible-doc cron :查看指定模塊的文檔

[root@ying01 ~]# ansible-doc cron 
> CRON    (/usr/lib/python2.7/site-packages/ansible/modules/system/cron.py)

        Use this module to manage crontab and environment variables entries. This module allows you to create environment
        variables and named crontab entries, update, or delete them. When crontab jobs are managed: the module includes one
        line with the description of the crontab entry `"#Ansible: <name>"' corresponding to the "name" passed to the module,
        which is used by future ansible/module calls to find/check the state. The "name" parameter should be unique, and
        changing the "name" value will result in a new cron task being created (or a different one being removed). When
        environment variables are managed: no comment line is added, but, when the module needs to find/check the state, it
        uses the "name" parameter to find the environment variable definition line. When using symbols such as %, they must
        be properly escaped.

OPTIONS (= is mandatory):

篇幅緣由,下面內容省略

7、使用ansible playbook

  • Playbooks 是 Ansible的配置,部署,編排語言.他們能夠被描述爲一個須要但願遠程主機執行命令的方案,或者一組IT程序運行的命令集合.
  • 若是 Ansible 模塊你是工做室中的工具,那麼 playbooks 就是你設置的方案計劃.
  • Playbooks 的格式是YAML。
[root@ying01 ~]# cd /etc/ansible/
[root@ying01 ansible]# ls
ansible.cfg  hosts  roles
[root@ying01 ansible]# vim test.yml

---
- hosts: ying02                      //針對ying02主機,若果多個主機,能夠用逗號隔開
  remote_user: root                  //遠程用戶爲root
  tasks:                             //任務
    - name: test_playbook            //任務名 test_playbook 
      shell: touch /tmp/qqq.txt      //用到shell模塊

執行test.yml文件方案

[root@ying01 ansible]# ansible-playbook test.yml

PLAY [ying02] ***********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying02]

TASK [test_playbook] ****************************************************************************************************************************************
 [WARNING]: Consider using the file module with state=touch rather than running touch.  If you need to use command because file 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: [ying02]

PLAY RECAP **************************************************************************************************************************************************
ying02                     : ok=2    changed=1    unreachable=0    failed=0

在ying02機器上驗證

[root@ying02 ~]# ls -l /tmp/qqq.txt
-rw-r--r-- 1 root root 0 9月  11 21:24 /tmp/qqq.txt
[root@ying02 ~]# date
2018年 09月 11日 星期二 21:26:19 CST

8、playbook裏的變量

建立create_user.yml文件

[root@ying01 ansible]# vim create_user.yml

---
- name: create_user
  hosts: ying02
  user: root
  gather_facts: false              //false 不收集主機相關信息;ture :與之相反
  vars:
    - user: "test"
  tasks:
    - name: create user
      user: name="{{ user }}"

create_user.yml文件語句釋義:

  • name參數對該playbook實現的功能作一個概述,後面執行過程當中,會打印name變量的值,能夠省略;
  • gather_facts參數指定了在如下任務部分執行前,是否先執行setup模塊獲取主機相關 信息,若是後面的task會使用到setup獲取的信息時會用到;
  • vars參數,指定了變量,這裏指字一個user變量,其值爲test,須要注意的是,變量值必定要用引號引住;
  • user指定了調用user模塊,name是user模塊裏的一個參數,而增長的用戶名字調用了上面user變量的值。

執行此文件

[root@ying01 ansible]# ansible-playbook create_user.yml 

PLAY [create_user] ******************************************************************************************************************************************

TASK [create user] ******************************************************************************************************************************************
changed: [ying02]

PLAY RECAP **************************************************************************************************************************************************
ying02                     : ok=1    changed=1    unreachable=0    failed=0

在ying02上,測試執行結果

[root@ying02 ~]# id test
uid=1002(test) gid=1002(test) 組=1002(test)

9、playbook裏的循環

建立while.yml文件

[root@ying01 ansible]# pwd
/etc/ansible
[root@ying01 ansible]# vim while.yml

---
- hosts: ying02                                       //針對ying02主機
  user: root                                          //用戶爲root
  tasks: 
    - name: change mode for files                      //任務名稱屬性   
      file: path=/tmp/{{ item }} state=touch mode=600  //定義變量item ,先建立,再給予權限
      with_items:                                      //item文本集合
        - 1.txt
        - 2.txt
        - 3.txt

執行 while.yml文件;Gathering Facts又出現,由於咱們沒有禁掉;

[root@ying01 ansible]# ansible-playbook while.yml 

PLAY [ying02] ***********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying02]

TASK [change mode for files] ********************************************************************************************************************************
changed: [ying02] => (item=1.txt) 
changed: [ying02] => (item=2.txt)
changed: [ying02] => (item=3.txt)

PLAY RECAP **************************************************************************************************************************************************
ying02                     : ok=2    changed=1    unreachable=0    failed=0

在ying02上,測試此循環試驗成功,每一個文件都建立,並授予600權限

[root@ying02 ~]# ls -l /tmp/?.txt
-rw------- 1 root root 0 9月  11 22:49 /tmp/1.txt
-rw------- 1 root root 0 9月  11 22:49 /tmp/2.txt
-rw------- 1 root root 0 9月  11 22:49 /tmp/3.txt

10、playbook裏的條件判斷

建立when.yml條件判斷的yml文本

[root@ying01 ansible]# vim when.yml

---
- hosts: testhost
  user: root
  gather_facts: True
  tasks:
    - name: use when
      shell: touch /tmp/when.txt         //
      when: ansible_ens33.ipv4.address == "192.168.112.138"

when: ansible_ens33.ipv4.address == "192.168.112.138" 釋義:

  • when: 爲ansble模塊
  • ansible_ens33 :爲一個1級範圍
  • ipv4:爲ansible_ens33範圍內的子集;
  • address:爲ipv4的一個子集;
  • == "192.168.112.138" :匹配此IP

上面的when條件語句,就經過查看facter信息,來設置條件;

查看全部的facter信息: ansible ying02 -m setup

[root@ying01 ansible]# ansible ying02 -m setup

如下內容爲節選,爲了突出when條件

"ansible_ens33": {                                //此爲1級條件
            "active": true, 
            "device": "ens33", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
            
                "vlan_challenged": "off [fixed]"
            }, 
            "hw_timestamp_filters": [],  
            "ipv4": {                            //此爲2級條件        
                "address": "192.168.112.138",    //此爲3級條件
                "broadcast": "192.168.112.255", 
                "netmask": "255.255.255.0", 
                "network": "192.168.112.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::43bd:36bd:3f01:f8e8", 
                    "prefix": "64", 
                    "scope": "link"
                }

執行 when.yml方案

[root@ying01 ansible]# ansible-playbook when.yml 

PLAY [testhost] *********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying02]
ok: [ying03]
ok: [ying01]
ok: [127.0.0.1]

TASK [use when] *********************************************************************************************************************************************
skipping: [127.0.0.1]
skipping: [ying01]
skipping: [ying03]
 [WARNING]: Consider using the file module with state=touch rather than running touch.  If you need to use command because file 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: [ying02]

PLAY RECAP **************************************************************************************************************************************************
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0   
ying01                     : ok=1    changed=0    unreachable=0    failed=0   
ying02                     : ok=2    changed=1    unreachable=0    failed=0   
ying03                     : ok=1    changed=0    unreachable=0    failed=0

在ying02機器上,驗證,有when.txt生成;由於只有ying02符合條件

[root@ying02 ~]# ls -l /tmp/when.txt
-rw-r--r-- 1 root root 0 9月  11 23:09 /tmp/when.txt

其餘機器都沒有,由於不符合when條件

[root@ying03 ~]# ls -l /tmp/when.txt
ls: 沒法訪問/tmp/when.txt: 沒有那個文件或目錄

11、playbook中的handlers

Ansible playbook中的handlers可實現相似邏輯與的功能。(至關於shell中&&)

運用場景爲:修改完配置文件後,從新加載配置文件;

建立handlers.yml文件

[root@ying01 ansible]# vim handlers.yml

---
- name: handlers test
  hosts: ying02
  user: root
  tasks:
    - name: copy file
      copy: src=/etc/passwd dest=/tmp/bbb.txt      //先複製
      notify: test handlers
  handlers:
    - name: test handlers
      shell: echo "111111" >> /tmp/bbb.txt        //再寫入內容

說明:此處必要copy步驟成功,handlers纔可以繼續執行;邏輯而且

執行 handlers.yml文件

[root@ying01 ansible]# ansible-playbook handlers.yml 

PLAY [handlers test] ****************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying02]

TASK [copy file] ********************************************************************************************************************************************
changed: [ying02]

RUNNING HANDLER [test handlers] *****************************************************************************************************************************
changed: [ying02]

PLAY RECAP **************************************************************************************************************************************************
ying02                     : ok=3    changed=2    unreachable=0    failed=0

在ying02機器上,測試bbb.txt文本有111111寫入,試驗成功

[root@ying02 ~]# tail /tmp/bbb.txt 
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
zabbix:x:997:994:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin
memcached:x:996:993:Memcached daemon:/run/memcached:/sbin/nologin
mongod:x:995:992:mongod:/var/lib/mongo:/bin/false
gitlab-www:x:994:990::/var/opt/gitlab/nginx:/bin/false
git:x:993:989::/var/opt/gitlab:/bin/sh
gitlab-redis:x:992:988::/var/opt/gitlab/redis:/bin/false
gitlab-psql:x:991:987::/var/opt/gitlab/postgresql:/bin/sh
gitlab-prometheus:x:990:986::/var/opt/gitlab/prometheus:/bin/sh
111111

12、 playbook安裝nginx

  • 實戰:批量安裝源碼nginx
  • 思路:先在一臺機器上編譯安裝好nginx、打包,而後再用ansible去下發

第一步:建立/etc/ansible/nginx_install目錄及其子目錄

[root@ying01 ~]# cd /etc/ansible
[root@ying01 ansible]# cd nginx_install/
[root@ying01 nginx_install]# mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
[root@ying01 nginx_install]# tree 
.
└── roles                    //install      此目錄爲安裝nginx操做
    ├── common               //此目錄爲一些準備操做
    │   ├── files               //此目錄存放一些安裝nginx時用到的文件
    │   ├── handlers            //當發生改變時要執行的操做,好比配置文件發生改變了,就要重啓nginx服務
    │   ├── meta                //此目錄存放說明信息
    │   ├── tasks               //存放核心的配置文件
    │   ├── templates           //存放一些配置文件,啓動腳本等模塊文件
    │   └── vars                //自定義變量
    └── install             //此目錄爲安裝nginx操做
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars

第二步:肯定須要打包的nginx目錄文件

[root@ying01 nginx_install]# pwd
/etc/ansible/nginx_install
您在 /var/spool/mail/root 中有新郵件
[root@ying01 nginx_install]# ls /usr/local/nginx/
client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  sbin  scgi_temp  uwsgi_temp
[root@ying01 nginx_install]# ls /etc/init.d/nginx 
/etc/init.d/nginx
[root@ying01 nginx_install]# ls /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/conf/nginx.conf

第三步:打包nginx目錄下,除vhost的全部有關nginxd文件;把nginx配置文件、啓動腳本複製到roles/install/templates/下;

[root@ying01 nginx_install]# cd /usr/local/
[root@ying01 local]# tar czf nginx.tar.gz --exclude "nginx.conf" --exclude "vost"
[root@ying01 local]# tar czf nginx.tar.gz --exclude "nginx.conf" --exclude "vhost" nginx/
[root@ying01 local]# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/
[root@ying01 local]# cp nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
[root@ying01 local]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates

[root@ying01 local]# cd /etc/ansible/nginx_install/roles/
[root@ying01 roles]# tree         //查看已複製到位的文件
.
├── common
│   ├── files
│   ├── handlers
│   ├── meta
│   ├── tasks
│   ├── templates
│   └── vars
└── install
    ├── files
    │   └── nginx.tar.gz
    ├── handlers
    ├── meta
    ├── tasks
    ├── templates
    │   ├── nginx
    │   └── nginx.conf
    └── vars

14 directories, 3 files

第四步:定義普通的tasks,建立main.yml文件

[root@ying01 roles]# cd common/
[root@ying01 common]# vim tasks/main.yml

- name: Install initializtion require software
  yum: name={{ item }} state=installed   //循環安裝所需包
  with_items:
    - zlib-devel
    - pcre-devel

第五步:定義變量,建立/install/vars/main.yml 文件

[root@ying01 common]# vim /etc/ansible/nginx_install/roles/install/vars/main.yml 

nginx_user: www                         //用戶
nginx_port: 800                         //端口
nginx_basedir: /usr/local/nginx         //nginx目錄

第六步:定義文件拷貝配置文件

[root@ying01 common]# vim /etc/ansible/nginx_install/roles/install/tasks/copy.yml

- name: Copy Nginx Software                 //把nginx包複製到指定目錄
  copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root  
- name: Uncompression Nginx Software         //用shell模塊遠程解壓到/usr/local下
  shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/                      
- name: Copy Nginx Start Script              //複製啓動nginx腳本                     
  template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755  
- name: Copy Nginx Config                    //複製nginx配置文件,經過變量,即/usr/local/nginx下
  template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root mode=0644

第七步:創建用戶、啓動服務。刪除安裝包

[root@ying01 ~]# vim  /etc/ansible/nginx_install/roles/install/tasks/install.yml 

- name: Create Nginx User                   //建立用戶信息等
  user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin
- name: Start Nginx Service                 //遠程啓動nginx
  shell: /etc/init.d/nginx start
- name: Add Boot Start Nginx Service        //增長nginx服務,到啓動項
  shell: chkconfig --level 345 nginx on
- name: Delete Nginx compression files        //刪除nginx.tar.gz包
  shell: rm -rf /tmp/nginx.tar.gz

第八步:建立main.yml,調用copy和install

[root@ying01 ~]# vim /etc/ansible/nginx_install/roles/install/tasks/main.yml 

- include: copy.yml
- include: install.yml

第九步:建立入口文件

[root@ying01 ~]# vim /etc/ansible/nginx_install/install.yml

---
- hosts: ying03
  remote_user: root
  gather_facts: True
  roles:
    - common
    - install

在認證主機ying03上,由於以前安裝有nginx,所以把設計nginx改成nginx1,防止試驗干涉;

[root@ying03 ~]# cd /usr/local/
[root@ying03 local]# mv nginx nginx1
[root@ying03 local]# ls
bin  etc  games  include  lib  lib64  libexec  mysql  nginx1  sbin  share  src
[root@ying03 local]# ls /etc/init.d/
functions  mysqld  netconsole  network  nginx  README
[root@ying03 local]# cd /etc/init.d/
[root@ying03 init.d]# ls
functions  mysqld  netconsole  network  nginx  README
[root@ying03 init.d]# mv nginx nginx1

在ying01上,開始執行總入口的install.yml文件

[root@ying01 ~]# ansible-playbook /etc/ansible/nginx_install/install.yml

PLAY [ying03] ***********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying03]

TASK [common : Install initializtion require software] ******************************************************************************************************
ok: [ying03] => (item=[u'zlib-devel', u'pcre-devel'])

TASK [install : Copy Nginx Software] ************************************************************************************************************************
changed: [ying03]

TASK [install : Uncompression Nginx Software] ***************************************************************************************************************
 [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: [ying03]

TASK [install : Copy Nginx Start Script] ********************************************************************************************************************
changed: [ying03]

TASK [install : Copy Nginx Config] **************************************************************************************************************************
changed: [ying03]

TASK [install : Create Nginx User] **************************************************************************************************************************
changed: [ying03]

TASK [install : Start Nginx Service] ************************************************************************************************************************
changed: [ying03]

TASK [install : Add Boot Start Nginx Service] ***************************************************************************************************************
changed: [ying03]

TASK [install : Delete Nginx compression files] *************************************************************************************************************
 [WARNING]: Consider using the file module with state=absent rather than running rm.  If you need to use command because file 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: [ying03]

PLAY RECAP **************************************************************************************************************************************************
ying03                     : ok=10   changed=8    unreachable=0    failed=0

到ying03機器上測試,有nginx的進程,說明是試驗成功

[root@ying03 init.d]# ps aux |grep nginx
root      8748  0.0  0.1  45576  1076 ?        Ss   01:01   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody    8749  0.0  0.3  47928  3704 ?        S    01:01   0:00 nginx: worker process
nobody    8750  0.0  0.3  47928  3704 ?        S    01:01   0:00 nginx: worker process
root      8887  0.0  0.0 112720   980 pts/0    S+   01:02   0:00 grep --color=auto nginx

十3、 playbook管理配置文件

生產環境中安裝軟件包只是在初始化環境的時候用一下,大多時候是須要管理配置文件的。此時能夠用playbook功能。

建立playbook配置目錄結構

[root@ying01 ~]#  mkdir  -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
[root@ying01 ~]# cd /etc/ansible/nginx_config/
[root@ying01 nginx_config]# tree
/etc/ansible/nginx_config/
└── roles
    ├── new
    │   ├── files
    │   ├── handlers
    │   ├── tasks
    │   └── vars
    └── old
        ├── files
        ├── handlers
        ├── tasks
        └── vars

11 directories, 0 files

把nginx虛擬主機,複製到nginx_config/roles/new/files/目錄下

[root@ying01 nginx_config]#  cd /usr/local/nginx/conf/
[root@ying01 conf]# cp -r nginx.conf vhost  /etc/ansible/nginx_config/roles/new/files/
[root@ying01 conf]# cd -
/etc/ansible/nginx_config
[root@ying01 nginx_config]# tree
.
└── roles
    ├── new
    │   ├── files
    │   │   ├── nginx.conf
    │   │   └── vhost
    │   │       ├── aaa.com.conf
    │   │       ├── load.conf
    │   │       ├── proxy.conf
    │   │       ├── ssl.conf
    │   │       └── test.com.conf
    │   ├── handlers
    │   ├── tasks
    │   └── vars
    └── old
        ├── files
        ├── handlers
        ├── tasks
        └── vars

12 directories, 6 files

定義變量文件

[root@ying01 nginx_config]#  vim /etc/ansible/nginx_config/roles/new/vars/main.yml

nginx_basedir: /usr/local/nginx

定義nginx從新加載配置

[root@ying01 nginx_config]# vim /etc/ansible/nginx_config/roles/new/handlers/main.yml  

- name: restart nginx
  shell: /etc/init.d/nginx reload

定義主配置文件

[root@ying01 nginx_config]# vim /etc/ansible/nginx_config/roles/new/tasks/main.yml 

- name: copy conf file
  copy: src={{ item.src }} dest={{ nginx_basedir }}/{{ item.dest }} backup=yes owner=root group=root mode=0644
  with_items:
    - { src: nginx.conf, dest: conf/nginx.conf }
    - { src: vhosts, dest: conf/ }
  notify: restart nginx

定義總入口配置,建立update.yml文件

[root@ying01 nginx_config]# vim /etc/ansible/nginx_config/update.yml 

---
- hosts: ying03
  user: root
  roles:
  - new

執行update.yml文件

[root@ying01 nginx_config]# ansible-playbook /etc/ansible/nginx_config/update.yml

PLAY [ying03] ***********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying03]

TASK [new : copy conf file] *********************************************************************************************************************************
ok: [ying03] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
changed: [ying03] => (item={u'dest': u'conf/', u'src': u'vhost'})

RUNNING HANDLER [new : restart nginx] ***********************************************************************************************************************
changed: [ying03]

PLAY RECAP **************************************************************************************************************************************************
ying03                     : ok=3    changed=2    unreachable=0    failed=0

在客戶端ying03測試,nginx服務從新加載

[root@ying03 ~]# ps aux |grep nginx
root      8945  0.0  0.2  45856  2900 ?        Ss   01:07   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody   10713  0.0  0.3  48208  3964 ?        S    02:11   0:00 nginx: worker process
nobody   10714  0.0  0.3  48208  3964 ?        S    02:11   0:00 nginx: worker process
root     10724  0.0  0.0 112720   984 pts/0    R+   02:12   0:00 grep --color=auto nginx

[root@ying03 ~]# ls /usr/local/nginx/conf/vhost/          //vhost也被複制到指定目錄
aaa.com.conf  load.conf  proxy.conf  ssl.conf  test.com.conf

文件的回滾測試

在ying01機器上,把new文件夾備份到old文件夾

[root@ying01 nginx_config]# rsync -av roles/new/ roles/old/
sending incremental file list
files/
files/nginx.conf
files/vhost/
files/vhost/aaa.com.conf
files/vhost/load.conf
files/vhost/proxy.conf
files/vhost/ssl.conf
files/vhost/test.com.conf
handlers/
handlers/main.yml
tasks/
tasks/main.yml
vars/
vars/main.yml

sent 4,919 bytes  received 207 bytes  10,252.00 bytes/sec
total size is 4,105  speedup is 0.80
[root@ying01 nginx_config]# tree
.
├── roles
│   ├── new
│   │   ├── files
│   │   │   ├── nginx.conf
│   │   │   └── vhost
│   │   │       ├── aaa.com.conf
│   │   │       ├── load.conf
│   │   │       ├── proxy.conf
│   │   │       ├── ssl.conf
│   │   │       └── test.com.conf
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── vars
│   │       └── main.yml
│   └── old
│       ├── files
│       │   ├── nginx.conf
│       │   └── vhost
│       │       ├── aaa.com.conf
│       │       ├── load.conf
│       │       ├── proxy.conf
│       │       ├── ssl.conf
│       │       └── test.com.conf
│       ├── handlers
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
├── update.retry
└── update.yml

13 directories, 20 files

建立rollback.yml 文件

[root@ying01 nginx_config]# vim /etc/ansible/nginx_config/rollback.yml 

---
- hosts: ying03
  user: root
  roles:
  - old

在ying上,配置文件nginx.conf,在include前面加上#號

[root@ying01 nginx_config]# vim /etc/ansible/nginx_config/roles/new/files/nginx.conf

 # include vhost/*.conf;

在ying02上測試,發現include前面有#號

[root@ying03 ~]# tail -5 /usr/local/nginx/conf/nginx.conf
    gzip_http_version 1.1;
    gzip_types text/plain application/x-javascript text/css text/htm 
    application/xml;
  # include vhost/*.conf;

執行rollback.yml 文件

[root@ying01 nginx_config]# ansible-playbook /etc/ansible/nginx_config/rollback.yml 

PLAY [ying03] ***********************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [ying03]

TASK [old : copy conf file] *********************************************************************************************************************************
ok: [ying03] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
ok: [ying03] => (item={u'dest': u'conf/', u'src': u'vhost'})

PLAY RECAP **************************************************************************************************************************************************
ying03                     : ok=2    changed=0    unreachable=0    failed=0

在ying02上測試,發現include的#消失了,試驗成功

[root@ying03 ~]# tail -5 /usr/local/nginx/conf/nginx.conf
    gzip_http_version 1.1;
    gzip_types text/plain application/x-javascript text/css text/htm 
    application/xml;
    include vhost/*.conf;
}
相關文章
相關標籤/搜索