ansible介绍、安装、远程执行命令、拷贝文件或目录、远程执行脚本、管理任务计划、安装包和管理服务、playbook、变量、循环、条件判断、handlers、安装nginx、管理配置文件,


24.15 ansible介绍

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供
一种框架。主要包括:

  • 连接插件connection plugins:负责和被监控端实现通信;
  • host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
  • 各种模块核心模块、command模块、自定义模块;
  • 借助于插件完成记录日志邮件等功能;
  • playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

ansible特点:

  • 不需要安装客户端,通过sshd去通信

  • 基于模块工作,模块可以由任何语言开发

  • 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读

  • 安装十分简单,centos上可直接yum安装

  • 有提供UI(浏览器图形化)www.ansible.com/tower , 收费的

  • ansible官网:https://www.ansible.com/

  • ansible官方文档地址:http://docs.ansible.com/ansible/latest/index.html

  • ansible在github地址:https://github.com/ansible/ansible

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

24.16 ansible安装

环境:

192.168.222.114 server
192.168.222.113 client

安装:

只需要在服务端上安装ansible:yum install -y ansible

[root@server ~]# yum list |grep ansible   # 可以看到自带源里就有2.4版本的ansible
ansible.noarch                              2.4.2.0-2.el7              extras   
ansible-doc.noarch                          2.4.2.0-2.el7              extras   
[root@server ~]# yum install -y ansible

使用ssh-keygen命令生成密钥对:

[root@server ~]# cd .ssh/
[root@server .ssh]# ssh-keygen -t rsa # -t指定密钥类型
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
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:
SHA256:QfYYQO7KFX3lvBa8X/bUKzB0Nz71soQjF9Ri079pEbo root@server
The key's randomart image is:
+---[RSA 2048]----+
|     .o.+   oo   |
|     . + + *+ o. |
|      o + oo*+.+o|
|     . . o. .Bo.*|
|      o S .oB +oX|
|   . o     +oE X+|
|    o        .+..|
|              .  |
|                 |
+----[SHA256]-----+
  • 建立服务端与客户端的连接,也就是配置密钥认证的SSH连接:
[root@server .ssh]# ssh-copy-id root@192.168.222.113   # 拷贝ssh key到客户端
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/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.222.113's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.222.113'"
and check to make sure that only the key(s) you wanted were added.

设置ssh的时候不会提示是否保存key

[root@server .ssh]# ssh-keyscan 192.168.222.113 >> ~/.ssh/known_hosts
# 192.168.222.113:22 SSH-2.0-OpenSSH_7.4
# 192.168.222.113:22 SSH-2.0-OpenSSH_7.4
# 192.168.222.113:22 SSH-2.0-OpenSSH_7.4

测试在服务端上能否通过密钥登录客户端

[root@server .ssh]# ssh root@192.168.222.113
Last login: Fri Oct 19 13:54:13 2018 from 192.168.222.1
[root@client ~]# logout
Connection to 192.168.222.113 closed

编辑服务端上的配置文件,配置远程主机组:

[root@server ~]# vim /etc/ansible/hosts  # 在文件末尾增加以下内容
[testhost]  # 主机组的名称,可自定义,以下的ip为该组内机器的ip
192.168.222.113

24.17 ansible远程执行命令

完成了ssh密钥认证以及主机组的配置之后就可以通过ansible对客户端远程执行命令

通过主机组执行:

[root@server ~]# ansible testhost -m command -a 'w'  
192.168.222.113 | SUCCESS | rc=0 >>
 15:54:52 up  2:01,  2 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.222.1    13:54   32:52   0.04s  0.04s -bash
root     pts/1    192.168.222.114  15:54    0.00s  0.13s  0.01s w

[root@server ~]# ansible testhost -m command -a 'hostname'
192.168.222.113 | SUCCESS | rc=0 >>
client

通过IP地址执行:

[root@server ~]# ansible 192.168.222.113 -m command -a 'hostname'
192.168.222.113 | SUCCESS | rc=0 >>
client

