自动化运维介绍
随着信息时代的持续发展,IT运维已经成为IT服务内涵中重要的组成部分。面对越来越复杂的业务,面对越来越多样化的用户需求,不断扩展的IT应用,需要越来越合理的模式来保障IT服务能灵活便捷、安全稳定地持续保障,这种模式中的保障因素就是IT运维(其他因素是更加优越的IT架构等)。从初期的几台服务器发展到庞大的数据中心,单靠人工已经无法满足在技术、业务、管理等方面的要求,那么标准化、自动化、架构优化、过程优化等降低IT服务成本的因素越来越被人们所重视。其中,自动化最开始作为代替人工操作为出发点的诉求被广泛研究和应用。
IT运维从诞生发展至今,自动化作为其重要属性之一,已经不仅仅只是代替人工操作,更重要的是深层探知和全局分析,关注的是在当前条件下如何实现性能与服务最优化,同时保障投资收益最大化。自动化对IT运维的影响,已经不仅仅是人与设备之间的关系,已经发展到了面向客户服务、驱动IT运维决策的层面,IT运维团队的构成,也从各级技术人员占大多数发展到业务人员甚至用户占大多数的局面。
因此,IT运维自动化是一组将静态的设备结构转化为根据IT服务需求动态弹性响应的策略,目的就是实现IT运维的质量,降低成本。可以说自动化一定是IT运维最高层面的重要属性之一,但不是全部。
常用工具
(1)Puppet(www.puppetlabs.com)
(2)SaltStack(官网 https://saltstack.com、文档docs.saltstack.com )
(3)Ansible(www.ansible.com)
Ansible
Ansible介绍
(1)Ansible不需要安装客户端,通过sshd去通信(无密钥登录)。
(2)Ansible基于模块工作,模块可以由任何语言开发。
(3)Ansible不仅支持命令行使用模块,也支持编写Yaml格式的playbook,易于编写和阅读。
(4)Ansible安装十分简单,CentOS上可直接Yum安装。
(5)Ansible有提供UI(浏览器图形化)
Ansible架构图
Ansible执行流程图
Ansible安装
(1)环境准备
在两台机器上关闭防火墙和SELinux,并修改/etc/hosts文件。
[root@ansible-01 ~]# systemctl stop firewalld
[root@ansible-01 ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
[root@ansible-01 ~]# setenforce 0
[root@ansible-01 ~]# cat /etc/selinux/config
…# disabled - No SELinux policy is loaded.
SELINUX=disabled //将此处改为disabled
# SELINUXTYPE= can take one of three two values:
…
[root@ansible-01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.200.124 ansible-01 //添加两台主机的IP和主机名
192.168.200.125 ansible-02
(2)安装Ansible先安装epel仓库
只需要在ansible-01上安装Ansible,
[root@ansible-01 ~]# yum install epel-release -y
[root@ansible-01 ~]# yum install -y ansible
[root@ansible-01 ~]# ansible --version
ansible 2.9.10
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
(3)免密配置
anisble-01上生成密钥对ssh-keygen -t rsa,把公钥放到anisble-02上,设置密钥认证。
注意:需要将本机也配置免密。
[root@ansible-01 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
0a:47:86:44:83:a2:7c:c3:0c:1b:33:1c:03:88:0c:09 root@ansible-test1
The key's randomart image is:
+--[ RSA 2048]----+
|E+.o+ |
|=Bo. o |
|o.O . o |
|.o = o |
| . o . S |
| . o . S |
| o . |
| . |
| |
| |
+-----------------+
[root@ansible-01 ~]# ssh-copy-id 192.168.200.125一直回车
[root@ansible-01 ~]# ssh-copy-id 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is 8b:94:37:ec:2d:fd:0c:95:f2:9d:a8:71:71:97:8a:64.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': y
Please type 'yes' or 'no': yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@127.0.0.1's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '127.0.0.1'"
and check to make sure that only the key(s) you wanted were added.
(4)主机组设置
在/etc/ansible/hosts文件中添加本机和另一台机器的IP:
[root@ansible-01 ~]# cat /etc/ansible/hosts
[testhost]
127.0.0.1
192.168.200.125
说明:testhost为自定义的主机组名字,下面两个IP为组内的机器IP。
Ansible远程执行命令
testhost为主机组名,-m后边是模块名字,-a后面是命令。当然我们也可以直接写一个IP,针对某一台机器来执行命令。
[root@ansible-01 ~]# ansible 127.0.0.1 -m command -a 'hostname'
127.0.0.1 | CHANGED | rc=0 >>
ansible-01
[root@ansible-01 ~]# ansible 192.168.200.125 -m command -a 'hostname'
192.168.200.125 | CHANGED | rc=0 >>
ansible-02
[root@ansible-01 ~]# ansible testhost -m command -a 'hostname'
192.168.200.125 | CHANGED | rc=0 >>
ansible-02
127.0.0.1 | CHANGED | rc=0 >>
ansible-01
shell同样可以实现
[root@ansible-01 ~]# ansible testhost -m shell -a 'hostname'
192.168.200.125 | CHANGED | rc=0 >>
ansible-02
127.0.0.1 | CHANGED | rc=0 >>
ansible-01
Ansible拷贝文件或目录
源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,如果dest指定的名字和源不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。
[root@ansible-01 ~]# vi wangruxin.txt
[root@ansible-01 ~]# ansible 192.168.200.125 -m copy -a "src=wangruxin.txt dest=/tmp/123"
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "c4f9375f9834b4e7f0a528cc65c055702bf5f24a",
"dest": "/tmp/123",
"gid": 0,
"group": "root",
"md5sum": "f447b20a7fcbf53a5d5be013ea0b15af",
"mode": "0644",
"owner": "root",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1621977190.44-24059-205077923707169/source",
"state": "file",
"uid": 0
}
去ansible-02下检查
[root@ansible-02 ~]# ls /tmp/
123
拷贝目录
[root@ansible-01 ~]# ansible 192.168.200.125 -m copy -a "src=test1 dest=/tmp/test1"
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "12039d6dd9a7e27622301e935b6eefc78846802e",
"dest": "/tmp/test1/test1/test.txt",
"gid": 0,
"group": "root",
"md5sum": "7c12772809c1c0c3deda6103b10fdfa0",
"mode": "0644",
"owner": "root",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1621944959.17-3689-38217942072177/source",
"state": "file",
"uid": 0
}
test1自动创建
[root@ansible-02 tmp]# ls /tmp/test1
test1
如果dest指定的名字和源不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。
[root@ansible-01 ~]# ansible 192.168.200.125 -m copy -a "src=test1.txt dest=/tmp/test2.txt"
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/tmp/test2.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1621949759.71-3786-255328681565941/source",
"state": "file",
"uid": 0
}
相当于复制到ansible-02并且重命名
[root@ansible-02 ~]# ls /tmp/
123 test1 test2.txt
如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。
[root@ansible-01 ~]# ansible 192.168.200.125 -m copy -a "src=test1.txt dest=/tmp/test1.txt"
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/tmp/test1.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1621949878.19-3817-97703450366335/source",
"state": "file",
"uid": 0
}
[root@ansible-02 ~]# ls /tmp/
123
1.txt
2.txt
3.txt
aaa.txt
ansible_test.txt
test1
test1.txt
Ansible远程执行脚本
首先创建一个shell脚本。
[root@ansible-01 ~]# cat /tmp/test.sh
#!/bin/bash
echo `date` > /tmp/ansible_test.txt
然后把脚本发送到主机组
[root@ansible-01 ~]# ansible testhost -m copy -a "src=/tmp/test.sh dest=/tmp/test.sh mode=0755"
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "1a6e4af02dba1bda6fc8e23031d4447efeba0ade",
"dest": "/tmp/test.sh",
"gid": 0,
"group": "root",
"md5sum": "edfaa4371316af8c5ba354e708fe8a97",
"mode": "0755",
"owner": "root",
"size": 48,
"src": "/root/.ansible/tmp/ansible-tmp-1621950419.73-3998-108005550371929/source",
"state": "file",
"uid": 0
}
127.0.0.1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "1a6e4af02dba1bda6fc8e23031d4447efeba0ade",
"dest": "/tmp/test.sh",
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/test.sh",
"size": 48,
"state": "file",
"uid": 0
}
远程执行脚本
[root@ansible-01 ~]# ansible testhost -m shell -a "/tmp/test.sh"
127.0.0.1 | CHANGED | rc=0 >>
192.168.200.125 | CHANGED | rc=0 >>
检查
[root@ansible-01 ~]# cat /tmp/ansible_test.txt
Tue May 25 21:48:46 CST 2021
[root@ansible-02 ~]# cat /tmp/ansible_test.txt
Tue May 25 21:48:46 CST 2021
shell模块,还支持远程执行命令并且带管道。
[root@ansible-01 ~]# ansible testhost -m shell -a "cat /etc/passwd|wc -l"
127.0.0.1 | CHANGED | rc=0 >>
21
192.168.200.125 | CHANGED | rc=0 >>
21
Ansible管理任务计划
[root@ansible-01 ~]# ansible testhost -m cron -a "name='test cron' job='/bin/touch /tmp/1212.txt' weekday=6"127.0.0.1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"test cron"
]
}
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"test cron"
]
}
查看
[root@ansible-01 ~]# crontab -e
#Ansible: test cron
* * * * 6 /bin/touch /tmp/1212.txt
~
删除
[root@ansible-01 ~]# ansible testhost -m cron -a "name='test cron' state=absent"
127.0.0.1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
192.168.200.125 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
~
Ansible安装RPM包/管理服务
使用Yum模块安装httpd服务。
[root@ansible-01 ~]# ansible testhost -m yum -a "name=httpd"
设置服务状态,这里的name是CentOS系统里的服务名,可以通过chkconfig –list命令查到。
[root@ansible-01 ~]# ansible testhost -m service -a "name=httpd state=started
enabled=yes"
Ansible文档的使用:
[root@ansible-01 ~]# ansible-doc -l //列出所有模块
fortios_router_community_list Configure community lists in Fortinet's FortiOS ...
azure_rm_devtestlab_info Get Azure DevTest Lab facts
ecs_taskdefinition register a task definition in ecs
avi_alertscriptconfig Module for setup of AlertScriptConfig Avi RESTfu...
tower_receive Receive assets from Ansible Tower
netapp_e_iscsi_target NetApp E-Series manage iSCSI target configuratio...
azure_rm_acs Manage an Azure Container Service(ACS) instance
…
[root@ansible-01 ~]# ansible-doc yum //查看指定模块的文档
> YUM (/usr/lib/python2.7/site-packages/ansible/modules/packaging/os/yum.py)
Installs, upgrade, downgrades, removes, and lists packages and groups with the `yum'
package manager. This module only works on Python 2. If you require Python 3 support
see the [dnf] module.
* This module is maintained by The Ansible Core Team
* note: This module has a corresponding action plugin.
OPTIONS (= is mandatory):
- allow_downgrade
Specify if the named package and version is allowed to downgrade a maybe already
installed higher version of that package. Note that setting allow_downgrade=True can
make this module behave in a non-idempotent way. The task could end up with a set of
packages that does not match the complete list of specified packages to install
(because dependencies between the downgraded package and others can cause changes to
the packages which were in the earlier transaction).
[Default: no]
type: bool
version_added: 2.4
Ansible playbook使用
ansible playbook中的使用
相当于把模块写入到配置文件里面,例
[root@ansible-01 ~]# vim /etc/ansible/test.yml
---
- hosts: 192.168.200.125
remote_user: root
tasks:
- name: test_playbook
shell: touch /tmp/ansible_test.txt
执行
[root@ansible-01 ~]# ansible-playbook /etc/ansible/test.yml
PLAY [192.168.200.125] **************************************************************************************
TASK [Gathering Facts] **************************************************************************************
ok: [192.168.200.125]
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.125]
PLAY RECAP **************************************************************************************************
192.168.200.125 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看已经存在ansible_test.txt
[root@ansible-02 ~]# ls /tmp/
123
ansible_test.txt
systemd-private-b6fcc2ff9893498db77e9b402aa5cb62-httpd.service-w5bIgD
test1
test1.txt
test2.txt
test.sh
yum_save_tx.2021-05-25.22-04.lEpDv7.yumtx
yum_save_tx.2021-05-25.22-04.rdGGvT.yumtx
说明:第一行需要有三个杠,hosts参数指定了对哪些主机进行操作,如果是多台机器可以用逗号作为分隔,也可以使用主机组,在/etc/ansible/hosts里定义,user参数指定了使用什么用户登录远程主机操作,tasks指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来,shell是ansible模块名字
创建用户的例子
[root@ansible-01 ~]# vim /etc/ansible/create_user.yml
---
- name: create_user
hosts: 192.168.200.125
user: root
gather_facts: false
vars:
- user: "test"
tasks:
- name: create user
user: name="{{ user }}"
[root@ansible-01 ~]# ansible-playbook /etc/ansible/create_user.yml
PLAY [create_user] ******************************************************************************************
TASK [create user] ******************************************************************************************
changed: [192.168.200.125]
PLAY RECAP **************************************************************************************************
192.168.200.125 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
说明:name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值 ,可以省略;gather_facts参数指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时用到;vars参数,指定了变量,这里指字一个user变量,其值为test ,需要注意的是,变量值一定要用引号引住;user提定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。
ansible playbook中的循环
创建while.yml文件修改权限
[root@ansible-01 ansible]# cat while.yml
---
- hosts: testhost
user: root
tasks:
- name: change mode for files
file: path=/tmp/{{ item }} mode=600
with_items:
- 1.txt
- 2.txt
- 3.txt
说明: with_items为循环的对象
执行while.yml。
[root@ansible-01 ansible]# ansible-playbook while.yml
PLAY [testhost] ***************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************
ok: [127.0.0.1]
ok: [192.168.200.125]
TASK [change mode for files] **************************************************************************************
ok: [127.0.0.1] => (item=1.txt)
changed: [192.168.2.20] => (item=1.txt)
ok: [127.0.0.1] => (item=2.txt)
changed: [192.168.2.20] => (item=2.txt)
ok: [127.0.0.1] => (item=3.txt)
changed: [192.168.2.20] => (item=3.txt)
PLAY RECAP ********************************************************************************************************
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.200.125 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
条件判断
[root@ansible-01 ~]# vim /etc/ansible/when.yml
---
- hosts: testhost
user: root
gather_facts: True
tasks:
- name: use when
shell: touch /tmp/when.txt
when: ansible_eno16777736.ipv4.address == "192.168.200.125"
~
[root@ansible-01 ~]# ansible-playbook /etc/ansible/when.yml
PLAY [testhost] *********************************************************************************************
TASK [Gathering Facts] **************************************************************************************
ok: [127.0.0.1]
ok: [192.168.200.125]
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.125]
PLAY RECAP **************************************************************************************************
127.0.0.1 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.200.125 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```[root@ansible-02 tmp]# ls
123
1.txt
2.txt
3.txt
ansible_test.txt
systemd-private-b6fcc2ff9893498db77e9b402aa5cb62-httpd.service-w5bIgD
test1
test1.txt
test2.txt
test.sh
when.txt
yum_save_tx.2021-05-25.22-04.lEpDv7.yumtx
yum_save_tx.2021-05-25.22-04.rdGGvT.yumtx
查看主机信息
[root@ansible-01 ~]# ansible 192.168.200.125 -m setup
**ansible playbook中的handlers**
[root@ansible-01 ~]# vim /etc/ansible/handlers.yml
[root@ansible-01 ~]# ansible-playbook /etc/ansible/handlers.yml
PLAY [handlers test] ****************************************************************************************
TASK [Gathering Facts] **************************************************************************************
ok: [192.168.200.125]
TASK [copy file] ********************************************************************************************
changed: [192.168.200.125]
RUNNING HANDLER [test handlers] *****************************************************************************
changed: [192.168.200.125]
PLAY RECAP **************************************************************************************************
192.168.200.125 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible-01 ~]# cat /etc/ansible/handlers.yml
---
- name: handlers test
hosts: 192.168.200.125
user: root
tasks:
- name: copy file
copy: src=/etc/passwd dest=/tmp/aaa.txt
notify: test handlers
handlers:
- name: test handlers
shell: echo "111111" >> /tmp/aaa.txt
[root@ansible-02 tmp]# 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
111111
说明,只有copy模块真正执行后,才会去调用下面的handlers相关的操作。也就是说如果1.txt和2.txt内容是一样的,并不会去执行handlers里面的shell相关命令。 这种比较适合配置文件发生更改后,重启服务的操作。
Ansible playbook实战
ansible自动化安装nginx
下载wget安装nginx的安装包
[root@ansible-01 ~]# yum install wget
[root@ansible-01 ~]# wget http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz
[root@ansible-01 ~]# ls
anaconda-ks.cfg test1
CentOS-7-x86_64-DVD-1511.iso test1.txt
nginx-1.9.6.tar.gz
解压安装依赖进行编译安装
[root@ansible-01 ~]# tar -zxf nginx-1.9.6.tar.gz
[root@ansible-01 nginx-1.9.6]# yum install gcc gcc-c++ pcre-devel zlib-devel openssl-devel -y
[root@ansible-01 nginx-1.9.6]# ./configure --prefix=/usr/local/nginx
[root@ansible-01 nginx-1.9.6]# make && make install
[root@ansible-01 nginx-1.9.6]# echo $?
0
编写/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
清空配置文件并重新编写
# > /usr/local/nginx/conf/nginx.conf
要把文字删掉不然会报错
[root@ansible-01 nginx-1.9.6]# #vim /usr/local/nginx/conf/nginx.conf
user nobody nobody; //定义nginx运行的用户和用户组
worker_processes 2; //nginx进程数,一般为CPU总核心数
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 //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 KaTeX parse error: Double subscript at position 7: http_x_̲forwarded_for [time_local]’
'
h
o
s
t
"
host "
host"request_uri" KaTeX parse error: Double superscript at position 9: status' '̲"http_referer" "KaTeX parse error: Can't use function '\.' in math mode at position 911: …ml; 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;
}
}
}
检查是否有错误
[root@ansible-01 nginx-1.9.6]# /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-01 nginx-1.9.6]# chmod 777 /etc/init.d/nginx
[root@ansible-01 nginx-1.9.6]# netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1087/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1375/master
tcp6 0 0 :::80 :::* LISTEN 5297/httpd
tcp6 0 0 :::22 :::* LISTEN 1087/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1375/master
[root@ansible-01 nginx-1.9.6]# systemctl stop httpd
[root@ansible-01 nginx-1.9.6]# netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1087/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1375/master
tcp6 0 0 :::22 :::* LISTEN 1087/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1375/master
[root@ansible-01 nginx-1.9.6]# service nginx start
Reloading systemd: [ OK ]
Starting nginx (via systemctl): [ OK ]
创建目录
[root@ansible-01 ~]# cd /etc/ansible
[root@ansible-01 ansible]# mkdir nginx_install
[root@ansible-01 ansible]# cd !$
cd nginx_install
[root@ansible-01 nginx_install]# mkdir -p roles/{common,install}/{handelers,files,meta,tasks,templates,vars}
打包
[root@ansible-01 local]# tar -zcvf nginx.tar.gz nginx/
nginx/
nginx/sbin/
nginx/sbin/nginx
nginx/conf/
nginx/conf/koi-win
nginx/conf/koi-utf
nginx/conf/win-utf
nginx/conf/mime.types
nginx/conf/mime.types.default
nginx/conf/fastcgi_params
nginx/conf/fastcgi_params.default
nginx/conf/fastcgi.conf
nginx/conf/fastcgi.conf.default
nginx/conf/uwsgi_params
nginx/conf/uwsgi_params.default
nginx/conf/scgi_params
nginx/conf/scgi_params.default
nginx/conf/nginx.conf.default
nginx/conf/nginx.conf
nginx/logs/
nginx/logs/error.log
nginx/logs/nginx.pid
nginx/logs/nginx_error.log
nginx/logs/access.log
nginx/html/
nginx/html/50x.html
nginx/html/index.html
nginx/client_body_temp/
nginx/proxy_temp/
nginx/fastcgi_temp/
nginx/uwsgi_temp/
打包完毕
移动目录
[root@ansible-01 local]# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/
复制配置文件
[root@ansible-01 nginx]# cp conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
[root@ansible-01 nginx]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/
查看ansible-02的http端口是否存在
[root@ansible-02 ~]# 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 Tue 2021-05-25 22:29:45 CST; 6h ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 6637 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─6637 /usr/sbin/httpd -DFOREGROUND
├─6638 /usr/sbin/httpd -DFOREGROUND
├─6639 /usr/sbin/httpd -DFOREGROUND
├─6640 /usr/sbin/httpd -DFOREGROUND
├─6642 /usr/sbin/httpd -DFOREGROUND
└─6643 /usr/sbin/httpd -DFOREGROUND
May 25 22:29:45 ansible-02 systemd[1]: Starting The...
May 25 22:29:45 ansible-02 httpd[6637]: AH00558: ht...
May 25 22:29:45 ansible-02 systemd[1]: Started The ...
Hint: Some lines were ellipsized, use -l to show in full.
[root@ansible-02 ~]# systemctl stop httpd
切换到nginx目录下(这里可以忽略,只要在目录下即可)
[root@ansible-01 ~]# cd /usr/local
[root@ansible-01 local]# ls
bin games lib libexec sbin src
etc include lib64 nginx share
[root@ansible-01 local]# cd nginx
[root@ansible-01 nginx]#
one
[root@ansible-01 nginx]# vim /etc/ansible/nginx_install/roles/common/tasks/main.yml
- name: install initializtion require software #安装依赖
yum : name={{ item }} state=installed
with_items: #循环列表
- zlib-devel
- pcre-devel
two
定义变量
[root@ansible-01 nginx]# vim /etc/ansible/nginx_install/roles/install/vars/main.yml
nginx_user: www
nginx_port: 80
nginx_basedir: /usr/local/nginx
three
[root@ansible-01 nginx]# vim /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 }}/co
nf/ owner=root group=root mode=0644
four
创建用户,启动服务,删除压缩包
[root@ansible-01 ~]# vim /etc/ansible/nginx_install/roles/install/tasks/install.yml
- name: Create Nginx User
user: name={{ nginx_user }} state=present createhome=no s
hell=/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
[root@ansible-01 ~]# vim /etc/ansible/nginx_install/roles/install/tasks/main.yml
- include: copy.yml
- include: install.yml
[root@ansible-01 ~]# vim /etc/ansible/nginx_install/install.yml
---
- hosts: 192.168.200.125
remote_user: root
gather_facts: True
roles:
- common
- install
[root@ansible-01 ~]# ansible-playbook /etc/ansible/nginx_install/install.yml
PLAY [192.168.200.125] **************************************************************************************
TASK [Gathering Facts] **************************************************************************************
ok: [192.168.200.125]
TASK [common : Install initializtion require 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.125] => (item=[u'zlib-devel', u'pcre-devel'])
TASK [install : Copy Nginx Software] ************************************************************************
changed: [192.168.200.125]
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.125]
TASK [install : Copy Nginx Start Script] ********************************************************************
changed: [192.168.200.125]
TASK [install : Copy Nginx Config] **************************************************************************
ok: [192.168.200.125]
TASK [install : Create Nginx User] **************************************************************************
changed: [192.168.200.125]
TASK [install : Start Nginx Service] ************************************************************************
changed: [192.168.200.125]
TASK [install : Add Boot Start Nginx Service] ***************************************************************
changed: [192.168.200.125]
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.125]
PLAY RECAP **************************************************************************************************
192.168.200.125 : ok=10 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
管理配置文件
生产环境中大多时候是需要管理配置文件的,安装软件包只是在初始化环境的时候用一下。下面我们来写个管理nginx配置文件的playbook。
创建目录
[root@ansible-01 ~]# mkdir -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
new为更新时用到的,old为回滚时用到的,files下面为nginx.conf和vhosts目录,handlers为重启nginx服务的命令
查找虚拟主机目录发现并没有创建虚拟主机目录
[root@ansible-01 ~]# cd /usr/local/nginx/conf
[root@ansible-01 conf]# ls
fastcgi.conf nginx.conf
fastcgi.conf.default nginx.conf.default
fastcgi_params scgi_params
fastcgi_params.default scgi_params.default
koi-utf uwsgi_params
koi-win uwsgi_params.default
mime.types win-utf
mime.types.default
[root@ansible-01 conf]# mkdir vhosts
[root@ansible-01 conf]# cd !$
cd vhosts
[root@ansible-01 vhosts]# touch 1.conf
两台虚拟机修改配置文件~~[root@ansible-01 ~]# cd /usr/local/nginx/conf~~
[root@ansible-01 conf]# vim nginx.conf
http下最后一个大括号前
加入include /usr/local/nginx/conf/vhosts/*.conf;
复制配置文件和虚拟主机
[root@ansible-01 conf]# cp -r nginx.conf vhosts /etc/ansible/nginx_config/roles/new/files/
查看
[root@ansible-01 conf]# ls /etc/ansible/nginx_config/roles/new/files/
nginx.conf vhosts
创建文件
[root@ansible-01 conf]# cd /etc/ansible/nginx_config/
变量
[root@ansible-01 nginx_config]# vim roles/new/vars/main.yml
nginx_basedir: /usr/local/nginx
重启nginx服务
[root@ansible-01 nginx_config]# vim roles/new/handlers/main.yml
- name: restart nginx
shell: /etc/init.d/nginx reload
复制nginx.conf和虚拟主机
[root@ansible-01 nginx_config]# vim 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-01 nginx_config]# vim /etc/ansible/nginx_config/update.yml
---
- hosts: testhost
user: root
roles:
- new
执行
[root@ansible-01 nginx_config]# ansible-playbook /etc/ansible/nginx_config/update.yml
PLAY [testhost] ****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.200.125]
ok: [127.0.0.1]
TASK [new : copy conf file] ****************************************************
ok: [192.168.200.125] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
ok: [127.0.0.1] => (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.125] => (item={u'dest': u'conf/', u'src': u'vhosts'})
RUNNING HANDLER [new : restart nginx] ******************************************
changed: [192.168.200.125]
PLAY RECAP *********************************************************************
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.200.125 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
更新操作完成
回滚操作就是把旧的配置覆盖,然后重新加载nginx服务, 每次改动nginx配置文件之前先备份到old里,对应目录为/etc/ansible/nginx_config/roles/old/files。
安装rsync
[root@ansible-01 nginx_config]# yum install rsync -y
[root@ansible-01 nginx_config]# rsync -av /etc/ansible/nginx_config/roles/new/ /etc/ansible/nginx_config/roles/old/
sending incremental file list
files/
files/nginx.conf
files/vhosts/
files/vhosts/1.conf
handlers/
handlers/main.yml
tasks/
tasks/main.yml
vars/
vars/main.yml
sent 2,445 bytes received 131 bytes 5,152.00 bytes/sec
total size is 1,892 speedup is 0.73
回滚
[root@ansible-01 nginx_config]# vim /etc/ansible/nginx_config/rollback.yml
---
- hosts: testhost
user: root
roles:
- old
执行
[root@ansible-01 nginx_config]# ansible-playbook /etc/ansible/nginx_config/rollback.yml
PLAY [testhost] ****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.200.125]
ok: [127.0.0.1]
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.125] => (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.125] => (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.125 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0