Ansible---

自动化运维

1.1 自动化运维介绍

随着信息时代的持续发展,IT运维已经成为IT服务内涵中重要的组成部分。面对越来越复杂的业务,面对越来越多样化的用户需求,不断扩展的IT应用,需要越来越合理的模式来保障IT服务能灵活便捷、安全稳定地持续保障,这种模式中的保障因素就是IT运维(其他因素是更加优越的IT架构等)。从初期的几台服务器发展到庞大的数据中心,单靠人工已经无法满足在技术、业务、管理等方面的要求,那么标准化、自动化、架构优化、过程优化等降低IT服务成本的因素越来越被人们所重视。其中,自动化最开始作为代替人工操作为出发点的诉求被广泛研究和应用。

IT运维从诞生发展至今,自动化作为其重要属性之一,已经不仅仅只是代替人工操作,更重要的是深层探知和全局分析,关注的是在当前条件下如何实现性能与服务最优化,同时保障投资收益最大化。自动化对IT运维的影响,已经不仅仅是人与设备之间的关系,已经发展到了面向客户服务、驱动IT运维决策的层面,IT运维团队的构成,也从各级技术人员占大多数发展到业务人员甚至用户占大多数的局面。

因此,IT运维自动化是一组将静态的设备结构转化为根据IT服务需求动态弹性响应的策略,目的就是实现IT运维的质量,降低成本。可以说自动化一定是IT运维最高层面的重要属性之一,但不是全部。

1.2 常用工具

(1)Puppet(www.puppetlabs.com)

Puppet是早期的Linux自动化运维工具,是一种LINUX、WINDOWS、UNIX平台的集中配置管理系统,到现在已经非常成熟,可以批量管理远程服务器,模块丰富、配置复杂、基于Ruby语言编写。是最典型的C/S结构,需要安装服务端和客户端。

Puppet采用C/S星状的结构,所有的客户端和一个或者多个服务器交互,每个客户端周期地(默认半个小时)向服务器发送请求,获得最新的配置信息,保证和配置信息同步。

每个Puppet客户端周期地连接一次服务器,下载最新的配置文件,并且严格按照配置文件来配置客户端。配置完成后,Puppet客户端可以反馈给服务器端一个消息,如果出错也会给服务器端反馈一个消息。

Puppet适用于服务器管理的整个过程,比如初始安装、配置、更新等。