注:

  • ansible 后面跟的是需要远程执行命令的机器,可以是一个主机组,可以是某个指定的ip或者主机名,如果使用主机名的话,需要先配置hosts
  • -m选项用于指定使用某个模块,在这里我们指定的是command 模块,这个模块可以用于远程执行命令
  • -a选项用于指定需要执行的命令,命令需要用单引号引起来

除了使用command模块外,还可以使用shell模块来实现远程执行命令

[root@server ~]# ansible testhost -m shell -a 'w'
192.168.222.113 | SUCCESS | rc=0 >>
 15:59:36 up  2:06,  2 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.222.1    13:54   37:36   0.04s  0.04s -bash
root     pts/1    192.168.222.114  15:59    0.00s  0.07s  0.01s w

command与shell的区别:command模块是用于执行单条命令;而shell模块可以用于执行单条命令,也可以用于执行脚本。

24.18 ansible拷贝文件或目录

拷贝目录:

[root@server ~]# ansible testhost -m copy -a "src=/etc/ansible  dest=/tmp/ansibletest owner=root
group=root mode=0755"
192.168.222.113 | SUCCESS => {
    "changed": true,
    "dest": "/tmp/ansibletest/",
    "src": "/etc/ansible"
}

注:

  • src指定来源目录路径
  • dest指定目标机器存储该目录的路径
  • owner指定目录的属主
  • group指定目录的属组
  • mode指定目录的权限

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

查看客户端拷贝的目录:

[root@client ~]#  ls /tmp/ansibletest
ansible
[root@client ~]# ls /tmp/ansibletest/ansible/
ansible.cfg  hosts  roles

拷贝文件:

[root@server ~]# ansible testhost -m copy -a "src=/etc/passwd dest=/tmp/passwd"
192.168.222.113 | SUCCESS => {
    "changed": true,
    "checksum": "7b95e8a3e5794f00aab8721e93bcd504a18aa0a0",
    "dest": "/tmp/passwd",
    "gid": 0,
    "group": "root",
    "md5sum": "92191c868c0df95d909fa2983ee0eb9c",
    "mode": "0644",
    "owner": "root",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 846,
    "src": "/root/.ansible/tmp/ansible-tmp-1539936535.44-243048400644709/source",
    "state": "file",
    "uid": 0
}

注:
src指定来源目录路径
dest指定目标机器存储该目录的路径

与拷贝目录同理,如果目标机器上存在一个/tmp/passwd目录,则会在/tmp/passwd目录下面创建passwd文件。

查看客户端接收文件:

[root@client ~]# ll /tmp/passwd
-rw-r--r--. 1 root root 846 10月 19 16:08 /tmp/passwd

24.19 ansible远程执行脚本

服务端上创建shell脚本测试:

[root@server ~]# vim  /tmp/test.sh  #添加脚本内容
#!/bin/bash
echo `date` > /tmp/ansible_test.txt

脚本分发到远程机器上:

[root@server ~]# ansible testhost -m copy -a "src=/tmp/test.sh dest=/tmp/test.sh mode=0755"
192.168.222.113 | SUCCESS => {
    "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-1539936986.48-59618023407009/source",
    "state": "file",
    "uid": 0
}

注:
脚本文件需要给755的权限,不然无法被直接执行。

通过shell模块执行远程机器上的shell脚本:

[root@server ~]# ansible testhost -m shell -a "/tmp/test.sh"
192.168.222.113 | SUCCESS | rc=0 >>

查看客户端是否执行:

[root@client ~]# cat /tmp/ansible_test.txt
2018年 10月 19日 星期五 16:19:33 CST

除此之外shell模块可以使用管道符,而command模块则不支持使用管道符:

[root@server ~]# ansible testhost -m shell -a "cat /etc/passwd|wc -l"
192.168.222.113 | SUCCESS | rc=0 >>
21

24.20 ansible管理任务计划

使用cron模块来管理任务计划:

