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 }