自动化运维-ansible

【简介】

ansible更加简洁的自动化运维工具,不需要再客户端安装agent,基于python开发,可以实现批量操作系统配置、批量程序的部署、批量运行命令

不需要安装客户端、通过`ssh`通信
基于`模块`工作,模块可以由任何语言开发
不仅支持命令行使用模块,也支持编写`yaml格式的playbook`,易于编写和阅读
安装简便,centos直接yum安装

实验:(镜像1511)

节点ip/主机名
管理节点192.168.200.66/ ansible-1
远程主机192.168.200.67 /ansible-2

一、ansible安装

管理节点和远程主机更改主机名,并关闭防火墙

hostnamectl set-hostname ansible-1
hostnamectl set-hostname ansible-2
systemctl stop firewalld
systemctl disable firewalld
setenforce 0

配置映射

[root@ansible-1 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.200.66 ansible-1
192.168.200.67 ansible-2
 
 
[root@ansible-2 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.200.66 ansible-1
192.168.200.67 ansible-2


管理节点安装ansible

 yum install epel-release -y
 yum install ansible -y

配置管理节点和远程主机之间的无密钥ssh

ssh-keygen -t rsa
ssh-copy-id 远程主机

管理节点修改配置文件,添加主机组。

配置文件:/etc/ansible/hosts

添加以下内容:
[testhost]      //主机组名称,`组内的机器都需要配置无密钥ssh`127.0.0.1   
192.168.200.67

二、ansible使用命令管理主机

格式:ansible 远程主机ip或主机组名 -m 模块 -a 命令

ansible模块

ansible-doc -l   	//列出所有模块
ansible-doc copy  	//查看指定模块

(一)远程执行命令

[root@ansible-1 ~]# ansible 192.168.200.67 -m command -a "hostname"
192.168.200.67 | CHANGED | rc=0 >>
ansible-2

注意:如果产生以下错误
错误:"msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"

解决:
在192.168.200.67远程主机安装:yum install -y libselinux-python


[root@ansible-1 ~]# ansible testhost -m command -a "hostname"
192.168.200.67 | CHANGED | rc=0 >>
ansible-2
127.0.0.1 | CHANGED | rc=0 >>
ansible-1

(二)ansible拷贝文件或目录

src 源地址 dest 目的地址 owner 所属用户 group 所属组 mode 文件权限

注意:拷贝的是文件,dest指定的名字和src不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名

[root@ansible-1 ~]# ansible 192.168.200.67 -m copy -a "src=1.txt dest=/tmp/2.txt"
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/2.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1621908783.93-15288-261699444933053/source", 
    "state": "file", 
    "uid": 0
}

`验证:`

[root@ansible-2 tmp]# ll
total 4
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l
[root@ansible-2 tmp]# ll /tmp/
total 4
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l

注意:拷贝的是文件,dest指定的名字和src相同,并且dest指定的名字是已经存在的目录,则会把文件放在目录下。 即拷贝的文件名和远程主机的目录名一样

[root@ansible-1 ~]# ansible 192.168.200.67 -m copy -a "src=1.txt dest=/tmp/1.txt"
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/1.txt/1.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1621909660.28-15359-108366850986878/source", 
    "state": "file", 
    "uid": 0
}

`验证:`

[root@ansible-2 ~]# ll /tmp/1.txt/
total 0
[root@ansible-2 ~]# ll /tmp/1.txt/
total 0
-rw-r--r--. 1 root root 0 May 25 10:27 1.txt

注意:拷贝的是目录,源目录会放到目标目录下,如果目标目录不存在,自动创建

[root@ansible-1 ~]# ansible 192.168.200.67 -m copy -a "src=test1 dest=/tmp/test2"  
192.168.200.67 | CHANGED => {                            
    "ansible_facts": {              
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "a8fdc205a9f19cc1c7507a60c4f01b13d11d7fd0", 
    "dest": "/tmp/test2/test1/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "ba1f2511fc30423bdbb183fe33f3dd0f", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 4, 
    "src": "/root/.ansible/tmp/ansible-tmp-1621910706.73-15434-106429848565317/source", 
    "state": "file", 
    "uid": 0
}

`目标目录不存在时`
`验证:`

[root@ansible-2 ~]# ll /tmp/
total 4
drwxr-xr-x. 2 root root  18 May 25 10:27 1.txt
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l
[root@ansible-2 ~]# ll /tmp/
total 4
drwxr-xr-x. 2 root root  18 May 25 10:27 1.txt
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l
drwxr-xr-x. 2 root root  21 May 25 10:42 test2
[root@ansible-2 ~]# ll /tmp/test2/
total 4
drwxr-xr-x. 2 root root 21 May 25 10:45 test1
[root@ansible-1 ~]# ansible 192.168.200.67 -m copy -a "src=test1 dest=/tmp/test3"
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "a8fdc205a9f19cc1c7507a60c4f01b13d11d7fd0", 
    "dest": "/tmp/test3/test1/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "ba1f2511fc30423bdbb183fe33f3dd0f", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 4, 
    "src": "/root/.ansible/tmp/ansible-tmp-1621910897.33-15466-29316052262559/source", 
    "state": "file", 
    "uid": 0
}