[root@server ~]# ansible testhost -m cron -a "name='test cron' job='/bin/touch /tmp/ansible_cron.txt'  

weekday=1"
192.168.222.113 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron"
    ]
}
[root@server ~]#

注:

  • name指定一个名称,用于作为标识符,会出现在crontab的注释里
  • job指定需要执行的命令
  • weekday表示星期;其他没有设置的时间位默认为 *

客户端查看执行命令:

[root@client ~]# crontab -l
# Lines below here are managed by Salt, do not edit
#Ansible: test cron
* * * * 1 /bin/touch /tmp/ansible_cron.txt

删除该cron ,只需要加一个字段 state=absent:

[root@server ~]# ansible testhost -m cron -a "name='test cron' state=absent"
192.168.222.113 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": []
}

客户端查看执行命令:

[root@client ~]# crontab -l
# Lines below here are managed by Salt, do not edit
[root@client ~]#

表示时间位的字段:

  • minute 分钟
  • hour 小时
  • day 日期
  • month 月份
  • weekday 周

24.21 ansible安装包和管理服务

给客户端安装httpd服务

[root@server ~]# ansible testhost -m yum -a "name=httpd"
192.168.222.113 | SUCCESS => {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "httpd-2.4.6-80.el7.centos.1.x86_64 providing httpd is already installed"
    ]
}

启动httpd服务:(第一句为SUCCESS则代表启动成功)

[root@server ~]# ansible testhost -m service -a "name=httpd state=started enabled=yes"
192.168.222.113 | SUCCESS => {

注:
这里的name是centos系统里的服务名,可以通过chkconfig --list查看到。

其它控制服务的命令:

停止服务

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

重新启动服务

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

重载服务

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

卸载服务

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

注:在name后面还可以加上state=installed或removed,加上removed的话,表示卸载这个服务,如果不指定state的值默认是installed;

查看卸载状态:

[root@client ~]# rpm -qa httpd
[root@client ~]#
  • ansible-doc -l : 列出所有的模块
  • ansible-doc cron :查看指定模块的文档

24.22 ansible-playbook

  • Playbooks 是 Ansible的配置,部署,编排语言.他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合.
  • 如果 Ansible 模块你是工作室中的工具,那么 playbooks 就是你设置的方案计划.
  • Playbooks 的格式是YAML。
  • playbook相当于可以把模块命令都写入到配置文件,就可以直接执行,类似于脚本;
[root@server ~]# vim /etc/ansible/test.yml
---
- hosts: testhost                    //针对testhost主机,若果多个主机,可以用逗号隔开
  remote_user: root                  //远程用户为root
  tasks:                             //任务
    - name: test_playbook            //任务名 test_playbook
      shell: touch /tmp/test.txt     //用到shell模块

playbook格式:

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

执行文件:ansible-playbook

[root@server ~]# ansible-playbook /etc/ansible/test.yml

PLAY [testhost]

********************************************************************************************************

TASK [Gathering Facts]

*************************************************************************************************
ok: [192.168.222.113]

TASK [test_playbook]

***************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.222.113]

PLAY RECAP

**********************************************************************************************************

***
192.168.222.113            : ok=2    changed=1    unreachable=0    failed=0   

客户端验证:

[root@client ~]# ls -l /tmp/test.txt
-rw-r--r--. 1 root root 0 10月 22 16:05 /tmp/test.txt
[root@client ~]#

24.23 playbook的变量

例:创建用户

[root@server ~]# vim /etc/ansible/create_user.yml  # 编辑内容如下
---
- name: create_user
  hosts: testhost
  user: root
  gather_facts: false
  vars:
    - user: "test"
  tasks:
    - name: create user
      user: name="{{ user }}"

注:

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

执行:

[root@server ~]# ansible-playbook /etc/ansible/create_user.yml

PLAY [create_user]

*****************************************************************************************************

TASK [create user]

*****************************************************************************************************
changed: [192.168.222.113]

PLAY RECAP

**********************************************************************************************************

