自动化运维-Ansible

自动化运维介绍

随着信息时代的持续发展,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  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值