inventory
Ansible使用清单的一个列表或者一组列表,同时针对多个被控机进行工作。定义了清单后,可以争对具体生产情况来对受管主机来进行分组。
清单的默认文件的名为/etc/ansible/hosts。但我们平时习惯于在项目目录中单独建立一个inventory文件,把受管主机信息写入。执行playbook时用-i指定清单即可。
inventory 别名
平时我们为了更方便的辨认主机的用途,我们会为各个主机或者组来起别名,这样比直接使用IP地址更方便
方式一:直接在inventory中对别名进行说明(INI格式)
[root@localhost project2]# vim inventory
mysql_host ansible_password=123456 ansible_host=192.168.190.134 用ansible_host注明对应ip地址
[root@localhost project2]# ansible mysql_host -m ping -i inventory ping主机的时候用别名代替ip地址即可。playbook同理。
mysql_host | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
方式二:为了更方便的管理主机或组,可以在host_vars或group_vars中建立别名的文件,然后在里面表明ip地址(YAML格式)
[root@localhost project2]# vim host_vars/mysql_host 在host_vars/mysql_host下说明密码和对应的ip地址
ansible_host: 192.168.190.134
ansible_password: 123456
[root@localhost project2]# ansible mysql_host -m ping -i inventory 同样ping通
mysql_host | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
通配符使用
除了用别名外,我们可以用通配符来匹配主机
注意:
- 通配符只是对字符串进行匹配,所以不会区分别名,域名,IP,组名。只要存在对应字符串的内容全都匹配。
- 来使用通配符来匹配主机时,必须使用'',否则ansible会报错。
[root@localhost project2]# ansible 'mysql*' -m ping -i inventory 匹配mysql_host主机
mysql_host | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
列表
可以在hosts中使用,来分隔多个主机的条目,使playbook对多个主机或组生效。
各个条目并没有限制。可以是主机名,可以是ip,也可以是组名。主要存在于inventory中即可。
vim test.yml
---
- name: test
hosts: mysql_host,test,192.168.190.133 这里分别选用了 mysql_host主机,test组,以及ip:192.168.190.133
tasks:
- name:
command: echo 'hello'
TASK [command] ************************************************************************************
changed: [192.168.190.134]
changed: [mysql_host]
changed: [192.168.190.133]
PLAY RECAP ****************************************************************************************
192.168.190.133 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.190.134 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mysql_host : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
多个清单
inventory可以作为一个目录存在,在此目录中新建多个清单文件,在用-i参数选择清单的时候可以指定清单
[root@localhost project]# ls inventory/ inventory目录下有两个清单文件
db web
[root@localhost project]# ansible all -m ping -i inventory/web 只选取web下的清单
192.168.190.134 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
配置并行
forks选项是Ansible原生支持的一种支持并发执行的方式,ansible默认只会创建5个进程,所以一次任务只能同时控制5台机器执行.那如果你有大量的机器需要控制,或者你希望减少进程数forks值默认是5,可以通过配置文件修改默认值。
并行执行方式
ansible默认是并行方式执行playbook,且forks值为5。所以ansible在执行playbook时,同时只会筛取被控对象中的前5台执行第一个task,执行完成之后再交由第二个5台被控对象进行执行第一个task,直到所有被控机第一个task执行完成之后再从头开始执行第二个task。
修改forks的方式
- 配置文件直接修改(永久生效)
[root@localhost project]# vim /etc/ansible/ansible.cfg
......
#forks = 5 直接修改即可
- 命令行修改(临时)
ansible/ansible-playbook -f 7 直接指定forks值即可 只针对这一次动作
管理滚动更新(serial)
ansible由于是分批并行运行任务,所以有可能导致一部分主机长时间处于等待状态,影响业务进行。
滚动更新方式
滚动更新可以使指定的主机中的playbook全部执行完之后继续执行。
关键字serial的运用
serial关键字用来指定完全执行playbook的主机数目,依次以指定数目来处理hosts中整个对象
[root@localhost project]# vim test1.yml
---
- name: test
hosts: all
serial: 2 设置serial值,优先把前2台主机的所有任务以及handlers执行完后再执行第三台主机
tasks:
- name: echo
command: echo 'hello'
TASK [Gathering Facts] ***********************************************************************
ok: [192.168.190.134]
ok: [192.168.190.133]
TASK [echo] **********************************************************************************
changed: [192.168.190.134]
changed: [192.168.190.133]
PLAY [test] **********************************************************************************
TASK [Gathering Facts] ***********************************************************************
ok: [192.168.190.135]
TASK [echo] **********************************************************************************
changed: [192.168.190.135]
导入与包含
如果playbook很长或很复杂,我们可以将其分成较小的文件,然后通过导入或者包含的方式来组合成完整的playbook。达到方便管理的作用。
import与include的区别
- include是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容
- import是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容
导入子playbook
关键字:import_playbook,
例:
第一个yml
---
- hosts: 192.168.190.134
tasks:
- name: test
command: echo 'hello world'
第二个yml
[root@localhost playbook]# vim date.yml
---
- hosts: 192.168.190.134
tasks:
- name: date
template:
src: ../template/date.j2
dest: /opt/date.txt
编写main.yml,连接以上2个playbook,完成后直接执行main.yml
[root@localhost playbook]# vim main.yml
---
- name: import echo_hello.yml
import_playbook: echo_hello.yml
- name: import date.yml
import_playbook: date.yml
root@localhost playbook]# ansible-playbook main.yml -i ../inventory/ 直接执行main.yml
......
TASK [test] **********************************************************************************
changed: [192.168.190.134]
......
TASK [date] **********************************************************************************
changed: [192.168.190.134]
[root@localhost ~]# vi /opt/date.txt 被控机上文件已经成功生成
show me 2020-09-12
导入任务文件
我们除了通过import_playbook的方式导入playbook外,我们还可以通过创建任务文件,并通过import_tasks来导入任务文件。
注意:任务文件没有的格式与playbook类似,但是不具备执行条件,因为并没有hosts值以及tasks块。
例:
[root@localhost project2]# vim tasks/test1.yml 任务文件
- name: test
template:
src: ../template/date2.j2
dest: /opt/date2.txt
[root@localhost project2]# vim test.yml playbook文件
---
- hosts: 192.168.190.134
tasks:
- name: print date
import_tasks: tasks/test1.yml
注意:import_tasks和import_playbook处于不同的级别;import_playbook是与tasks平级;import_tasks则是tasks的子任务,所以书写时注意格式
包含任务文件
关键字:include_tasks
例:
[root@localhost project2]# vim test.yml
---
- hosts: 192.168.190.134
tasks:
- name: print date
include_tasks: tasks/test1.yml
play中变量的运用
[root@localhost project2]# vim tasks/test2.yml 任务文件中定义变量
- name: test
command: echo {{ echo_name }}
register: result
- debug:
var: result
[root@localhost project2]# vim test.yml
---
- hosts: 192.168.190.134
tasks:
- name: echo
import_tasks: tasks/test2.yml
vars: 直接在导入任务下定义变量值,注意vars的级别时与import_tasks一个级别。也为tasks下一级别。
echo_name: " hello world "
[root@localhost project2]# ansible-playbook test.yml -i inventory
"start": "2020-09-14 20:47:27.109908",
"stderr": "",
"stderr_lines": [],
"stdout": "hello world",
"stdout_lines": [
"hello world"
]
}
......