(2)SaltStack(官网 https://saltstack.com、文档docs.saltstack.com )

SaltStack和Puppet一样,也是C/S模式,需要安装服务端和客户端,基于Python编写,加入了MQ消息同步,可以使执行命令和执行结果高效返回,但其执行过程需要等待客户端全部返回,如果客户端没有及时返回或者没有响应的话,可能会导致部分机器没有执行结果。

(3)Ansible(www.ansible.com)

Ansible基于Python开发的,Ansible不需要在客户端服务器上安装客户端。因为Ansible基于SSH远程管理,而Linux服务器大部分都离不开SSH,所以Ansible不需要为配置添加额外的支持。

Ansible安装使用都很简单,而且基于上千个插件和模块,实现各种软件、平台、版本的管理,支持虚拟容器多层级的部署。

Ansible

2.1 Ansible介绍

(1)Ansible不需要安装客户端,通过sshd去通信(无密钥登录)。

(2)Ansible基于模块工作,模块可以由任何语言开发。

(3)Ansible不仅支持命令行使用模块,也支持编写Yaml格式的playbook,易于编写和阅读。

(4)Ansible安装十分简单,CentOS上可直接Yum安装。

(5)Ansible有提供UI(浏览器图形化)www.ansible.com/tower,收费的官方文档 http://docs.ansible.com/ansible/latest/index.html。

Ansible已经被RedHat公司收购,它在Github(https://github.com/ansible/ansible)上是一个非常受欢迎的开源软件。

一本不错的入门电子书 https://ansible-book.gitbooks.io/ansible-first-book/

 

2.1.1 Ansible架构图

 

2.1.2 Ansible执行流程

2.2 Ansible安装

(1)环境准备

在两台机器上关闭防火墙和SELinux,并修改/etc/hosts文件。

[root@ansible-test1 ~]# systemctl stop firewalld

[root@ansible-test1 ~]# 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-test1 ~]# setenforce 0

[root@ansible-test1 ~]# cat /etc/selinux/config

#     disabled - No SELinux policy is loaded.

SELINUX=disabled //将此处改为disabled

# SELINUXTYPE= can take one of three two values:

[root@ansible-test1 ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.2.10 ansible-test1     //添加两台主机的IP和主机名

192.168.2.20 ansible-test2

(2)安装Ansible

准备两台机器anisble-01和anisble-02,只需要在anisble-01上安装Ansible,先安装epel仓库。

[root@ansible-test1 ~]# yum install epel-release -y

[root@ansible-test1 ~]# yum install -y ansible

[root@ansible-test1 ~]# 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-test1 ~]# 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 .         |

|      .          |

|                 |

|                 |

+-----------------+

[root@ansible-test1 ~]# ssh-copy-id 192.168.2.20

The authenticity of host '192.168.2.20 (192.168.2.20)' can't be established.

ECDSA key fingerprint is dc:a5:08:4d:9a:40:8a:be:ee:68:dd:41:61:7d:d7:05.

Are you sure you want to continue connecting (yes/no)? yes

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

root@192.168.2.20's password:

 

Number of key(s) added: 1

 

Now try logging into the machine, with:   "ssh '192.168.2.20'"

and check to make sure that only the key(s) you wanted were added.

 

[root@ansible-test1 ~]# ssh 192.168.2.20

Last login: Sat Jul  4 16:49:18 2020 from 192.168.2.3

[root@ansible-test2 ~]# 登出

Connection to 192.168.2.20 closed.

(4)主机组设置

在/etc/ansible/hosts文件中添加本机和另一台机器的IP:

[root@ansible-test1 ~]# grep ^[^#] /etc/ansible/hosts

[testhost]

127.0.0.1

192.168.2.20

说明:testhost为自定义的主机组名字,下面两个IP为组内的机器IP。

2.3 Ansible远程执行命令

这样就可以批量执行命令了。这里的testhost为主机组名,-m后边是模块名字,-a后面是命令。当然我们也可以直接写一个IP,针对某一台机器来执行命令。

[root@ansible-test1 ~]# ansible testhost -m command -a "hostname"

127.0.0.1 | CHANGED | rc=0 >>

ansible-test1

192.168.2.20 | CHANGED | rc=0 >>

ansible-test2

[root@ansible-test1 ~]# ansible 192.168.2.20 -m command -a "hostname"

192.168.2.20 | CHANGED | rc=0 >>

ansible-test2

2.4 Ansible拷贝文件或目录

源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,如果dest指定的名字和源不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果desc是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面。

[root@ansible-test1 ~]# ansible 192.168.2.20 -m copy -a "src=/etc/passwd

dest=/tmp/123"

192.168.2.20 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "checksum": "8f3ebea24b1558e6207af80195aa12931d96345f",

    "dest": "/tmp/123",

    "gid": 0,

    "group": "root",

    "md5sum": "ca8f3327c9a73cb6fd96ba88ec4d18ee",

    "mode": "0644",

    "owner": "root",

    "secontext": "unconfined_u:object_r:admin_home_t:s0",

    "size": 1040,

    "src": "/root/.ansible/tmp/ansible-tmp-1593856449.24-11462-53060923085626/source",

    "state": "file",

    "uid": 0

}

这里的/tmp/123和源机器上的/etc/passwd是一致的,但如果目标机器上已经有/tmp/123目录,则会再/tmp/123目录下面建立passwd文件。

2.5 Ansible远程执行脚本

首先创建一个shell脚本。

[root@ansible-test1 ~]# cat /tmp/test.sh

#!/bin/bash

echo `date` > /tmp/ansible_test.txt

然后把该脚本分发到各个机器上。

[root@ansible-test1 ~]# ansible testhost -m copy -a "src=/tmp/test.sh

dest=/tmp/test.sh

mode=0755"

192.168.2.20 | 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",

    "secontext": "unconfined_u:object_r:admin_home_t:s0",

    "size": 48,

    "src": "/root/.ansible/tmp/ansible-tmp-1593856700.7-11499-220274653312920/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",

    "secontext": "unconfined_u:object_r:user_tmp_t:s0",

    "size": 48,

    "state": "file",

    "uid": 0

}

最后是批量执行该shell脚本。

[root@ansible-test1 ~]# ansible testhost -m shell -a "/tmp/test.sh"

127.0.0.1 | CHANGED | rc=0 >>

 

192.168.2.20 | CHANGED | rc=0 >>

 

shell模块,还支持远程执行命令并且带管道。

[root@ansible-test1 ~]# ansible testhost -m shell -a "cat /etc/passwd |wc -l "

127.0.0.1 | CHANGED | rc=0 >>

21

192.168.2.20 | CHANGED | rc=0 >>

21

[root@ansible-test1 ~]# cat /tmp/ansible_test.txt //

2020年 07月 04日 星期六 18:00:51 CST

运行成功。

2.6 Ansible管理任务计划

创建任务计划,命名并定义工作。

[root@ansible-test1 ~]# ansible testhost -m cron -a "name='test cron'

job='/bin/bash

/tmp/test.sh' weekday=6"

127.0.0.1 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "envs": [],

    "jobs": [

        "test cron"

    ]

}

