自動化運維之ansible

第三十九課 自動化運維之ansiblephp

目錄html

十5、 ansible介紹
十6、 ansible安裝
十7、 ansible遠程執行命令
十8、 ansible拷貝文件或目錄
十9、 ansible遠程執行腳本
二10、 ansible管理任務計劃
二11、 ansible安裝包和管理服務
二12、 使用ansible playbook
二十3、 playbook裏的變量
二十4、 playbook裏的循環
二十5、 playbook裏的條件判斷
二十6、 playbook中的handlers
二十7、 playbook安裝nginx
二十8、 playbook管理配置文件node


十5、 ansible介紹

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

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

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

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

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

Ansible有提供命令行版本,免費。也有提供UI(瀏覽器圖形化)版本,網址: www.ansible.com/tower,可是收費的。shell

官方文檔: http://docs.ansible.com/ansible/latest/index.htmlapache

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

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


十6、 ansible安裝

環境:

ansiblemanager 192.168.1.51 CentOS Linux release 7.5.1804 (Core)

ansiblemanaged01 192.168.1.52 CentOS Linux release 7.5.1804 (Core)

ansiblemanaged02 192.168.1.53 CentOS Linux release 7.5.1804 (Core)

爲三臺主機配置hosts文件

[root@ansiblemanager ~]# vim /etc/hosts
// 添加以下內容
192.168.1.51 ansiblemanager
192.168.1.52 ansiblemanaged01
192.168.1.53 ansiblemanaged02

1.在ansiblemanager上安裝ansible

// 查看源裏自帶的ansible版本
[root@ansiblemanager ~]# yum list | grep ansible
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
ansible.noarch                            2.6.2-1.el7                  epel     
ansible-doc.noarch                        2.6.2-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   
// 安裝ansible
[root@ansiblemanager ~]# yum -y install ansible  ansible-doc.noarch

2.在ansiblemanager上生成密鑰

[root@ansiblemanager ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:SelwQ1T30hy8SQxvHWlQ/0YmDvm0VNYvAR9qrVdqFb8 root@ansiblemanager
The key's randomart image is:
+---[RSA 2048]----+
|       .o.. +*=+=|
|       . . . X=O*|
|      . =   *.&+X|
|       = o . X+O+|
|        S   . BEo|
|             o . |
|                 |
|                 |
|                 |
+----[SHA256]-----+
[root@ansiblemanager ~]# ssh-copy-id 192.168.1.52
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.1.52 (192.168.1.52)' can't be established.
ECDSA key fingerprint is SHA256:F7bJ5VTokx6I6FGONg5glMgIm7xggOdBnDfnOz1WAm4.
ECDSA key fingerprint is MD5:d3:c0:12:84:40:a4:89:27:3f:bd:1a:2b:e5:2e:cc:27.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.52's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.1.52'"
and check to make sure that only the key(s) you wanted were added.

[root@ansiblemanager ~]# ssh 192.168.1.52
Last login: Wed Sep  5 17:31:52 2018 from ansiblemanaged01
[root@ansiblemanaged01 ~]# logout
Connection to 192.168.1.52 closed.
[root@ansiblemanager ~]# ssh-copy-id 192.168.1.53
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.1.53 (192.168.1.53)' can't be established.
ECDSA key fingerprint is SHA256:F7bJ5VTokx6I6FGONg5glMgIm7xggOdBnDfnOz1WAm4.
ECDSA key fingerprint is MD5:d3:c0:12:84:40:a4:89:27:3f:bd:1a:2b:e5:2e:cc:27.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.1.53's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.1.53'"
and check to make sure that only the key(s) you wanted were added.

[root@ansiblemanager ~]# ssh 192.168.1.53
Last login: Wed Sep  5 17:32:23 2018 from ansiblemanaged01
[root@ansiblemanaged02 ~]# logout
Connection to 192.168.1.53 closed.

3.新建配置被管理主機清單文件/etc/ansible/hosts

[root@ansiblemanager ~]# vim /etc/ansible/hosts
// 添加如下內容
[testhosts]
192.168.1.52
192.168.1.53


十7、 ansible遠程執行命令

ansible命令的格式是:

ansible <host-pattern> [options]

演示:

// 批量執行命令,-m後面接調用module的名字, -a後面接調用module的參數
[root@ansiblemanager ~]# ansible  testhosts -m command -a 'w' 
192.168.1.52 | SUCCESS | rc=0 >>
 17:49:21 up 59 min,  3 users,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      16:52   56:01   0.02s  0.02s -bash
root     pts/0    192.168.1.9      16:52    3:13   0.32s  0.32s -bash
root     pts/1    ansiblemanager   17:49    0.00s  0.11s  0.00s w

192.168.1.53 | SUCCESS | rc=0 >>
 17:49:22 up 58 min,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      16:53   55:46   0.01s  0.01s -bash
root     pts/0    192.168.1.9      16:53    3:14   0.31s  0.31s -bash
root     pts/1    ansiblemanager   17:49    1.00s  0.08s  0.00s w

// 也能夠針對單主機執行命令
[root@ansiblemanager ~]# ansible 192.168.1.52 -m command -a 'uptime'
192.168.1.52 | SUCCESS | rc=0 >>
 10:24:44 up 54 min,  2 users,  load average: 0.00, 0.01, 0.03
 
// shell模塊也能夠執行命令
[root@ansiblemanager ~]# ansible  testhosts -m shell -a 'w'
192.168.1.52 | SUCCESS | rc=0 >>
 10:26:16 up 55 min,  2 users,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.1.9      09:31    3:52   0.01s  0.01s -bash
root     pts/1    ansiblemanager   10:26    0.00s  0.05s  0.00s w

192.168.1.53 | SUCCESS | rc=0 >>
 10:26:16 up 55 min,  2 users,  load average: 0.00, 0.01, 0.02
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.1.9      09:31   55:08   0.01s  0.01s -bash
root     pts/1    ansiblemanager   10:26    0.00s  0.08s  0.00s w

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

解決: yum install -y libselinux-python


十8、 ansible拷貝文件或目錄

1.拷貝目錄

// 源目錄會放到目標目錄下面去,若是目標指定的目錄不存在,它會自動建立。
// 若是拷貝的是文件,dest指定的名字和源若是不一樣,而且它不是已經存在的目錄,
// 至關於拷貝過去後又重命名。但相反,若是desc是目標機器上已經存在的目錄,
// 則會直接把文件拷貝到該目錄下面。
[root@ansiblemanager ~]# ansible 192.168.1.52 -m copy -a "src=/etc/ansible dest=/tmp owner=root group=root mode=755"
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/etc/ansible"
}
// 在192.168.1.52上查看
[root@ansiblemanaged01 ~]# ls -l /tmp/
total 0
drwxr-xr-x 3 root root 51 Sep  6 10:39 ansible
drwx------ 2 root root  6 Sep  6 09:14 vmware-root
[root@ansiblemanaged01 ~]#

