【简介】
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