***
192.168.222.113            : ok=1    changed=1    unreachable=0    failed=0

注:如果test用户已经存在,输出显示绿色,changed=0;

客户端查看:

[root@client ~]# id test
uid=1000(test) gid=1000(test) 组=1000(test)

24.24 playbook的循环

创建:

[root@server ~]# vim /etc/ansible/while.yml
---
- hosts: testhost
  user: root
  tasks:
    - name: change mode for files
      file: path=/tmp/{{ item }} state=touch mode=600
      with_items:
        - 1.txt
        - 2.txt
        - 3.txt

注:

  • file模块可以对文件进行相关的操作,例如创建文件或者更改文件权限等,具体可以查看该模块的文档
  • with_items为循环的对象,相当于是一个数组或集合,写在下面的1.txt、2.txt以及3.txt是该集合的元素。而item则表示的是遍历出来的元素,也就是说item指代的是1.txt、2.txt以及3.txt。
  • state的值设置为touch表示如果该文件不存在就进行创建
  • path表示文件的路径
  • mode设置权限

执行:

[root@server ~]# ansible-playbook /etc/ansible/while.yml

PLAY [testhost]

********************************************************************************************************

TASK [Gathering Facts]

*************************************************************************************************
ok: [192.168.222.113]

TASK [change mode for files]

*******************************************************************************************
changed: [192.168.222.113] => (item=1.txt)
changed: [192.168.222.113] => (item=2.txt)
changed: [192.168.222.113] => (item=3.txt)

PLAY RECAP

**********************************************************************************************************

***
192.168.222.113            : ok=2    changed=1    unreachable=0    failed=0   

查看:

[root@client ~]# ll /tmp/*.txt
-rw-------. 1 root root 0 11月 22 10:28 /tmp/1.txt
-rw-------. 1 root root 0 11月 22 10:28 /tmp/2.txt
-rw-------. 1 root root 0 11月 22 10:28 /tmp/3.txt

24.25 playbook的条件判断

查看到setup收集到的所有的facter信息:

ansible testhost -m setup

编辑条件:

[root@server ~]# vim /etc/ansible/when.yml
---
- hosts: testhost
  user: root
  gather_facts: True
  tasks:
    - name: use when
      shell: touch /tmp/when.txt
      when: ansible_ens33.ipv4.address == "192.168.222.113"

注:
when: ansible_ens33是一个数组存储着网卡相关信息,ipv4属于该数组的子元素,但是ipv4也是一个数组,而address则是ipv4数组的子元素。我们需要使用address 来作为判断条件。所以要访问address就需要使用这样的格式:
when: ansible_ens33.ipv4.address,address表示的是键,而"192.168.222.113"则是值,when为判断语句相当于if,所以其判断条件为:该键的值为"192.168.222.113"时就执行shell模块里定义的语句。

执行:

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

PLAY [testhost]

********************************************************************************************************

TASK [Gathering Facts]

*************************************************************************************************
ok: [192.168.222.113]

TASK [use when]

********************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.222.113]

PLAY RECAP

**********************************************************************************************************

***
192.168.222.113            : ok=2    changed=1    unreachable=0    failed=0   

查看:

[root@client ~]# ll /tmp/when.txt
-rw-r--r--. 1 root root 0 11月 22 11:21 /tmp/when.txt

24.26 playbook中的handlers

使用环境:当执行了tasks里面的内容之后,服务器发生了变化,这时可能需要执行一些相关的操作;相当于编程中的回调函数;例如:修改了某个服务的配置文件后,则需要重启一下服务,当任务执行成功,handlers执行完成重启;否则不执行;类似于shell脚本中的&&符号;

创建:

[root@server ~]# vim /etc/ansible/handlers.yml
---
- name: handlers test
  hosts: testhost
  user: root
  tasks:
    - name: copy file
      copy: src=/etc/passwd dest=/tmp/test_passwd.txt
      notify: test handlers
  handlers:
    - name: test handlers
      shell: echo "1234567890" >> /tmp/test_passwd.txt