`目标目录存在时`
`验证`

[root@ansible-2 ~]# ll /tmp/
total 4
drwxr-xr-x. 2 root root  18 May 25 10:27 1.txt
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l
drwxr-xr-x. 2 root root   6 May 25 10:47 test3
[root@ansible-2 ~]# ll /tmp/test3/
total 0
drwxr-xr-x. 2 root root 21 May 25 10:48 test1

(三)ansible远程执行脚本

创建脚本

[root@ansible-1 ~]# vi /tmp/test.sh 
#!/bin/bash
echo `date` > /tmp/ansible_test.txt

将脚本复制到主机组内的主机

[root@ansible-1 ~]# ansible testhost -m copy -a "src=/tmp/test.sh dest=/tmp/test.sh mode=0755"
127.0.0.1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "checksum": "1f832df5cc0793fddaf62b32b798a7d2a1abb0c2", 
    "dest": "/tmp/test.sh", 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/tmp/test.sh", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": 49, 
    "state": "file", 
    "uid": 0
}
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "1f832df5cc0793fddaf62b32b798a7d2a1abb0c2", 
    "dest": "/tmp/test.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "757ff95d06528b0a09ff73767aabb653", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 49, 
    "src": "/root/.ansible/tmp/ansible-tmp-1621911561.03-15504-123722683192477/source", 
    "state": "file", 
    "uid": 0
}

批量执行脚本

[root@ansible-1 ~]# ansible testhost -m shell -a "/tmp/test.sh"
127.0.0.1 | CHANGED | rc=0 >>

192.168.200.67 | CHANGED | rc=0 >>


`验证`
[root@ansible-1 ~]# cat /tmp/ansible_test.txt 
Tue May 25 12:32:52 CST 2021
[root@ansible-2 ~]# cat /tmp/ansible_test.txt 
Wed May 26 03:32:49 CST 2021

(四)ansible管理任务计划

创建任务

name 任务的名字 job 任务 分钟 minute 小时 hour 日期 day 月份 month 星期 weekday

[root@ansible-1 ~]# ansible testhost -m cron -a "name='test cron' job='/bin/touch /tmp/121.txt' weekday=6" 
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}
127.0.0.1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron"
    ]
}




`验证`

[root@ansible-1 ~]# crontab -l
#Ansible: test cron
* * * * 6 /bin/touch /tmp/121.txt
[root@ansible-2 ~]# crontab -l
#Ansible: test cron
* * * * 6 /bin/touch /tmp/121.txt

删除任务

name 任务的名字 state=absent

[root@ansible-1 ~]# ansible testhost -m cron -a "name='test cron' state=absent" 
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}
127.0.0.1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}



`验证`

[root@ansible-1 ~]# crontab -l     
[root@ansible-1 ~]#                    ##无内容,已删除
[root@ansible-2 ~]# crontab -l      
[root@ansible-1 ~]#             	  ##无内容,已删除
 

(五)ansible安装rpm包/管理服务

安装rpm包

name rpm包名(需要精准包名)可以添加 state=installed/removed

[root@ansible-1 ~]# ansible 192.168.200.67 -m yum -a "name=httpd "
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "installed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos 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-97.el7.centos         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-97.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-97.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-97.el7.centos                                            \n\nComplete!\n"
    ]
}



`验证`
[root@ansible-2 ~]# rpm -qa |grep httpd
httpd-tools-2.4.6-97.el7.centos.x86_64
httpd-2.4.6-97.el7.centos.x86_64

管理服务