2.拷貝文件

// 拷貝的行爲相似於copy命令
[root@ansiblemanager ~]# ansible 192.168.1.52 -m copy -a "src=/etc/inittab dest=/tmp"                                       
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "checksum": "e285e50c4dd88d8a2f644dd1750f60400ca60f94", 
    "dest": "/tmp/inittab", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "66a88d6c4d693170753ea3382f8bc150", 
    "mode": "0644", 
    "owner": "root", 
    "size": 511, 
    "src": "/root/.ansible/tmp/ansible-tmp-1536201763.72-216741204056791/source", 
    "state": "file", 
    "uid": 0
}
// 在192.168.1.52上查看
[root@ansiblemanaged01 ~]# ls -l /tmp/
total 4
drwxr-xr-x 3 root root  51 Sep  6 10:39 ansible
-rw-r--r-- 1 root root 511 Sep  6 10:42 inittab
drwx------ 2 root root   6 Sep  6 09:14 vmware-root


十9、 ansible遠程執行腳本

1.在AnsibkeManager端創建腳本文件

[root@ansiblemanaged01 sh]# vim who.sh
#!/bin/bash

echo $HOSTNAME

2.分發腳本到被管理機器

[root@ansiblemanager ~]# ansible testhosts -m copy -a "src=/root/script/sh/who.sh dest=/tmp mode=755"
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "checksum": "71b7b8522c1f41a69ce8f1e6671b028fdf849752", 
    "dest": "/tmp/who.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "2896d6645133ac0c98022eb61a5737cb", 
    "mode": "0755", 
    "owner": "root", 
    "size": 28, 
    "src": "/root/.ansible/tmp/ansible-tmp-1536202718.33-277007092121833/source", 
    "state": "file", 
    "uid": 0
}
192.168.1.53 | SUCCESS => {
    "changed": true, 
    "checksum": "71b7b8522c1f41a69ce8f1e6671b028fdf849752", 
    "dest": "/tmp/who.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "2896d6645133ac0c98022eb61a5737cb", 
    "mode": "0755", 
    "owner": "root", 
    "size": 28, 
    "src": "/root/.ansible/tmp/ansible-tmp-1536202718.34-129515903004432/source", 
    "state": "file", 
    "uid": 0
}

3.批量執行腳本

[root@ansiblemanager ~]# ansible testhosts -m shell -a '/tmp/who.sh'
192.168.1.52 | SUCCESS | rc=0 >>
ansiblemanaged01

192.168.1.53 | SUCCESS | rc=0 >>
ansiblemanaged02

// shell模塊與command模塊的區別: shell模塊,還支持遠程執行命令而且帶管道
[root@ansiblemanager ~]# ansible testhosts -m command -a 'who | grep root'     
192.168.1.52 | FAILED | rc=1 >>
who: extra operand ‘root’
Try 'who --help' for more information.non-zero return code

192.168.1.53 | FAILED | rc=1 >>
who: extra operand ‘root’
Try 'who --help' for more information.non-zero return code


[root@ansiblemanager ~]# ansible testhosts -m shell -a 'who | grep root'
192.168.1.52 | SUCCESS | rc=0 >>
root     pts/0        2018-09-06 09:31 (192.168.1.9)
root     pts/1        2018-09-06 11:01 (ansiblemanager)

192.168.1.53 | SUCCESS | rc=0 >>
root     pts/0        2018-09-06 09:31 (192.168.1.9)
root     pts/1        2018-09-06 11:01 (ansiblemanager)


二10、 ansible管理任務計劃

1.新建任務計劃

// 其餘的時間表示:分鐘 minute 小時 hour 日期 day 月份 month
[root@ansiblemanager ~]# ansible testhosts -m cron -a "name='test cron' job='/bin/echo $(date +%F)>>/tmp/dd.txt'  weekday=6"
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}
192.168.1.53 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}
// 在被管理端檢查計劃任務是否創建
[root@ansiblemanaged01 ~]# crontab -l
#Ansible: test cron
* * * * 6 /bin/echo 2018-09-06>>/tmp/dd.txt
// 由ansible管理的計劃任務,請不要手動修改,不然會致使ansible沒法再管理相應的計劃任務

2.刪除計劃任務