192.168.2.20 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "envs": [],

    "jobs": [

        "test cron"

    ]

}

若要删除该cron只需要加一个字段state=absent。

[root@ansible-test1 ~]# 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.2.20 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "envs": [],

    "jobs": []

}

其他的时间表示——分钟:minute;小时:hour;日期:day;月份:month。

2.7 Ansible安装RPM包/管理服务

使用Yum模块安装httpd服务。

[root@ansible-test1 ~]# ansible testhost -m yum -a "name=httpd"

127.0.0.1 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "changes": {

        "installed": [

            "httpd"

        ]

    },

    "msg": "",

    "rc": 0,

    "results": [

        …

… 

\n\nComplete!\n"

    ]

}

192.168.2.20 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "changes": {

        "installed": [

            "httpd"

        ]

    },

    "msg": "",

    "rc": 0,

    "results": [

        …

\n\nComplete!\n"

    ]

}

在name后面还可以加上state=installed/removed。

设置服务状态,这里的name是CentOS系统里的服务名,可以通过chkconfig –list命令查到。

[root@ansible-test1 ~]# ansible testhost -m service -a "name=httpd state=started

enabled=yes"

127.0.0.1 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "enabled": true,

    "name": "httpd",

    "state": "started",

    "status": {

        …

        "WatchdogTimestampMonotonic": "0",

        "WatchdogUSec": "0"

    }

}

192.168.2.20 | CHANGED => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": true,

    "enabled": true,

    "name": "httpd",

    "state": "started",

    "status": {

       …

        "WatchdogUSec": "0"

    }

}

Ansible文档的使用:

[root@ansible-test1 ~]# 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-test1 ~]# 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使用

3.1 ansible playbook中的使用

相当于把模块写入到配置文件里面,例:

[root@ansible-test1 ansible]# cat /etc/ansible/test.yml

---

- hosts: 192.168.2.20

  remote_user: root

  tasks:

  - name: test_playbook

shell: touch /tmp/playbook_test.txt

说明:第一行需要有三个杠,hosts参数指定了对哪些主机进行参作,如果是多台机器可以用逗号作为分隔,也可以使用主机组,在/etc/ansible/hosts里定义,user参数指定了使用什么用户登录远程主机操作,tasks指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来,shell是ansible模块名字

 [root@ansible-test1 ansible]# ansible-playbook test.yml

 

PLAY [192.168.2.20] ***********************************************************************************************

 

TASK [Gathering Facts] ********************************************************************************************

ok: [192.168.2.20]

 

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

 

PLAY RECAP ********************************************************************************************************

192.168.2.20               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

再来一个创建用户的例子:

 [root@ansible-test1 ansible]# cat create_user.yml