name 		服务名称 
state 		对当前服务执行启动,停止、重启、重新加载等操作  
enabled 	是否开机启动 yes|no
[root@ansible-1 ~]# ansible 192.168.200.67 -m service -a "name=httpd state=started enabled=yes"
192.168.200.67 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "inactive", 
        "After": "-.mount systemd-journald.socket network.target remote-fs.target basic.target nss-lookup.target system.slice", 
        "AllowIsolate": "no", 
        "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": "7217", 
        "LimitRSS": "18446744073709551615", 
        "LimitRTPRIO": "0", 
        "LimitRTTIME": "18446744073709551615", 
        "LimitSIGPENDING": "7217", 
        "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": "/tmp /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", 
        "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@ansible-2 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-05-26 11:09:56 CST; 1min 28s ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 17252 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─17252 /usr/sbin/httpd -DFOREGROUND
           ├─17253 /usr/sbin/httpd -DFOREGROUND
           ├─17254 /usr/sbin/httpd -DFOREGROUND
           ├─17255 /usr/sbin/httpd -DFOREGROUND
           ├─17256 /usr/sbin/httpd -DFOREGROUND
           └─17257 /usr/sbin/httpd -DFOREGROUND

May 26 11:09:56 ansible-2 systemd[1]: Starting The Apache HTTP...
May 26 11:09:56 ansible-2 httpd[17252]: AH00558: httpd: Could ...
May 26 11:09:56 ansible-2 systemd[1]: Started The Apache HTTP ...
Hint: Some lines were ellipsized, use -l to show in full.

三、ansible的playbook

(一)ansible中playbook的使用

Playbook是由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表
plays 对每一组server的所有操作就组成一个play
`所有YAML文件以---开头`
脚本组成:
hosts    指定哪些机器上操作,可以是主机组,多台机器用逗号分隔。
user     指定使用什么用户登录远程主机操作。
tasks    指定执行的任务    name   对任务的描述
handlers  与notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
`编辑脚本`

[root@ansible-1 ~]# vi /etc/ansible/test.yml 
---                   #固定格式
- hosts: 192.168.200.67     #破折号和空格开头, 冒号后边必须有一个空格。
  remote_user: root          
  tasks:
     - name: test_playbook
       shell: touch /tmp/ansible_test.txt


 `执行脚本,执行格式:ansible—playbook yml文件`
 
[root@ansible-1 ~]# ansible-playbook /etc/ansible/test.yml   

PLAY [192.168.200.67] *********************************************************************

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

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

PLAY RECAP ********************************************************************************
192.168.200.67             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  



`验证`

[root@ansible-2 ~]# ll /tmp/
total 5
drwxr-xr-x. 2 root root  18 May 25 10:27 1.txt
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rw-r--r--. 1 root root  29 May 26 11:58 ansible_test.txt
-rwx------. 1 root root 827 May 24 23:34 ks-script-aDhH4l

创建用户

`编辑脚本`

[root@ansible-1 ~]# vi /etc/ansible/create_user.yml 
---
- name: create_user       #对该playbook实现功能的概述,name变量的值执行过程中会被打印出。
  hosts: 192.168.200.67
  user: root
  gather_facts: false    #指定以下任务在执行前,是否先执行setup模块获取主机相关信息。
  vars:                 #指定变量
    - user: "test"       #user为指定变量, 其后面的值需要用引号。
  tasks:
    - name: create user
      user: name="{{ user }}"  #新添加的用户名调用上面user变量的值。
~          

`执行脚本`
[root@ansible-1 ~]# ansible-playbook /etc/ansible/create_user.yml 

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

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

PLAY RECAP ********************************************************************************
192.168.200.67             : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


`验证 `
[root@ansible-2 ~]# cat /etc/passwd |grep test
test:x:1002:1002::/home/test:/bin/bash
            

(二)ansible中playbook的循环

`编辑脚本`
[root@ansible-1 ~]# vi /etc/ansible/while.yml 
---
- hosts: testhost    #指定主机组
  user: root
  tasks:
   - name: change mode for files
     file: path=/tmp/{{ item }} mode=600   #使用file模块,指定路径,将权限改为600
     with_items:                #循环对象
      - 1.txt
      - 2.txt
      - 3.txt

`执行脚本`
[root@ansible-1 ~]# ansible-playbook /etc/ansible/while.yml 

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

TASK [Gathering Facts] ********************************************************************
ok: [192.168.200.67]
ok: [127.0.0.1]

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

