正文
部署有一个需求,要将所有的模块服务器里添加一个叫agentmizar的日志采集模块。但是有一些服务器提前有部署过,那么判断一下如果服务器里有此进程就跳过,如果没有此进程就传包并修改配置文件然后启动。
与playbook搭配的yaml内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50- hosts: all #默认执行hosts里的所有IP
remote_user: root
any_errors_fatal: no
gather_facts: no #不采集对方机器的数据,提高执行速度
serial:
- 5 #5台机器一组
tasks:
- name: judge agent process is exits
shell: ps -aux | grep agent
ignore_errors: True #如果命令执行不成功,即 echo $?不为0,则在其语句后面的ansible语句不会被执行,导致整个程序中止。
register: result
- name: agent is running
shell: echo "agent is running"
when: result.stdout.find('agent.conf') != -1
- name: agent dir is exits
shell: ls /opt/agentmizar
ignore_errors: True
register: dirresult
- name: copy packages
copy:
src: /tmp/agentmizar.zip
dest: /opt
owner: root
when: dirresult is failed #如果文件夹存在就是dirresult is succeeded
- name: unzip agentmizar
unarchive: #如果你并不喜欢用unzip的话,那么可以shell:unzip -o 对应.zip的方式来达到不用输入y的效果,但是更推荐用unarchive
#extra_opts: -j #将zip里的所有递归文件都放到本目录
src: /opt/agentmizar.zip
dest: /opt
remote_src: yes
when: result.stdout.find('agent.conf') == -1
- name: backup old and unpack new package
shell: cp -rf /opt/build/* /opt/ #由于zip包也解压缩出来是一个build文件夹,需要再扒一层
when: result.stdout.find('agent.conf') == -1
- name: update agent.conf
lineinfile:
dest: /opt/agentmizar/agent.conf
regexp: "kafka = 192.168.0.1:9092,192.168.0.2:9092,192.168.0.3:9092" #修改配置文件
line: "kafka = 172.0.10.1:9092"
when: result.stdout.find('agent.conf') == -1
- name: start agentmizar
shell: cd /opt/agentmizar/ && /bin/bash /opt/agentmizar/start_agent.sh
when: result.stdout.find('agent.conf') == -1
这个yaml,我执行ps -aux | grep agent
,并将结果存储到result
这个register
里。然后从register
里去find关键字agent.conf
,如果不存在就返回-1,那么可以判断当前机器里没有agentmizar进程。
如果说进程是一个守护进程,那么在判断进程(比如是systemctl status apache2)是否存在可以这么写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14- name: Check if Apache is running
command: systemctl status apache2
ignore_errors: yes
changed_when: false
register: service_apache_status
- name: Report status of Apache
fail:
msg: |
Service apache2 is not running.
Output of `systemctl status apache2`:
{{ service_apache_status.stdout }}
{{ service_apache_status.stderr }}
when: service_apache_status | failed
注意!如果when条件判断句中有变量的话要将用()来括变量,如下:
1
2when: ansible_default_ipv4.address == {{ ETCD_NODE03 }} #错误写法
when: ansible_default_ipv4.address == (ETCD_NODE03) #正确写法
再注意!register
变量的命名不能用-(中横线),比如dev-sda6_result
,则会被解析成sda6_result
,dev会被丢掉!
yum一次性安装多个模块的问题
新版本的ansible-playbook已经不支持在yum安装多个模块里使用的方式了,也就是说
1
2
3
4
5
6
7tasks
- name: 安装最新版本的命令
yum: name={{ item }} state=latest
with_items:
- unzip
- psmisc
- java-1.8.0-openjdk*
这么写在老版本还OK,但是在2.8以后,还这么写就会有错误:[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: "", please
use name: ['unzip', 'psmisc', 'java-1.8.0-openjdk*'] 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
.要改成如下:
1
2
3
4
5
6
7
8tasks:
- name: 安装最新版本的命令
yum:
state: latest
name:
- unzip
- psmisc
- java-1.8.0-openjdk*
如何在task之间传递变量
某个变量想从一个task给另一个,可以按照如下的方式写:
1
2
3
4
5
6
7
8
9
10---
- hosts: all
gather_facts: no
tasks:
- name: register vars
shell: hostname
register: info
- name: display vars
debug: msg="{{info.stdout}}"
第一个shell执行完后,使用register获取数据到info里,info是一个key value字典,debug输出info.stdout的具体内容。
参考资料
https://www.ibm.com/developerworks/cn/linux/1608_lih_ansible/index.html
https://blog.51cto.com/liuzhengwei521/1962382 (条件判断)