[root@ansiblemanager ~]# ansible 192.168.1.52 -m cron -a "name='test cron' state=absent"                                      
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
// 驗證
[root@ansiblemanager ~]# ansible testhosts -m command -a "crontab -l"                                   
192.168.1.52 | SUCCESS | rc=0 >>


192.168.1.53 | SUCCESS | rc=0 >>
#Ansible: test cron
* * * * 6 /bin/echo 2018-09-06>>/tmp/dd.txt


二11、 ansible安裝包和管理服務

1.經過yum模塊安裝包

// 在name後面還能夠加上state=installed/removed來管理軟件包
[root@ansiblemanager ~]# ansible testhosts -m yum -a "name=httpd"          
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.cn99.com\n * epel: mirrors.aliyun.com\n * extras: mirrors.cn99.com\n * updates: mirrors.163.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-80.el7.centos.1 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-80.el7.centos.1 for package: httpd-2.4.6-80.el7.centos.1.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-80.el7.centos.1.x86_64\n--> Running transaction check\n---> Package httpd-tools.x86_64 0:2.4.6-80.el7.centos.1 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 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\nInstalling for dependencies:\n httpd-tools       x86_64       2.4.6-80.el7.centos.1       updates        90 k\n mailcap           noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+2 Dependent packages)\n\nTotal download size: 2.8 M\nInstalled size: 9.6 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              3.8 MB/s | 2.8 MB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-tools-2.4.6-80.el7.centos.1.x86_64                     1/3 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Installing : httpd-2.4.6-80.el7.centos.1.x86_64                           3/3 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  1/3 \n  Verifying  : httpd-tools-2.4.6-80.el7.centos.1.x86_64                     2/3 \n  Verifying  : httpd-2.4.6-80.el7.centos.1.x86_64                           3/3 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-80.el7.centos.1                                          \n\nDependency Installed:\n  httpd-tools.x86_64 0:2.4.6-80.el7.centos.1    mailcap.noarch 0:2.1.41-2.el7   \n\nComplete!\n"
    ]
}
192.168.1.53 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.163.com\n * epel: mirrors.aliyun.com\n * extras: mirrors.163.com\n * updates: mirrors.163.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-80.el7.centos.1 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-80.el7.centos.1 for package: httpd-2.4.6-80.el7.centos.1.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-80.el7.centos.1.x86_64\n--> Running transaction check\n---> Package httpd-tools.x86_64 0:2.4.6-80.el7.centos.1 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 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\nInstalling for dependencies:\n httpd-tools       x86_64       2.4.6-80.el7.centos.1       updates        90 k\n mailcap           noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+2 Dependent packages)\n\nTotal download size: 2.8 M\nInstalled size: 9.6 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              3.1 MB/s | 2.8 MB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-tools-2.4.6-80.el7.centos.1.x86_64                     1/3 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Installing : httpd-2.4.6-80.el7.centos.1.x86_64                           3/3 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  1/3 \n  Verifying  : httpd-tools-2.4.6-80.el7.centos.1.x86_64                     2/3 \n  Verifying  : httpd-2.4.6-80.el7.centos.1.x86_64                           3/3 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-80.el7.centos.1                                          \n\nDependency Installed:\n  httpd-tools.x86_64 0:2.4.6-80.el7.centos.1    mailcap.noarch 0:2.1.41-2.el7   \n\nComplete!\n"
    ]
}

2.服務管理