---

- name: create_user

  hosts: 192.168.2.20

  user: root

  gather_facts: false

  vars:

    - user: "test"

  tasks:

    - name: create user

      user: name="{{ user }}"

说明:name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值 ,可以省略;gather_facts参数指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时用到;vars参数,指定了变量,这里指字一个user变量,其值为test ,需要注意的是,变量值一定要用引号引住;user提定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。

[root@ansible-test1 ansible]# ansible-playbook create_user.yml

 

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

 

TASK [create user] ************************************************************************************************

changed: [192.168.2.20]

 

PLAY RECAP ********************************************************************************************************

192.168.2.20               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.2 ansible playbook中的循环

创建while.yml文件

[root@ansible-test1 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-test1 ansible]# ansible-playbook while.yml

 

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

 

TASK [Gathering Facts] ********************************************************************************************

ok: [127.0.0.1]

ok: [192.168.2.20]

 

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.2.20               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.3 ansible playbook中的条件判断

创建when.yml文件。

[root@ansible-test1 ansible]# cat 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.2.20"

说明:ansible anisble-02 -m setup 可以查看到所有的facter信息

执行when.yml。

[root@ansible-test1 ansible]# ansible-playbook when.yml

 

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

 

TASK [Gathering Facts] ********************************************************************************************

ok: [127.0.0.1]

ok: [192.168.2.20]

 

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

 

PLAY RECAP ********************************************************************************************************

127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  

192.168.2.20               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.4 ansible playbook中的handlers

执行task之后,服务器发生变化之后要执行的一些操作,比如我们修改了配置文件后,需要重启一下服务,创建handlers.yml文件加入如下内容

[root@ansible-test1 ansible]# cat handlers.yml

---

- name: handlers test

  hosts: 192.168.2.20

  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

说明,只有copy模块真正执行后,才会去调用下面的handlers相关的操作。也就是说如果1.txt和2.txt内容是一样的,并不会去执行handlers里面的shell相关命令。 这种比较适合配置文件发生更改后,重启服务的操作。

[root@ansible-test1 ansible]# ansible-playbook handlers.yml

 

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

 

TASK [Gathering Facts] ********************************************************************************************

ok: [192.168.2.20]

 

TASK [copy file] **************************************************************************************************

changed: [192.168.2.20]

 

RUNNING HANDLER [test handlers] ***********************************************************************************

changed: [192.168.2.20]

 

PLAY RECAP ********************************************************************************************************

192.168.2.20               : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ansible playbook实战

4.1 ansible自动化安装nginx

(1)编译安装nginx

1)使用wget下载nginx包,下载地址:

http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz

2)解压下载的nginx包

./configure --prefix=/usr/local/nginx

make && make install

3)编写/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

4)清空配置文件并重新编写

# > /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 $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压缩输出

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;

}

}

}

5)编写完成后可以检查一下

# /usr/local/nginx/sbin/nginx -t

6)启动nginx

# service nginx start

编译安装完成

(2)环境准备

1)将nginx.tar.gz复制到/etc/ansible/nginx_install/roles/install/files下

启动脚本和配置文件都放到/etc/ansible/nginx_install/roles/install/template下

# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/

# cp nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/

# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/

2)编写需要的yml文件

[root@ansible2 nginx_install]# cat install.yml

---

- hosts: 192.168.2.101            //入口文件

  remote_user: root

  gather_facts: True

  roles:

    - common

    - install

[root@ansible2 nginx_install]# cat roles/common/tasks/main.yml

- name: install initialization require software  //安装需要的依赖

  yum: name={{ item }} state=installed

  with_items:         

    - zlib-devel

    - pcre-devel

    - gcc

[root@ansible2 nginx_install]# cat roles/install/vars/main.yml

nginx_user: www            //定义所需变量

nginx_port: 80

nginx_basedir: /usr/local/nginx

[root@ansible2 nginx_install]# cat 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          //复制nginx配置文件

  template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root

mode=0644

[root@ansible2 nginx_install]# cat roles/install/tasks/install.yml

- name: create nginx user //创建用户

  user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin

- name: start nginx service     //开启服务

  shell: /etc/init.d/nginx start

- name: add boot start nginx service    //加入开机启动

  shell: chkconfig --level 345 nginx on

- name: delete nginx compression files //删除压缩包

  shell: rm -rf /tmp/nginx.tar.gz

[root@ansible2 nginx_install]# cat roles/install/tasks/main.yml

- include: copy.yml  //调用copy.yml和install.yml

- include: install.yml

(3)执行文件

运行install.yml文件

# ansible-playbook /etc/ansible/nginx_install/install.yml

注:要检查远程机器存在端口占用,及时卸载。

结果如下:

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

 

PLAY [192.168.2.31] ****************************************************************************************************

 

TASK [Gathering Facts] *************************************************************************************************

  • ok: [192.168.2.31]

 

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.2.31] => (item=[u'zlib-devel', u'pcre-devel'])

 

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

changed: [192.168.2.31]

 

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

 

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

  • ok: [192.168.2.31]

 

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

  • ok: [192.168.2.31]

 

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

  • ok: [192.168.2.31]

 

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

changed: [192.168.2.31]

 

TASK [install : Add Boot start Nginx service] **************************************************************************

changed: [192.168.2.31]

 

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

 

PLAY RECAP *************************************************************************************************************

192.168.2.31               : ok=10   changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

4.2 管理配置文件

生产环境中大多时候是需要管理配置文件的,安装软件包只是在初始化环境的时候用一下。下面我们来写个管理nginx配置文件的playbook。

[root@ansible2nginx_config]#cat

/etc/ansible/nginx_config/roles/new/handlers/main.yml

- name: restart nginx //用于重新加载nginx服务

  shell: /etc/init.d/nginx reload

[root@ansible2nginx_config]# cat /etc/ansible/nginx_config/roles/new/tasks/main.yml

- name: copy conf file     //复制.conf和hosts文件

  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@ansible2 nginx_config]# cat /etc/ansible/nginx_config/roles/new/vars/main.yml

nginx_basedir: /usr/local/nginx    //定义变量

[root@ansible2 nginx_config]# cat update.yml

---

- hosts: 192.168.2.101     //入口文件

  user: root

  roles:

  - new              //这里只有new

old目录中的yml文件与new目录中的相同,files中的配置文件不同。

其中new为更新时用到的,old为回滚时用到的,files下面为nginx.conf和vhosts目录,handlers为重启nginx服务的命令

在执行update.yml前,应备份当前配置文件,当执行之后发现错误,则进行回滚操作。关于回滚,需要在执行playbook之前先备份一下旧的配置,所以对于老配置文件的管理一定要严格,千万不能随便去修改线上机器的配置,并且要保证new/files下面的配置和线上的配置一致,命令如下:

# rsync -av /etc/ansible/nginx_config/roles/new/

/etc/ansible/nginx_config/roles/old/

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

更新操作结果:

[root@ansible-01 nginx_config]# ansible-playbook

/etc/ansible/nginx_config/update.yml

 

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

 

TASK [Gathering Facts] *************************************************************************************************

  • ok: [192.168.2.31]
  • ok: [127.0.0.1]

 

TASK [new : copy conf file] ********************************************************************************************

  • ok: [192.168.2.31] => (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.2.31] => (item={u'dest': u'conf/', u'src': u'vhosts'})

 

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

changed: [192.168.2.31]

 

PLAY RECAP *************************************************************************************************************

127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

192.168.2.31               : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

回滚操作结果:

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

 

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

 

TASK [Gathering Facts] *************************************************************************************************

  • ok: [192.168.2.31]
  • ok: [127.0.0.1]

 

TASK [old : copy conf file] ********************************************************************************************

  • ok: [192.168.2.31] => (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: [192.168.2.31] => (item={u'dest': u'conf/', u'src': u'vhosts'})
  • ok: [127.0.0.1] => (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.2.31               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

注:本次实验并未改变配置文件,故changed为0。

posted @ 2021-07-08 10:30  渝怀。  阅读(136)  评论(0编辑  收藏  举报