注:

  • 只有copy模块执行成功后,才会去调用下面的handlers里定义的内容。也就是说如果/etc/passw和/tmp/test_passwd.txt内容是一样的话,就不会去执行handlers里面的shell相关命令,因为copy没有被执行。 这种比较适合配置文件发生更改后,重启服务的操作。
  • notify用于指定handlers的name参数的值,因为handlers可以定义多个,所以需要使用notify来进行指定调用哪一个

执行:

[root@server ~]# ansible-playbook /etc/ansible/handlers.yml

PLAY [handlers test]

***************************************************************************************************

TASK [Gathering Facts]

*************************************************************************************************
ok: [192.168.222.113]

TASK [copy file]

*******************************************************************************************************
changed: [192.168.222.113]

RUNNING HANDLER [test handlers]

****************************************************************************************
changed: [192.168.222.113]

PLAY RECAP

**********************************************************************************************************

***
192.168.222.113            : ok=3    changed=2    unreachable=0    failed=0   

查看:

[root@client ~]# tail -n1 /tmp/test_passwd.txt
1234567890

24.27/24.28 playbook安装nginx

思路:先在一台机器上编译安装好nginx、打包,然后再用ansible 分发到远程机器上。

在ansible配置目录下,创建一个nginx_install目录;
[root@server ~]# cd /etc/ansible
[root@server ansible]# mkdir nginx_install
[root@server ansible]# cd nginx_install
[root@server nginx_install]# mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
[root@server nginx_install]#  ls roles/
common  install
[root@server nginx_install]# ls roles/install/
files  handlers  meta  tasks  templates  vars
[root@server nginx_install]# ls roles/common/
files  handlers  meta  tasks  templates  vars

说明:
roles目录下有两个角色,common为一些准备操作,install为安装nginx的操作。每个角色下面又有几个目录,handlers下面是当发生改变时要执行的操作,通常用在配置文件发生改变,重启服务。files为安装时用到的一些文件,meta为说明信息,说明角色依赖等信息,tasks里面是核心的配置文件,templates通常存一些配置文件,启动脚本等模板文件,vars下为定义的变量;

准备安装需要用到的文件:

  • 在一台机器上事先编译安装好nginx,配置好启动脚本,配置好配置文件
  • 安装好后,我们需要把nginx目录打包,并放到/etc/ansible/nginx_install/roles/install/files/下面,名字为:nginx.tar.gz
  • 启动脚本、配置文件都要放到/etc/ansible/nginx_install/roles/install/templates下面

编译安装:

[root@server ~]# ls /usr/local/
bin  etc  games  include  lib  lib64  libexec  nginx  sbin  share  src
[root@server ~]# ls /usr/local/nginx/
client_body_temp  conf  fastcgi_temp  html  logs  nginx.conf  proxy_temp  sbin  scgi_temp  uwsgi_temp

把nginx目录打包,并放到files下面,以及把启动脚本、配置文件放到templates下面:

[root@server ~]# cd /usr/local/
[root@server local]# tar -czvf nginx.tar.gz --exclude "nginx.conf" --exclude "vhost" nginx/
[root@server local]# mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/
[root@server local]# cp nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
[root@server local]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/

定义common的tasks,因为nginx是需要一些依赖包的:

[root@server local]# cd  /etc/ansible/nginx_install/roles
[root@server roles]# vim  ./common/tasks/main.yml
- name: Install initializtion require software
  yum: name="zlib-devel,pcre-devel" state=installed

定义变量:

[root@server roles]# vim install/vars/main.yml
nginx_user: www
nginx_port: 80
nginx_basedir: /usr/local/nginx

然后要把所有用到的文档拷贝到目标机器:

[root@server roles]# vim install/tasks/copy.yml
- name: Copy Nginx Software   # 拷贝nginx包
  copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root
- name: Uncompression Nginx Software  # 解压nginx包
  shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/
- name: Copy Nginx Start Script  # 拷贝nginx的启动脚本
  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