PLAY RECAP ********************************************************************************
127.0.0.1                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.67             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

`验证`

[root@ansible-1 ~]# ll /tmp/     #执行脚本前文件权限
total 12
-rw-r--r--. 1 root root 1040 May 25 00:19 123
-rw-r--r--. 1 root root    0 May 26 08:45 1.txt
-rw-r--r--. 1 root root    0 May 26 08:45 2.txt
-rw-r--r--. 1 root root    0 May 26 08:45 3.txt
[root@ansible-1 ~]# ll /tmp/     
total 12
-rw-r--r--. 1 root root 1040 May 25 00:19 123
-rw-------. 1 root root    0 May 26 08:45 1.txt
-rw-------. 1 root root    0 May 26 08:45 2.txt
-rw-------. 1 root root    0 May 26 08:45 3.txt

[root@ansible-2 ~]# ll /tmp     #执行脚本前文件权限
total 12
-rw-r--r--. 1 root root   0 May 26 23:44 1.txt
-rw-r--r--. 1 root root   0 May 25 10:13 2.txt
-rw-r--r--. 1 root root   0 May 26 23:44 3.txt
[root@ansible-2 ~]# ll /tmp/
total 12
-rw-------. 1 root root   0 May 26 23:44 1.txt
-rw-------. 1 root root   0 May 25 10:13 2.txt
-rw-------. 1 root root   0 May 26 23:44 3.txt

(三)ansible中playbook的条件判断

`编辑脚本`

[root@ansible-1 ~]# vi /etc/ansible/when.yml 
---
- hosts: testhost   #指定主机组
  user: root
  gather_facts: True
  tasks:
   - name: use when
     shell: touch /tmp/when.txt
     when: ansible_eno16777728.ipv4.address == "192.168.200.67"   #when模块,作为条件判断,判断主机相关信息,当ansible_eno16777728.ipv4.address=192.168.200.67 时,执行shell模块中命令。


`执行脚本`

[root@ansible-1 ~]# ansible-playbook /etc/ansible/when.yml 

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

TASK [Gathering Facts] ********************************************************************
ok: [127.0.0.1]
ok: [192.168.200.67]