[root@ansiblemanager ~]# ansible testhosts -m service -a "name=httpd state=started enabled=yes" 
192.168.1.52 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "inactive", 
        "After": "systemd-journald.socket -.mount tmp.mount nss-lookup.target system.slice basic.target network.target remote-fs.target", 
        "AllowIsolate": "no", 
        "AmbientCapabilities": "0", 
        "AssertResult": "no", 
        "AssertTimestampMonotonic": "0", 
        "Before": "shutdown.target", 
        "BlockIOAccounting": "no", 
        "BlockIOWeight": "18446744073709551615", 
        "CPUAccounting": "no", 
        "CPUQuotaPerSecUSec": "infinity", 
        "CPUSchedulingPolicy": "0", 
        "CPUSchedulingPriority": "0", 
        "CPUSchedulingResetOnFork": "no", 
        "CPUShares": "18446744073709551615", 
        "CanIsolate": "no", 
        "CanReload": "yes", 
        "CanStart": "yes", 
        "CanStop": "yes", 
        "CapabilityBoundingSet": "18446744073709551615", 
        "ConditionResult": "no", 
        "ConditionTimestampMonotonic": "0", 
        "Conflicts": "shutdown.target", 
        "ControlPID": "0", 
        "DefaultDependencies": "yes", 
        "Delegate": "no", 
        "Description": "The Apache HTTP Server", 
        "DevicePolicy": "auto", 
        "Documentation": "man:httpd(8) man:apachectl(8)", 
        "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", 
        "ExecMainCode": "0", 
        "ExecMainExitTimestampMonotonic": "0", 
        "ExecMainPID": "0", 
        "ExecMainStartTimestampMonotonic": "0", 
        "ExecMainStatus": "0", 
        "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "FailureAction": "none", 
        "FileDescriptorStoreMax": "0", 
        "FragmentPath": "/usr/lib/systemd/system/httpd.service", 
        "GuessMainPID": "yes", 
        "IOScheduling": "0", 
        "Id": "httpd.service", 
        "IgnoreOnIsolate": "no", 
        "IgnoreOnSnapshot": "no", 
        "IgnoreSIGPIPE": "yes", 
        "InactiveEnterTimestampMonotonic": "0", 
        "InactiveExitTimestampMonotonic": "0", 
        "JobTimeoutAction": "none", 
        "JobTimeoutUSec": "0", 
        "KillMode": "control-group", 
        "KillSignal": "18", 
        "LimitAS": "18446744073709551615", 
        "LimitCORE": "18446744073709551615", 
        "LimitCPU": "18446744073709551615", 
        "LimitDATA": "18446744073709551615", 
        "LimitFSIZE": "18446744073709551615", 
        "LimitLOCKS": "18446744073709551615", 
        "LimitMEMLOCK": "65536", 
        "LimitMSGQUEUE": "819200", 
        "LimitNICE": "0", 
        "LimitNOFILE": "4096", 
        "LimitNPROC": "1796", 
        "LimitRSS": "18446744073709551615", 
        "LimitRTPRIO": "0", 
        "LimitRTTIME": "18446744073709551615", 
        "LimitSIGPENDING": "1796", 
        "LimitSTACK": "18446744073709551615", 
        "LoadState": "loaded", 
        "MainPID": "0", 
        "MemoryAccounting": "no", 
        "MemoryCurrent": "18446744073709551615", 
        "MemoryLimit": "18446744073709551615", 
        "MountFlags": "0", 
        "Names": "httpd.service", 
        "NeedDaemonReload": "no", 
        "Nice": "0", 
        "NoNewPrivileges": "no", 
        "NonBlocking": "no", 
        "NotifyAccess": "main", 
        "OOMScoreAdjust": "0", 
        "OnFailureJobMode": "replace", 
        "PermissionsStartOnly": "no", 
        "PrivateDevices": "no", 
        "PrivateNetwork": "no", 
        "PrivateTmp": "yes", 
        "ProtectHome": "no", 
        "ProtectSystem": "no", 
        "RefuseManualStart": "no", 
        "RefuseManualStop": "no", 
        "RemainAfterExit": "no", 
        "Requires": "basic.target -.mount", 
        "RequiresMountsFor": "/var/tmp", 
        "Restart": "no", 
        "RestartUSec": "100ms", 
        "Result": "success", 
        "RootDirectoryStartOnly": "no", 
        "RuntimeDirectoryMode": "0755", 
        "SameProcessGroup": "no", 
        "SecureBits": "0", 
        "SendSIGHUP": "no", 
        "SendSIGKILL": "yes", 
        "Slice": "system.slice", 
        "StandardError": "inherit", 
        "StandardInput": "null", 
        "StandardOutput": "journal", 
        "StartLimitAction": "none", 
        "StartLimitBurst": "5", 
        "StartLimitInterval": "10000000", 
        "StartupBlockIOWeight": "18446744073709551615", 
        "StartupCPUShares": "18446744073709551615", 
        "StatusErrno": "0", 
        "StopWhenUnneeded": "no", 
        "SubState": "dead", 
        "SyslogLevelPrefix": "yes", 
        "SyslogPriority": "30", 
        "SystemCallErrorNumber": "0", 
        "TTYReset": "no", 
        "TTYVHangup": "no", 
        "TTYVTDisallocate": "no", 
        "TasksAccounting": "no", 
        "TasksCurrent": "18446744073709551615", 
        "TasksMax": "18446744073709551615", 
        "TimeoutStartUSec": "1min 30s", 
        "TimeoutStopUSec": "1min 30s", 
        "TimerSlackNSec": "50000", 
        "Transient": "no", 
        "Type": "notify", 
        "UMask": "0022", 
        "UnitFilePreset": "disabled", 
        "UnitFileState": "disabled", 
        "Wants": "system.slice", 
        "WatchdogTimestampMonotonic": "0", 
        "WatchdogUSec": "0"
    }
}
192.168.1.53 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "inactive", 
        "After": "remote-fs.target nss-lookup.target tmp.mount network.target systemd-journald.socket system.slice -.mount basic.target", 
        "AllowIsolate": "no", 
        "AmbientCapabilities": "0", 
        "AssertResult": "no", 
        "AssertTimestampMonotonic": "0", 
        "Before": "shutdown.target", 
        "BlockIOAccounting": "no", 
        "BlockIOWeight": "18446744073709551615", 
        "CPUAccounting": "no", 
        "CPUQuotaPerSecUSec": "infinity", 
        "CPUSchedulingPolicy": "0", 
        "CPUSchedulingPriority": "0", 
        "CPUSchedulingResetOnFork": "no", 
        "CPUShares": "18446744073709551615", 
        "CanIsolate": "no", 
        "CanReload": "yes", 
        "CanStart": "yes", 
        "CanStop": "yes", 
        "CapabilityBoundingSet": "18446744073709551615", 
        "ConditionResult": "no", 
        "ConditionTimestampMonotonic": "0", 
        "Conflicts": "shutdown.target", 
        "ControlPID": "0", 
        "DefaultDependencies": "yes", 
        "Delegate": "no", 
        "Description": "The Apache HTTP Server", 
        "DevicePolicy": "auto", 
        "Documentation": "man:httpd(8) man:apachectl(8)", 
        "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", 
        "ExecMainCode": "0", 
        "ExecMainExitTimestampMonotonic": "0", 
        "ExecMainPID": "0", 
        "ExecMainStartTimestampMonotonic": "0", 
        "ExecMainStatus": "0", 
        "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "FailureAction": "none", 
        "FileDescriptorStoreMax": "0", 
        "FragmentPath": "/usr/lib/systemd/system/httpd.service", 
        "GuessMainPID": "yes", 
        "IOScheduling": "0", 
        "Id": "httpd.service", 
        "IgnoreOnIsolate": "no", 
        "IgnoreOnSnapshot": "no", 
        "IgnoreSIGPIPE": "yes", 
        "InactiveEnterTimestampMonotonic": "0", 
        "InactiveExitTimestampMonotonic": "0", 
        "JobTimeoutAction": "none", 
        "JobTimeoutUSec": "0", 
        "KillMode": "control-group", 
        "KillSignal": "18", 
        "LimitAS": "18446744073709551615", 
        "LimitCORE": "18446744073709551615", 
        "LimitCPU": "18446744073709551615", 
        "LimitDATA": "18446744073709551615", 
        "LimitFSIZE": "18446744073709551615", 
        "LimitLOCKS": "18446744073709551615", 
        "LimitMEMLOCK": "65536", 
        "LimitMSGQUEUE": "819200", 
        "LimitNICE": "0", 
        "LimitNOFILE": "4096", 
        "LimitNPROC": "1796", 
        "LimitRSS": "18446744073709551615", 
        "LimitRTPRIO": "0", 
        "LimitRTTIME": "18446744073709551615", 
        "LimitSIGPENDING": "1796", 
        "LimitSTACK": "18446744073709551615", 
        "LoadState": "loaded", 
        "MainPID": "0", 
        "MemoryAccounting": "no", 
        "MemoryCurrent": "18446744073709551615", 
        "MemoryLimit": "18446744073709551615", 
        "MountFlags": "0", 
        "Names": "httpd.service", 
        "NeedDaemonReload": "no", 
        "Nice": "0", 
        "NoNewPrivileges": "no", 
        "NonBlocking": "no", 
        "NotifyAccess": "main", 
        "OOMScoreAdjust": "0", 
        "OnFailureJobMode": "replace", 
        "PermissionsStartOnly": "no", 
        "PrivateDevices": "no", 
        "PrivateNetwork": "no", 
        "PrivateTmp": "yes", 
        "ProtectHome": "no", 
        "ProtectSystem": "no", 
        "RefuseManualStart": "no", 
        "RefuseManualStop": "no", 
        "RemainAfterExit": "no", 
        "Requires": "basic.target -.mount", 
        "RequiresMountsFor": "/var/tmp", 
        "Restart": "no", 
        "RestartUSec": "100ms", 
        "Result": "success", 
        "RootDirectoryStartOnly": "no", 
        "RuntimeDirectoryMode": "0755", 
        "SameProcessGroup": "no", 
        "SecureBits": "0", 
        "SendSIGHUP": "no", 
        "SendSIGKILL": "yes", 
        "Slice": "system.slice", 
        "StandardError": "inherit", 
        "StandardInput": "null", 
        "StandardOutput": "journal", 
        "StartLimitAction": "none", 
        "StartLimitBurst": "5", 
        "StartLimitInterval": "10000000", 
        "StartupBlockIOWeight": "18446744073709551615", 
        "StartupCPUShares": "18446744073709551615", 
        "StatusErrno": "0", 
        "StopWhenUnneeded": "no", 
        "SubState": "dead", 
        "SyslogLevelPrefix": "yes", 
        "SyslogPriority": "30", 
        "SystemCallErrorNumber": "0", 
        "TTYReset": "no", 
        "TTYVHangup": "no", 
        "TTYVTDisallocate": "no", 
        "TasksAccounting": "no", 
        "TasksCurrent": "18446744073709551615", 
        "TasksMax": "18446744073709551615", 
        "TimeoutStartUSec": "1min 30s", 
        "TimeoutStopUSec": "1min 30s", 
        "TimerSlackNSec": "50000", 
        "Transient": "no", 
        "Type": "notify", 
        "UMask": "0022", 
        "UnitFilePreset": "disabled", 
        "UnitFileState": "disabled", 
        "Wants": "system.slice", 
        "WatchdogTimestampMonotonic": "0", 
        "WatchdogUSec": "0"
    }
}