注:这里src参数指定的是相对路径,这个相对路径相对的是模块,例如copy模块里的src参数的值为nginx.tar.gz,那么就会去files目录下找nginx.tar.gz,而template模块则是会去templates目录下找。

建立用户,启动服务,删除压缩包:

[root@server roles]# vim install/tasks/install.yml

  • name: Create Nginx User # 创建nginx用户
    user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin
  • name: Start Nginx Service # 启动nginx服务
    shell: /etc/init.d/nginx start
  • name: Add Boot Start Nginx Service # 将nginx服务添加到开机启动列表
    shell: chkconfig --level 345 nginx on
  • name: Delete Nginx compression files # 删除nginx的压缩包
    shell: rm -rf /tmp/nginx.tar.gz

注:nginx_user变量是之前我们在vars目录下的main.yml文件中定义的,所以在这里可以直接引用。

再创建一个总体的main.yml,在这个文件里对copy.yml以及install.yml进行一个调用

[root@server roles]# vim install/tasks/main.yml
- include: copy.yml
- include: install.yml

到此两个roles:common和install就定义完成了,接下来要定义一个作为总入口的配置文件:

[root@server nginx_install]# vim install.yml
---
- hosts: testhost
  remote_user: root
  gather_facts: True
  roles:
    - common
    - install

注意:接着就是需要执行这个总入口文件了,但是如果你的目标机器之前安装过nginx需要先清理掉,不然可能会有冲突:

编译安装的清理办法:(find / -name "nginx*" -exec rm -rf {} \;)
yum安装的清理办法:rpm -qa nginx    yum remove -y nginx

执行这个总入口文件:

[root@server ~]# ansible-playbook /etc/ansible/nginx_install/install.yml
[DEPRECATION WARNING]: The use of 'include' for tasks has been deprecated. Use 'import_tasks' for static inclusions or
'include_tasks' for dynamic inclusions. This feature will be removed in a future release. Deprecation warnings can be
disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: include is kept for backwards compatibility but usage is discouraged. The module documentation
details page may explain more about this rationale.. This feature will be removed in a future release. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

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

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

TASK [common : Install initializtion require software] *****************************************************************
changed: [192.168.222.113]

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

TASK [install : Uncompression Nginx Software] **************************************************************************
 [WARNING]: Consider using unarchive module rather than running tar

changed: [192.168.222.113]

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

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

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

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

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

TASK [install : Delete Nginx compression files] ************************************************************************
 [WARNING]: Consider using file module with state=absent rather than running rm

changed: [192.168.222.113]

PLAY RECAP *************************************************************************************************************
192.168.222.113            : ok=10   changed=9    unreachable=0    failed=0

查看进程及监听端口:

[root@client ~]# ps aux |grep nginx
root      3847  0.0  0.0  20492   612 ?        Ss   16:06   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody    3848  0.0  0.1  20932  1332 ?        S    16:06   0:00 nginx: worker process
root      3964  0.0  0.0 112676   980 pts/0    S+   16:08   0:00 grep --color=auto nginx
[root@client ~]# netstat -lntp |grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3847/nginx: master

安装完成。

24.29/24.30 playbook管理配置文件

生产环境中大多时候是需要管理配置文件的,例如修改配置文件然后进行重启服务,修改配置文件时可能会出现误修改的情况,所以我们还需要准备一个回滚的操作。至于安装软件包只是在初始化环境的时候用一下。下面我们来写个管理nginx配置文件的playbook。

创建相应的目录:

[root@server ~]# mkdir -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
[root@server ~]# cd /etc/ansible/nginx_config/
[root@server nginx_config]# ls
roles
[root@server nginx_config]# ls roles/
new  old
[root@server nginx_config]# ls roles/new/
files  handlers  tasks  vars
[root@server nginx_config]# ls roles/old/
files  handlers  tasks  vars

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

注:
关于回滚,需要在执行playbook之前先备份一下旧的配置,所以对于老配置文件的管理一定要严格,千万不能随便去修改线上机器的配置,并且要保证new/files下面的配置和线上的配置一致