TASK [use when] ***************************************************************************
skipping: [127.0.0.1]     #不符合条件,执行命令。
[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: [192.168.200.67]

PLAY RECAP ********************************************************************************
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.200.67             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  


`验证`
[root@ansible-1 ~]# ll /tmp/    #由于127.0.0.1 不符合条件,所以不会执行shell模块中命令。
total 12
-rw-r--r--. 1 root root 1040 May 25 00:19 123
-rw-------. 1 root root    0 May 26 08:45 1.txt
-rw-------. 1 root root    0 May 26 08:45 2.txt
-rw-------. 1 root root    0 May 26 08:45 3.txt
-rwxr-xr-x. 1 root root   49 May 25 10:57 test.sh
-rw-------. 1 root root    0 May 24 23:31 yum.log
[root@ansible-2 ~]# ll /tmp/
total 12
-rw-------. 1 root root   0 May 26 23:44 1.txt
-rw-------. 1 root root   0 May 25 10:13 2.txt
-rw-------. 1 root root   0 May 26 23:44 3.txt
-rw-r--r--. 1 root root   0 May 26 23:59 when.txt


(四)ansible中playbook的handlers

它需要在tasks中被调用,才有可能被执行。
Tasks中的任务都是有状态的,changed或者ok。 在Ansible中,只在task的执行状态为changed的时候,才会执行该task调用的handlers。
`在所有的任务里表执行之后执行,如果有多个task notify同一个handler,那么只执行一次。`
`编辑脚本`

[root@ansible-1 ~]# vi /etc/ansible/handlers.yml 
---
- name: handlers test
  hosts: 192.168.200.67
  user: root
  tasks:
   - name: copy file
     copy: src=/etc/passwd dest=/tmp/aaa.txt  
     #当该模块真的执行时,handlers才会被调用。即如果/etc/passwd和/tmp/aaa.txt/文件内容相同时,copy模块没真正执行,handlers不会被调用;如果文件不同,copy模块会真正执行,hanlers被调用。
     notify: test handlers
  handlers:
   - name: test handlers
     shell: echo "111" >> /tmp/aaa.txt

`执行脚本`
[root@ansible-1 ~]# ansible-playbook /etc/ansible/handlers.yml 

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

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

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

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

PLAY RECAP ********************************************************************************
192.168.200.67             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


`验证`
[root@ansible-2 ~]# ll /tmp/
total 16
-rw-------. 1 root root    0 May 26 23:44 1.txt
-rw-------. 1 root root    0 May 25 10:13 2.txt
-rw-------. 1 root root    0 May 26 23:44 3.txt
-rw-r--r--. 1 root root 1133 May 27 00:46 aaa.txt
[root@ansible-2 ~]# cat /tmp/aaa.txt 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
111    ##重定向追加111,handlers被调用。

四、play实战安装nginx

(一)管理节点编译安装nginx

#下载nginx包并解压

yum install wget -y
wget http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz
tar -zxf nginx-1.9.6.tar.gz 

#安装nginx依赖包(远程主机也安装)
yum install gcc gcc-c++ pcre-devel zlib-devel openssl-devel -y


#编译安装nginx
cd nginx-1.9.6
./configure --prefix=/usr/local/nginx
make && make install
echo $?     #检查编译安装脚本是否有错

(1)编辑/etc/init.d/nginx配置文件

[root@ansible-1 ~]# vi /etc/init.d/nginx 
#!/bin/bash
# chkconfig: - 30 21
# description: http service.
# Source Function Library
. /etc/init.d/functions
# Nginx Settings
NGINX_SBIN="/usr/local/nginx/sbin/nginx"
NGINX_CONF="/usr/local/nginx/conf/nginx.conf"
NGINX_PID="/usx/local/nginx/logs/nginx.pid"
RETVAL=0
prog="Nginx"

start()
{
        echo -n $"Starting $prog: "
        mkdir -p /dev/shm/nginx_temp
        daemon $NGINX_SBIN -c $NGINX_CONF
        RETVAL=$?
        echo
        return $RETVAL
}
stop()
{
        echo -n $"Stopping $prog: "
        killproc -p $NGINX_PID $NGINX_SBIN -TERM
        rm -rf /dev/shm/nginx_temp
        RETVAL=$?
        echo
        return $RETVAL
}
reload()
{
        echo -n $"Reloading $prog: "
        killproc -p $NGINX_PID $NGINX_SBIN -HUP
        RETVAL=$?
        echo
        return $RETVAL
}
restart()
{
        stop
        start
}
configtest()
{
        $NGINX_SBIN -c $NGINX_CONF -t
        return 0
}
case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        reload)
                reload
                ;;
        restart)
                restart
                ;;
        configtest)
                configtest
                ;;
        *)
                echo $"Usage: $0 {start|stop|reload|restart|configtest}"
                RETVAL=1
esac
exit $RETVAL

(2)编辑/usr/local/nginx/conf/nginx.conf配置文件

##首先清空这个文件
[root@ansible-1 ~]# echo > /usr/local/nginx/conf/nginx.conf


##编辑配置文件
[root@ansible-1 ~]#  cat /usr/local/nginx/conf/nginx.conf
user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 6000;
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 3526;
server_names_hash_max_size 4096;
log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
'$host "$request_uri" $status'
'"$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 8 4k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;
client_max_body_size 10m;
client_body_buffer_size 256k;
client_body_temp_path /usr/local/nginx/client_body_temp;
proxy_temp_path /usr/local/nginx/proxy_temp;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_intercept_errors on;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 5;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/htm
application/xml;
server
{
listen 80;
server_name localhost;
index index.html index.htm index.php;
root /usr/local/nginx/html;
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/1ocal/nginx/html$fastcgi_script_name;
}
}
}

(3)检查配置文件并启动nginx