// 被管理端檢查
[root@ansiblemanager ~]# ansible testhosts -m shell -a "netstat -nltp | grep :80"
192.168.1.52 | SUCCESS | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      2542/httpd          

192.168.1.53 | SUCCESS | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      2015/httpd

3.Ansible文檔的使用

// 列出全部的模塊

[root@ansiblemanager ~]# ansible-doc -l 
a10_server                                           Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' server objec...
a10_server_axapi3                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices              
a10_service_group                                    Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' service grou...
a10_virtual_server                                   Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' virtual serv...
accelerate                                           Enable accelerated mode on remote node                              
aci_aaa_user                                         Manage AAA users (aaa:User)                                         
aci_aaa_user_certificate                             Manage AAA user certificates (aaa:UserCert)                         
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interface policy leaf profile interface selectors (inf...
aci_aep                                              Manage attachable Access Entity Profile (AEP) objects (infra:AttEnti...
aci_aep_to_domain                                    Bind AEPs to Physical or Virtual Domains (infra:RsDomP)             
aci_ap                                               Manage top level Application Profile (AP) objects (fv:Ap
...下略...

// 查看指定模塊的文檔
[root@ansiblemanager ~]# ansible-doc a10_server 
> A10_SERVER    (/usr/lib/python2.7/site-packages/ansible/modules/network/a10/a10_server.py)

        Manage SLB (Server Load Balancer) server objects on A10 Networks devices via aXAPIv2.

OPTIONS (= is mandatory):

- client_cert
        PEM formatted certificate chain file to be used for SSL client authentication. This file can
        also include the key as well, and if the key is included, `client_key' is not required.
        [Default: (null)]

- client_key
        PEM formatted file that contains your private key to be used for SSL client authentication.
        If `client_cert' contains both the certificate and key, this option is not required.
        [Default: (null)]

- force
        If `yes' do not get a cached copy.
        (Aliases: thirsty)[Default: False]
        type: bool
...下略...


二12、 使用ansible playbook

Playbooks 是 Ansible的配置,部署,編排語言.他們能夠被描述爲一個須要但願遠程主機執行命令的方案,或者一組IT程序運行的命令集合.

若是 Ansible 模塊你是工做室中的工具,那麼 playbooks 就是你設置的方案計劃.

Playbooks 的格式是YAML。

第一個playbook

// 編寫playbook文件
// 第一行須要有三個槓,hosts參數指定了對哪些主機進行參做,
// 若是是多臺機器能夠用逗號做爲分隔,也可使用主機組,在/etc/ansible/hosts裏定義
// user參數指定了使用什麼用戶登陸遠程主機操做
// tasks指定了一個任務,其下面的name參數一樣是對任務的描述,在執行過程當中會打印出來,shell是ansible模塊名字

[root@ansiblemanager ~]#  vim  /etc/ansible/test.yml
---
- hosts: ansiblemanaged01
  remote_user: root
  tasks:
    - name: test_playbook
      shell: echo $HOSTNAME >>/tmp/playbook_Test.txt

// 執行
[root@ansiblemanager ansible]# ansible-playbook test.yml

PLAY [testhosts] *************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************
ok: [192.168.1.53]
ok: [192.168.1.52]

TASK [test playbook] *********************************************************************************************************
changed: [192.168.1.53]
changed: [192.168.1.52]

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

[root@ansiblemanager ansible]# ansible all -m shell -a "cat /tmp/playboogtest.txt" 
192.168.1.53 | SUCCESS | rc=0 >>
ansiblemanaged02

192.168.1.52 | SUCCESS | rc=0 >>
ansiblemanaged01


二十3、 playbook裏的變量

演示

// 建立playbook文件
[root@ansiblemanager ansible]# vim create_user.yml
---
- name: create user
  hosts: testhosts
  user: root
  gather_facts: false
  vars:
   - user: "nico"
  tasks:
   - name: create user
     user: name="{{ user }}"
// 執行
[root@ansiblemanager ansible]# ansible-playbook create_user.yml 

PLAY [create user] ***********************************************************************************************************

TASK [create user] ***********************************************************************************************************
changed: [192.168.1.53]
changed: [192.168.1.52]

PLAY RECAP *******************************************************************************************************************
192.168.1.52               : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.53               : ok=1    changed=1    unreachable=0    failed=0   
// 驗證
[root@ansiblemanager ansible]# ansible all -m shell -a "grep nico /etc/passwd" 
192.168.1.52 | SUCCESS | rc=0 >>
nico:x:5001:5001::/home/nico:/bin/bash

192.168.1.53 | SUCCESS | rc=0 >>
nico:x:5001:5001::/home/nico:/bin/bash

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


二十4、 playbook裏的循環

演示

// 建立playbook文件
// with_items爲循環的對象
[root@ansiblemanager ansible]# vim loop.yml              
---
- hosts: 192.168.1.52
  user: root
  tasks:
   - name: change mode for files
     file: path=/tmp/{{ item }} state=touch mode=600
     with_items:
      - 1.txt
      - 2.txt
      - 3.txt
// 執行
[root@ansiblemanager ansible]# ansible-playbook loop.yml 

PLAY [192.168.1.52] **********************************************************************************************************

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

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

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


二十5、 playbook裏的條件判斷

演示:

// 新建playbook文件
[root@ansiblemanager ansible]# vim when.yml              
---
- hosts: testhosts
  user: root
  gather_facts: True
  tasks:
   - name: use when
     shell: echo $HOSTNAME >>/tmp/tt.txt
     when: ansible_ens32.ipv4.address=="192.168.1.52"
// 執行
[root@ansiblemanager ansible]# ansible-playbook when.yml 

PLAY [testhosts] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.52]
ok: [192.168.1.53]

TASK [use when] ****************************************************************
skipping: [192.168.1.53]
changed: [192.168.1.52]

PLAY RECAP *********************************************************************
192.168.1.52               : ok=2    changed=1    unreachable=0    failed=0   
192.168.1.53               : ok=1    changed=0    unreachable=0    failed=0   
// 驗證
[root@ansiblemanager ansible]# ansible all -m command -a 'cat /tmp/tt.txt'    
192.168.1.53 | FAILED | rc=1 >>
cat: /tmp/tt.txt: No such file or directorynon-zero return code

192.168.1.52 | SUCCESS | rc=0 >>
ansiblemanaged01

// 當註釋when這一句,則會對192.168.1.53

[root@ansiblemanager ansible]# vim when.yml                               
---
- hosts: testhosts
  user: root
  gather_facts: True
  tasks:
   - name: use when
     shell: echo $HOSTNAME >>/tmp/tt.txt
     #when: ansible_ens32.ipv4.address=="192.168.1.52"
// 執行
[root@ansiblemanager ansible]# ansible-playbook when.yml 

PLAY [testhosts] *************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************
ok: [192.168.1.52]
ok: [192.168.1.53]

TASK [use when] **************************************************************************************************************
changed: [192.168.1.53]
changed: [192.168.1.52]

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

[root@ansiblemanager ansible]# ansible all -m command -a 'cat /tmp/tt.txt'
192.168.1.52 | SUCCESS | rc=0 >>
ansiblemanaged01
ansiblemanaged01

192.168.1.53 | SUCCESS | rc=0 >>
ansiblemanaged02

//全部的facter信息能夠經過 "ansible aming-02 -m setup" 查看


二十6、 playbook中的handlers

Ansible playbook中的handlers可實現相似邏輯與的功能。

演示

// 新建playbook文件
// 只有copy模塊真正執行後,纔會去調用下面的handlers相關的操做。
// 也就是說若是1.txt和2.txt內容是同樣的,並不會去執行handlers裏面的shell相關命令。 // 這種比較適合配置文件發生更改後,重啓服務的操做。
[root@ansiblemanager ansible]# vim handlers.yml                       
---
- name: handlers test
  hosts: testhosts
  user: root
  tasks:
    - name: copy file
      copy: src=/etc/inittab dest=/tmp/1.txt
      notify: test handlers
  handlers:
    - name: test handlers
      shell: echo "new line" >> /tmp/1.txt
// 執行
[root@ansiblemanager ansible]# ansible-playbook handlers.yml

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

TASK [Gathering Facts] *******************************************************************************************************
ok: [192.168.1.52]
ok: [192.168.1.53]

TASK [copy file] *************************************************************************************************************
changed: [192.168.1.52]
changed: [192.168.1.53]

RUNNING HANDLER [test handlers] **********************************************************************************************
changed: [192.168.1.52]
changed: [192.168.1.53]

PLAY RECAP *******************************************************************************************************************
192.168.1.52               : ok=3    changed=2    unreachable=0    failed=0   
192.168.1.53               : ok=3    changed=2    unreachable=0    failed=0   
// 檢查
[root@ansiblemanager ansible]# ansible all -m command -a "tail -n 2 /tmp/1.txt"
192.168.1.52 | SUCCESS | rc=0 >>
#
new line

192.168.1.53 | SUCCESS | rc=0 >>
#
new line


二十7、 playbook安裝nginx

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

1.分發主機進入ansible配置文件目錄

[root@ansiblemanager ~]# cd /etc/ansible/

2.爲方便管理,建立一個nginx_install的目錄

[root@ansiblemanager ansible]# mkdir  nginx_install
[root@ansiblemanager ansible]# ls -ld !$
ls -ld nginx_install
drwxr-xr-x 2 root root 6 Sep 10 15:03 nginx_install
[root@ansiblemanager ansible]# cd !$
cd nginx_install

3.建立playbook目錄結構

[root@ansiblemanager nginx_install]# mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
[root@ansiblemanager nginx_install]# tree
.
└── roles
    ├── common
    │   ├── files
    │   ├── handlers
    │   ├── meta
    │   ├── tasks
    │   ├── templates
    │   └── vars
    └── install
        ├── files
        ├── handlers
        ├── meta
        ├── tasks
        ├── templates
        └── vars
// roles目錄下有兩個角色,common爲一些準備操做,install爲安裝nginx的操做。
// 每一個角色下面又有幾個目錄,handlers下面是當發生改變時要執行的操做,
// 一般用在配置文件發生改變,重啓服務。files爲安裝時用到的一些文件,
// meta爲說明信息,說明角色依賴等信息,tasks裏面是核心的配置文件,
// templates一般存一些配置文件,啓動腳本等模板文件,vars下爲定義的變量

4.在模板機安裝nginx並打包

[root@lanquark sh]# cd /usr/local/
[root@lanquark local]# tar zcvf nginx.tar.gz nginx/ --exclude nginx.conf 
// 打包好之後同步到分發主機

5.將打包的nginx文件,配置文件,啓動腳本拷貝到相應的目錄

[root@ansiblemanager nginx_install]# mv /usr/local/src/nginx.tar.gz roles/install/files/
[root@ansiblemanager nginx_install]# mv /usr/local/src/nginx.conf roles/install/templates/
[root@ansiblemanager nginx_install]# mv /usr/local/src/nginx roles/install/templates/

6.定義普通的tasks

[root@ansiblemanager nginx_install]# vim roles/common/tasks/main.yml
- name: Install initializtion require software
  yum: name={{ item }} state=installed
  with_items:
    - zlib-devel
    - pcre-devel

7.定義變量

[root@ansiblemanager nginx_install]# vim roles/install/vars/main.yml
nginx_user: nginx
nginx_port: 80
nginx_basedir: /usr/local/nginx

8.定義文件拷貝配置

[root@ansiblemanager nginx_install]# vim roles/install/tasks/copy.yml
- name: Copy Nginx Software
  copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root
- name: Uncompression Nginx Software
  shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/
- name: Copy Nginx Start Script
  template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755
- name: Copy Nginx Config
  template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root mode=0644

9.創建用戶、啓動服務。刪除安裝包

[root@ansiblemanager nginx_install]# vim roles/install/tasks/install.yml

- name: Create Nginx User
  user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin
- name: Start Nginx Service
  shell: /etc/init.d/nginx start
- name: Add Boot Start Nginx Service
  shell: chkconfig --level 345 nginx on
- name: Delete Nginx compression files
  shell: rm -rf /tmp/nginx.tar.gz

10.建立main.yml,調用copy和install

[root@ansiblemanager nginx_install]# vim roles/install/tasks/main.yml
- include: copy.yml
- include: install.yml

11.建立入口文件

[root@ansiblemanager nginx_install]# vim install.yml 
---
- hosts: 192.168.1.52
  remote_user: root
  gather_facts: True
  roles:
    - common
    - install

12.執行

[root@ansiblemanager nginx_install]# ansible-playbook install.yml 

PLAY [192.168.1.52] **********************************************************************************************************

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

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

TASK [install : Copy Nginx Software] *****************************************************************************************
ok: [192.168.1.52]

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: [192.168.1.52]

TASK [install : Copy Nginx Start Script] *************************************************************************************
ok: [192.168.1.52]

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

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

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

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

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: [192.168.1.52]

PLAY RECAP *******************************************************************************************************************
192.168.1.52               : ok=10   changed=6    unreachable=0    failed=0

13.客戶端檢查

[root@ansiblemanaged01 ~]# lsof -i :80
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   14441  root    6u  IPv4 510103      0t0  TCP *:http (LISTEN)
nginx   14442 nginx    6u  IPv4 510103      0t0  TCP *:http (LISTEN)


二十8、 playbook管理配置文件

生產環境中安裝軟件包只是在初始化環境的時候用一下,大多時候是須要管理配置文件的,下面咱們來寫個管理nginx配置文件的playbook

1.建立playbook配置目錄結構

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

11 directories, 0 files
// 其中new爲更新時用到的,old爲回滾時用到的,files下面爲nginx.conf和vhosts
// 目錄,handlers爲重啓nginx服務的task
// 關於回滾,須要在執行playbook以前先備份一下舊的配置,因此對於老配置文件的管
// 理必定要嚴格,千萬不能隨便去修改線上機器的配置,而且要保證new/files下面的
// 配置和線上的配置一致

2.把當前線上的文件放到new/files下

11 directories, 0 files
[root@ansiblemanager ansible]# cp /usr/local/src/nginx.conf nginx_config/roles/new/files/
[root@ansiblemanager ansible]# ls -l !$
ls -l nginx_config/roles/new/files/
total 4
-rw-r--r-- 1 root root 2903 Sep 10 16:53 nginx.conf

3.定義變量

[root@ansiblemanager ansible]#  vim /etc/ansible/nginx_config/roles/new/vars/main.yml
nx_basedir: /usr/local/nginx

4.定義從新加載nginx服務

[root@ansiblemanager ansible]# vim /etc/ansible/nginx_config/roles/new/handlers/main.yml  
- name: restart nginx
  shell: /etc/init.d/nginx reload

5.定義主配置文件

[root@ansiblemanager ansible]#  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
  1. 定義入口文件
---
- hosts: 192.168.1.52
  user: root
  roles:
  - new

7.執行更新

// 修改了默認的配置文件,新建了vhosts文件夾,並在vhosts文件夾裏添加了幾個配置文件
-rw-r--r-- 1 root root 56 Sep 10 20:22 update.yml
[root@ansiblemanager nginx_config]# ansible-playbook update.yml 

PLAY [192.168.1.52] *****************************************************************************************************************************************************

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

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

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

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

// 在192.168.1.52上檢查,已經更新,再也不是默認的那個配置文件了
[root@ansiblemanager nginx_config]# ansible 192.168.1.52 -m command -a "tail -n 5 /usr/local/nginx/conf/nginx.conf"  
192.168.1.52 | SUCCESS | rc=0 >>
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }    
    }
}

8.回滾操做

// 更新前必定要備份new下files中的內容,再行更新
// 同步new的內容到old,也至關於備份了一次
[root@ansiblemanager nginx_config]# rsync -av roles/new/ roles/old/
sending incremental file list
files/
files/nginx.conf
files/vhosts/
files/vhosts/bbs.yuankeedu.conf
files/vhosts/www.yuankeedu.conf
handlers/
handlers/main.yml
tasks/
tasks/main.yml
vars/
vars/main.yml

sent 3,910 bytes  received 150 bytes  8,120.00 bytes/sec
total size is 3,270  speedup is 0.81
[root@ansiblemanager nginx_config]# tree
.
├── roles
│   ├── new
│   │   ├── files
│   │   │   ├── nginx.conf
│   │   │   └── vhosts
│   │   │       ├── bbs.yuankeedu.conf
│   │   │       └── www.yuankeedu.conf
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── vars
│   │       └── main.yml
│   └── old
│       ├── files
│       │   ├── nginx.conf
│       │   └── vhosts
│       │       ├── bbs.yuankeedu.conf
│       │       └── www.yuankeedu.conf
│       ├── handlers
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
├── update.retry
└── update.yml

13 directories, 14 files
// 對配置文件進行變動,註釋掉對vhosts引用
#    include vhost/*.conf;
//更新
[root@ansiblemanager nginx_config]# ansible-playbook update.yml 

PLAY [192.168.1.52] *****************************************************************************************************************************************************

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

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

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

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

[root@ansiblemanager nginx_config]# 
// 檢查是否更新

[root@ansiblemanager nginx_config]# ansible 192.168.1.52 -m command -a "grep ^# /usr/local/nginx/conf/nginx.conf"
192.168.1.52 | SUCCESS | rc=0 >>
#    include vhost/*.conf;

// 回滾
// 創建回滾入口文件
[root@ansiblemanager nginx_config]# vim rollback.yml 
---
- hosts: 192.168.1.52
  user: root
  roles:
  - old

//執行回滾
"rollback.yml" 5L, 56C written                                                                                                                         
[root@ansiblemanager nginx_config]# ansible-playbook rollback.yml 

PLAY [192.168.1.52] *****************************************************************************************************************************************************

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

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

RUNNING HANDLER [old : restart nginx] ***********************************************************************************************************************************
changed: [192.168.1.52]

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

// 檢查, 回滾成功

[root@ansiblemanager nginx_config]# ansible 192.168.1.52 -m command -a "grep vhost /usr/local/nginx/conf/nginx.conf"
192.168.1.52 | SUCCESS | rc=0 >>
    include vhost/*.conf;
相關文章
相關標籤/搜索