把nginx.conf和vhost目录放到files目录下面:

[root@server nginx_config]# cd /usr/local/nginx/conf/
[root@server conf]# ls
fastcgi.conf          fastcgi_params.default  mime.types          nginx.conf.default   uwsgi_params
fastcgi.conf.default  koi-utf                 mime.types.default  scgi_params          uwsgi_params.default
fastcgi_params        koi-win                 nginx.conf          scgi_params.default  win-utf
[root@server conf]# cp -r nginx.conf /etc/ansible/nginx_config/roles/new/files/

编辑定义变量的文件:

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

编辑用于定义重新加载nginx服务的文件:

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

编辑用于执行核心任务的文件:

[root@server ~]# vim /etc/ansible/nginx_config/roles/new/tasks/main.yml
- name: copy conf file
  copy: src={{ item.src }} dest={{ nginx_basedir }}/{{ item.dest }} backup=yes owner=root group=root mode=0644
  with_items:
    - { src: nginx.conf, dest: conf/nginx.conf }
    - { src: vhost, dest: conf/ }
  notify: restart nginx

最后是定义总入口配置文件:

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

执行总入口配置文件:

[root@server ~]# ansible-playbook /etc/ansible/nginx_config/update.yml
[root@server ~]# ansible-playbook /etc/ansible/nginx_config/update.yml

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

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

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

PLAY RECAP *************************************************************************************************************
192.168.222.113            : ok=2    changed=0    unreachable=0    failed=0  

回滚操作:
回滚对应的roles为old,所以首先把new目录下的所有文件同步到old目录下,这一步相当于是备份一份在old目录下,之后回滚就是从old目录下进行拷贝文件:

[root@server ~]# rsync -av  /etc/ansible/nginx_config/roles/new/ /etc/ansible/nginx_config/roles/old/
sending incremental file list
files/
files/nginx.conf
handlers/
handlers/main.yml
tasks/
tasks/main.yml
vars/
vars/main.yml

sent 3,423 bytes  received 108 bytes  7,062.00 bytes/sec
total size is 2,965  speedup is 0.84

回滚操作就是把旧的配置覆盖,然后重新加载nginx服务,每次改动nginx配置文件之前先备份到old里,对应目录为/etc/ansible/nginx_config/roles/old/files。如果你修改nginx配置文件之前没有备份old里,那么你就无法进行回滚操作了。

编辑总入口配置文件:

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

例:修改Nginx配置文件,在文件末尾增加一行注释

增加注释前先将配置文件同步到old目录下:

[root@server ~]# rsync -av  /etc/ansible/nginx_config/roles/new/files/nginx.conf /etc/ansible/nginx_config/roles/old/files/nginx.conf 
sending incremental file list

sent 49 bytes  received 12 bytes  122.00 bytes/sec
total size is 2,656  speedup is 43.54

增加注释:

[root@server ~]# vim /etc/ansible/nginx_config/roles/new/files/nginx.conf
#1234567890  /(最后一行增加注释)

执行update.yml文件向客户端更新文件:

[root@server ~]# ansible-playbook /etc/ansible/nginx_config/update.yml

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

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

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

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

PLAY RECAP *************************************************************************************************************
192.168.222.113            : ok=3    changed=2    unreachable=0    failed=0  

到客户端上查看是否有增加的注释:
[root@client ~]# tail -n2 /usr/local/nginx/conf/nginx.conf
    #1234567890
}

确认之后,执行rollback.yml文件进行回滚操作:
[root@server ~]# ansible-playbook /etc/ansible/nginx_config/rollback.yml 

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

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

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

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

PLAY RECAP *************************************************************************************************************
192.168.222.113            : ok=3    changed=2    unreachable=0    failed=0 

到客户端上查看是否已恢复:

[root@client ~]# tail -n2 /usr/local/nginx/conf/nginx.conf

}

相关内容

    暂无相关文章