[root@ansible-1 ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful


#确认配置文件无误后启动nginx
[root@ansible-1 ~]# chmod 777 /etc/init.d/nginx    #修改权限
[root@ansible-1 ~]# systemctl stop httpd           #关闭httpd服务
[root@ansible-1 ~]# service nginx start         #启动nginx
Reloading systemd:                                         [  OK  ]
Starting nginx (via systemctl):                            [  OK  ]


[root@ansible-1 ~]# systemctl status nginx   #检查状态
● nginx.service - SYSV: http service.
   Loaded: loaded (/etc/rc.d/init.d/nginx; bad; vendor preset: disabled)
   Active: active (running) since Wed 2021-05-26 13:38:36 CST; 2min 29s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 33633 ExecStart=/etc/rc.d/init.d/nginx start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/nginx.service
           ├─33637 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx...
           ├─33638 nginx: worker process
           └─33639 nginx: worker process

May 26 13:38:36 ansible-1 systemd[1]: Starting SYSV: http service....
May 26 13:38:36 ansible-1 nginx[33633]: Starting Nginx: [  OK  ]
May 26 13:38:36 ansible-1 systemd[1]: Started SYSV: http service..

(二)管理节点创建环境配置文件并将nginx打包

`创建配置文件`

[root@ansible-1 ~]# mkdir -p /etc/ansible/nginx_install/roles/{common,install}/{handlers,files,meta,tasks,templates,vars}

[root@ansible-1 ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── create_user.yml
├── handlers.yml
├── hosts
├── nginx_install           #创建的管理目录
│   └── roles               #该目录下存在两个角色
│       ├── common          #该角色存放准备操作
│       │   ├── files       #安装时用到的文件
│       │   ├── handlers    #用户配置文件发生变化时,重启服务
│       │   ├── meta        #说明信息,说明角色依赖信息等
│       │   ├── tasks       #核心的配置文件
│       │   ├── templates   #存放配置文件,启动脚本等模板文件
│       │   └── vars        #定义的变量
│       └── install         #该角色存放安装nginx的操作
│           ├── files
│           ├── handlers
│           ├── meta
│           ├── tasks
│           ├── templates
│           └── vars
├── roles
├── test.yml
├── when.yml
└── while.yml


`打包`
[root@ansible-1 ~]# cd /usr/local/
[root@ansible-1 local]# tar -czf nginx.tar.gz nginx
[root@ansible-1 local]# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/


`将nginx的包移动到install角色中files目录下`
[root@ansible-1 ~]# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/

`将nginx的配置文件和启动文件拷贝到install角色中templates目录下`
[root@ansible-1 ~]# cp /usr/local/nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
[root@ansible-1 ~]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/

(三)管理节点文件编辑

[root@ansible-2 ~]# systemctl stop httpd #远程主机关闭httpd服务

(1)定义yum安装依赖软件

注意:文件放在common角色中tasks目录下

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/roles/common/tasks/main.yml
- name: install initializtion requre software
  yum: name={{ item }} state=installed
  with_items:
    - zlib-devel
    - pcre-devel

(2)定义变量

注意:文件放在install角色中vars目录下

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/roles/install/vars/main.yml
nginx_user: www
nginx_port: 80
nginx_basedir: /usr/local/nginx

(3)定义copy

注意:文件放在install角色中tasks目录下

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/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

(4)定义用户,启动服务,删除压缩包

注意:文件放在install角色中tasks目录下

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/roles/install/tasks/install.yml
- name: Creat 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

(5)定义copy.yml和install.yml调用

注意:文件放在install角色中tasks目录下

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/roles/install/tasks/main.yml
- include: copy.yml  #include模块,引用。
- include: install.yml

(6)定义启动文件

[root@ansible-1 ~]# vi /etc/ansible/nginx_install/install.yml
---
- hosts: 192.168.200.67
  remote_user: root
  gather_facts: True
  roles:
    - common
    - install

执行启动文件安装nginx


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

PLAY [192.168.200.67] ****************************************************************************************************************

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

TASK [common : install initializtion requre software] ********************************************************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to 
supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['zlib-devel', 'pcre-devel']` and remove the loop. This 
feature will be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [192.168.200.67] => (item=[u'zlib-devel', u'pcre-devel'])

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

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.200.67]

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

TASK [install : Copy Nginx Config] ***************************************************************************************************
ok: [192.168.200.67]

TASK [install : Creat Nginx User] ****************************************************************************************************
changed: [192.168.200.67]

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

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

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.200.67]

PLAY RECAP ***************************************************************************************************************************
192.168.200.67             : ok=10   changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 


`验证`

[root@ansible-2 ~]# systemctl status nginx
● nginx.service - SYSV: http service.
   Loaded: loaded (/etc/rc.d/init.d/nginx; bad; vendor preset: disabled)
   Active: active (running) since Thu 2021-05-27 06:11:40 CST; 6min ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/nginx.service
           ├─37283 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
           ├─37284 nginx: worker process
           └─37285 nginx: worker process

May 27 06:11:40 ansible-2 systemd[1]: Starting SYSV: http service....
May 27 06:11:40 ansible-2 nginx[37279]: Starting Nginx: [  OK  ]
May 27 06:11:40 ansible-2 systemd[1]: Started SYSV: http service..

(四)管理配置文件

管理nginx配置文件的playbook

`创建目录`

[root@ansible-1 ~]# mkdir  -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
[root@ansible-1 ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── create_user.yml
├── handlers.yml
├── hosts
├── nginx_config     
│   └── roles   
│       ├── new            #更新时用到的角色
│       │   ├── files      #存放nginx.conf文件和vhosts目录
│       │   ├── handlers
│       │   ├── tasks
│       │   └── vars
│       └── old       	  #回滚时用到的角色
│           ├── files
│           ├── handlers
│           ├── tasks
│           └── vars


`创建虚拟主机目录`
[root@ansible-1 ~]# mkdir /usr/local/nginx/conf/vhosts
[root@ansible-1 ~]# touch /usr/local/nginx/conf/vhosts/1.conf
`修改nginx的配置文件`
[root@ansible-1 ~]# vim /usr/local/nginx/conf/nginx.conf

user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 6000;
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 3526;
server_names_hash_max_size 4096;
log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
'$host "$request_uri" $status'
'"$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 8 4k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;
client_max_body_size 10m;
client_body_buffer_size 256k;
client_body_temp_path /usr/local/nginx/client_body_temp;
proxy_temp_path /usr/local/nginx/proxy_temp;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_intercept_errors on;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 5;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/htm
application/xml;
server
{
listen 80;
server_name localhost;
index index.html index.htm index.php;
root /usr/local/nginx/html;
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/1ocal/nginx/html$fastcgi_script_name;
}
}
include /usr/local/nginx/conf/vhosts/*.conf;     #该行为添加内容.
}



[root@ansible-2 ~]# vi /usr/local/nginx/conf/nginx.conf

user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 6000;
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 3526;
server_names_hash_max_size 4096;
log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
'$host "$request_uri" $status'
'"$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 8 4k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;
client_max_body_size 10m;
client_body_buffer_size 256k;
client_body_temp_path /usr/local/nginx/client_body_temp;
proxy_temp_path /usr/local/nginx/proxy_temp;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_intercept_errors on;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 5;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/htm
application/xml;
server
{
listen 80;
server_name localhost;
index index.html index.htm index.php;
root /usr/local/nginx/html;
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/1ocal/nginx/html$fastcgi_script_name;
}
}
include /usr/local/nginx/conf/vhosts/*.conf;    #该行为添加内容
}

[root@ansible-1 ~]# cd /usr/local/nginx/conf/
[root@ansible-1 conf]# cp -r nginx.conf vhosts /etc/ansible/nginx_config/roles/new/files/

定义变量

[root@ansible-1 ~]# vi /etc/ansible/nginx_config/roles/new/vars/main.yml
nginx_basedir: /usr/local/nginx

定义重新加载nginx服务

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

定义任务

[root@ansible-1 ~]# vi /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

定义更新时入口

[root@ansible-1 ~]# vi /etc/ansible/nginx_config/update.yml
---
- hosts: testhost
  user: root
  roles:
   - new

执行脚本(此时为更新)

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

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

TASK [Gathering Facts] ***************************************************************************************************************
ok: [127.0.0.1]
ok: [192.168.200.67]

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

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

PLAY RECAP ***************************************************************************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.67             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

回滚

回滚操作就是把旧的配置覆盖,然后重新加载nginx服务, 每次改动nginx配置文件之前先备份到old里,对应目录为/etc/ansible/nginx_config/roles/old/files

[root@ansible-1 conf]# rsync -av /etc/ansible/nginx_config/roles/new/ /etc/ansible/nginx_config/roles/old/

定义回滚时入口

[root@ansible-1 conf]# vim /etc/ansible/nginx_config/rollback.yml 
---
- hosts: testhost
  user: root
  roles:
   - old

执行脚本(此时为回滚)

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

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

TASK [Gathering Facts] ***************************************************************************************************************
ok: [127.0.0.1]
ok: [192.168.200.67]

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

PLAY RECAP ***************************************************************************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.67             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

`由于对配置文件没有任何修改操作,所以直接复制`

人为修改配置文件,查看回滚

[root@ansible-2 ~]# rm -rf /usr/local/nginx/conf/nginx.conf   #删除nginx的配置文件

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

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

TASK [Gathering Facts] ***************************************************************************************************************
ok: [127.0.0.1]
ok: [192.168.200.67]

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

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

PLAY RECAP ***************************************************************************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.67             : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值