1、 选择具有主机模式的主机
1.1 主机清单
[student@workstation mmx]$ cat inventory
web.example.com
data.example.com
[lab]
labhost1.example.com
labhost2.example.com
[test]
test1.example.com
test2.example.com
[datacenter1]
labhost1.example.com
test1.example.com
[datacenter2]
labhost2.example.com
test2.example.com
[datacenter:children]
datacenter1
datacenter2
# 不建议在inventory清单中指定地址给
[new]
192.168.1.1
192.168.1.2
1.2 间接指向ip
不建议在inventory中写ip地址,不清晰,可以通过如下方式
[student@workstation mmx]$ mkdir host_vars
[student@workstation mmx]$ mkdir group_vars
[student@workstation mmx]$ cd host_vars/
[student@workstation host_vars]$ ls
[student@workstation host_vars]$ touch mmx1
[student@workstation host_vars]$ touch mmx2
# 通过在主机组内定义变量,指定ip地址
[student@workstation host_vars]$ echo ansible_host: 192.168.1.1 > mmx1
[student@workstation host_vars]$ echo ansible_host: 192.168.1.2 > mmx2
[student@workstation mmx]$ cat inventory
...
[new]
# 192.168.1.1
# 192.168.1.2
mmx1
mmx2
# 亲测可用
[student@workstation mmx]$ ansible mmx1 -m ping
mmx1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
1.3 指定hosts的几种方式
web.example.com
data.example.com
[lab]
labhost1.example.com
labhost2.example.com
[test]
test1.example.com
test2.example.com
[datacenter1]
labhost1.example.com
test1.example.com
[datacenter2]
labhost2.example.com
test2.example.com
[datacenter:children]
datacenter1
datacenter2
[new]
192.168.1.1
192.168.1.2
host取值 | 说明 |
---|---|
lab | 指定单一主机组(lab) |
all | 指定所有主机组 |
ungrouped | 指定不属于任何组主机(web.example.com,data.example.com) |
* | 相当于all |
!lab | 除了lab组之外所有主机 |
192.168.1.* | 网段192.168.1.开头 |
datacenter* | 以datacenter开头 |
lab,test | 包含lab和test |
lab,data* | 包含lab和data* |
1.4 与和或
符号 | 含义 |
---|---|
& | 与,两个都存在 |
, | 或,存在一个以上 |
# lab和datacenter1的交集
---
- hosts: lab,&datacenter1
...(labhost1.example.com)
# 不包括test2.example.com这个主机
---
- hosts: datacenter,!test2.example.com
...(labhost1.example.com,test1.example.com,labhost2.example.com)
1.5 选择主机or主机组练习
1.5.1 题目要求
-
查看inventory1
-
查看inventroy2
-
使用ad hoc 执行练习:
- 使用ad hoc命令加参数--list-hosts查看db1中的主机
- 使用ad hoc命令加参数--list-hosts查看172.25.252.44中的主机
- 使用ad hoc命令加参数--list-hosts查看inventory中的所有主机
- 使用ad hoc命令加参数--list-hosts查看“*.example.com”中的所有主机
- 使用ad hoc命令加参数--list-hosts查看inventory且没有“*.lab.example.com"中的主机
- 使用ad hoc命令加参数--list-hosts查看三个主机lb1.lab.example.com,s1.lab.example.com,db1.example.com中的主机
- 使用ad hoc命令加参数--list-hosts查看”172.25.*‘的主机
- 使用ad hoc命令加参数--list-hosts查看“s*"中的所有主机
- 使用ad hoc命令加参数--list-hosts查看prod,172*,中的所有主机
- 使用ad hoc命令加参数--list-hosts查看在db和lodon两者都存在的主机
- 在playbook下填写london,使用-i参数inventory2执行playbook
- 在playbook下填写europe,使用-i参数inventory2执行playbook
- 在playbook下填写ungrouped,使用-i参数inventory2执行playbook
1.5.2 练习
[student@workstation projects-host]$ cat inventory2
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
[web]
jupiter.lab.example.com
saturn.example.com
[db]
db1.example.com
db2.example.com
db3.example.com
[lb]
lb1.lab.example.com
lb2.lab.example.com
[boston]
db1.example.com
jupiter.lab.example.com
lb2.lab.example.com
[london]
db2.example.com
db3.example.com
file1.lab.example.com
lb1.lab.example.com
[dev]
web1.lab.example.com
db3.example.com
[stage]
file2.example.com
db2.example.com
[prod]
lb2.lab.example.com
db1.example.com
jupiter.lab.example.com
[function:children]
web
db
lb
city
[city:children]
boston
london
environments
[environments:children]
dev
stage
prod
new
[new]
172.25.252.23
172.25.252.44
172.25.252.32
[student@workstation projects-host]$ cat inventory2
workstation.lab.example.com
[london]
servera.lab.example.com
[berlin]
serverb.lab.example.com
[tokyo]
serverc.lab.example.com
[atlanta]
serverd.lab.example.com
[europe:children]
london
berlin
# 使用ad hoc命令加参数--list-hosts查看db1中的主机
[student@workstation projects-host]$ ansible db1.example.com -i inventory1 --list-hosts
hosts (1):
db1.example.com
# 使用ad hoc命令加参数--list-hosts查看172.25.252.44中的主机
[student@workstation projects-host]$ ansible 172.25.252.44 -i inventory1 --list-hosts
hosts (1):
172.25.252.44
# 使用ad hoc命令加参数--list-hosts查看inventory中的所有主机
[student@workstation projects-host]$ ansible all -i inventory1 --list-hosts
hosts (17):
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
jupiter.lab.example.com
saturn.example.com
db1.example.com
db2.example.com
db3.example.com
lb1.lab.example.com
lb2.lab.example.com
file1.lab.example.com
web1.lab.example.com
file2.example.com
172.25.252.23
172.25.252.44
172.25.252.32
#使用ad hoc命令加参数--list-hosts查看“*.example.com”中的所有主机
[student@workstation projects-host]$ ansible '*.example.com' -i inventory1 --list-hosts
hosts (14):
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
jupiter.lab.example.com
saturn.example.com
db1.example.com
db2.example.com
db3.example.com
lb1.lab.example.com
lb2.lab.example.com
file1.lab.example.com
web1.lab.example.com
file2.example.com
# 使用ad hoc命令加参数--list-hosts查看inventory且没有“*.lab.example.com"中的主机
[student@workstation projects-host]$ ansible '*.example.com, !*.lab.example.com' -i inventory1 --list-hosts
hosts (7):
srv1.example.com
srv2.example.com
saturn.example.com
db1.example.com
db2.example.com
db3.example.com
file2.example.com
# 使用ad hoc命令加参数--list-hosts查看三个主机lb1.lab.example.com,s1.lab.example.com,db1.example.com中的主机
[student@workstation projects-host]$ ansible lb1.lab.example.com,s1.lab.example.com,db1.example.com -i inventory1 --list-hosts
hosts (3):
lb1.lab.example.com
s1.lab.example.com
db1.example.com
# 使用ad hoc命令加参数--list-hosts查看”172.25.*‘的主机
[student@workstation projects-host]$ ansible '172.25.*' -i inventory1 --list-hosts
hosts (3):
172.25.252.23
172.25.252.44
172.25.252.32
# 使用ad hoc命令加参数--list-hosts查看“s*"中的所有主机
[student@workstation projects-host]$ ansible 's*' -i inventory1 --list-hosts
hosts (7):
file2.example.com
db2.example.com
srv1.example.com
srv2.example.com
s1.lab.example.com
s2.lab.example.com
saturn.example.com
# 使用ad hoc命令加参数--list-hosts查看prod,172*,中的所有主机
[student@workstation projects-host]$ ansible 'prod,172.*,*lab*' -i inventory1 --list-hosts
hosts (11):
lb2.lab.example.com
db1.example.com
jupiter.lab.example.com
172.25.252.23
172.25.252.44
172.25.252.32
s1.lab.example.com
s2.lab.example.com
lb1.lab.example.com
file1.lab.example.com
web1.lab.example.com
# 使用ad hoc命令加参数--list-hosts查看在db和lodon两者都存在的主机
[student@workstation projects-host]$ ansible 'db,&london' -i inventory1 --list-hosts
hosts (2):
db2.example.com
db3.example.com
# 在playbook下填写london,使用-i参数inventory2执行playbook
[student@workstation projects-host]$ vim playbook.yml
[student@workstation projects-host]$ cat playbook.yml
---
- name: Resolve host patterns
hosts: london
tasks:
- name: Display managed host name
debug:
msg: "{{inventory_hostname}}"
[student@workstation projects-host]$ ansible-playbook -i inventory2 playbook.yml
# 在playbook下填写europe,使用-i参数inventory2执行playbook
[student@workstation projects-host]$ cat playbook.yml
---
- name: Resolve host patterns
hosts: europe
tasks:
- name: Display managed host name
debug:
msg: "{{inventory_hostname}}"
[student@workstation projects-host]$ ansible-playbook playbook.yml -i inventory2
# 在playbook下填写ungrouped,使用-i参数inventory2执行playbook
[student@workstation projects-host]$ cat playbook.yml
---
- name: Resolve host patterns
hosts: ungrouped
tasks:
- name: Display managed host name
debug:
msg: "{{inventory_hostname}}"
[student@workstation projects-host]$ ansible-playbook playbook.yml -i inventory2
2、 管理动态inventory文件
静态清单文件在一个笔记大型的项目中,无法准确的判断管理节点那些是在线的,那些不存在,使用动态清单文件管理host,可以很方便的解决这一问题
2.1 一些提供动态inventory接口的平台
- OpenStack平台
- 亚马逊AWS
- 虚拟化平台(oVirt,VMware等)
- OpenShift
- 红帽卫星
- 主机提供者
2.2 动态的Inventroy文件
一个静态inventroy文件在底层调用的时候会转化为JSON格式,如果要编写动态inventory文件,必须是JSON格式的
[student@workstation control-flow]$ cat inventory
[database_dev]
servera.lab.example.com
[database_prod]
serverb.lab.example.com
[student@workstation control-flow]$ ansible-inventory -i inventory --list
{
"_meta": {
"hostvars": {
"servera.lab.example.com": {},
"serverb.lab.example.com": {}
}
},
"all": {
"children": [
"database_dev",
"database_prod",
"ungrouped"
]
},
"database_dev": {
"hosts": [
"servera.lab.example.com"
]
},
"database_prod": {
"hosts": [
"serverb.lab.example.com"
]
}
}
可以通过执行脚本,返回JSON数据,执行时必须能使用--list参数,可选项: 主机变量
动态inventory中最好不要主机组名和主机名重名,如果重名了,需要在清单文件开头加入一个空的主机组名,以示区分
2.3 动态inventory文件练习
2.3.1 题目要求
- 开启实验环境
- 进入目录查看,创建inventory目录,下载动态inventroy文件
- 下载http://materials.example.com/labs/projects-inventory/inventorya.py
- 下载http://materials.example.com/labs/projects-inventory/inventoryw.py
- 通过执行XX.py list方式查看主机或主机组
- 加入一条静态inventory清单,文件名hosts
- 定义一个webservers组,确保执行的时候不会报错
- 定义一个servers组,他的子组是webservers
2.3.2 练习
[student@workstation ~]$ lab projects-inventory start
Setting up workstation for lab exercise work:
· Verifying Ansible installation.............................. SUCCESS
· Creating working directory.................................. SUCCESS
· Deploying ansible.cfg....................................... SUCCESS
[student@workstation ~]$ cd projects-inventory/
[student@workstation projects-inventory]$ ls
ansible.cfg
[student@workstation projects-inventory]$ cat ansible.cfg
[defaults]
inventory = inventory
[student@workstation projects-inventory]$ mkdir inventory
[student@workstation projects-inventory]$ cd inventory/
[student@workstation inventory]$ wget http://materials.example.com/labs/projects-inventory/inventorya.py
[student@workstation inventory]$ wget http://materials.example.com/labs/projects-inventory/inventoryw.py
[student@workstation inventory]$ ls
inventorya.py inventoryw.py
# 动态inventory写法,python方式
[student@workstation inventory]$ cat inventorya.py
#!/usr/bin/python3
from subprocess import Popen,PIPE
import sys
import json
result = {}
# 主机组
result['webservers'] = {}
# 主机
result['webservers']['hosts'] = []
# 变量
result['webservers']['vars'] = {}
# Popen函数主要用来执行linux命令,调用/etc/hosts
'''
[root@workstation ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.254 classroom.example.com classroom
172.25.254.254 content.example.com content
172.25.254.254 materials.example.com materials
### rht-vm-hosts file listing the entries to be appended to /etc/hosts
#
172.25.250.9 workstation.lab.example.com workstation
172.25.250.10 servera.lab.example.com servera
172.25.250.11 serverb.lab.example.com serverb
172.25.250.12 serverc.lab.example.com serverc
172.25.250.13 serverd.lab.example.com serverd
172.25.250.254 bastion.lab.example.com bastion
'''
pipe = Popen(['getent', 'hosts'], stdout=PIPE, universal_newlines=True)
for line in pipe.stdout.readlines():
# 切割字符串
s = line.split()
'''
如果是以servera开头,则是:
servera.lab.example.com
如果是以server开头,则是:
servera.lab.example.com
serverb.lab.example.com
serverc.lab.example.com
serverd.lab.example.com
'''
if s[1].startswith('servera'):
# 在 result['webservers']['hosts']加入一个主机
result['webservers']['hosts'].append(s[1])
# 执行脚本输出--list参数,则会执行json.dumps(result)
if len(sys.argv) == 2 and sys.argv[1] == '--list':
print(json.dumps(result))
# 执行脚本输出--list参数,则会执行json.dumps(result)
elif len(sys.argv) == 3 and sys.argv[1] == '--host':
print(json.dumps({}))
else:
# 否则输入如下信息
print("Requires an argument, please use --list or --host <host>")
[student@workstation inventory]$ cat inventoryw.py
#!/usr/bin/python3
from subprocess import Popen,PIPE
import sys
import json
result = {}
result['all'] = {}
pipe = Popen(['getent', 'hosts'], stdout=PIPE, universal_newlines=True)
result['all']['hosts'] = []
for line in pipe.stdout.readlines():
s = line.split()
if s[1].startswith('workstation'):
result['all']['hosts'].append(s[1])
result['all']['vars'] = {}
if len(sys.argv) == 2 and sys.argv[1] == '--list':
print(json.dumps(result))
elif len(sys.argv) == 3 and sys.argv[1] == '--host':
print(json.dumps({}))
else:
print("Requires an argument, please use --list or --host <host>")
# 赋予可执行权限
[student@workstation inventory]$ chmod +x inventory*
# 通过执行python,可以得出定义了webservers组servera和不属于组的workstation
[student@workstation inventory]$ ./inventorya.py --list
{"webservers": {"hosts": ["servera.lab.example.com"], "vars": {}}}
[student@workstation inventory]$ ./inventoryw.py --list
{"all": {"hosts": ["workstation.lab.example.com"], "vars": {}}}
[student@workstation projects-inventory]$ ansible webservers --list-hosts
hosts (1):
servera.lab.example.com
[student@workstation projects-inventory]$ ansible ungrouped --list-hosts
hosts (1):
workstation.lab.example.com
[student@workstation projects-inventory]$ cat hosts
# 动态清单中有webservers组,在文件上方定义一个这样的组,不会报错
[webservers]
[servers:children]
webservers
3、 多线程优化
3.1 指定任务使用cpu数
forks:一次处理被管理主机数量,默认forks为5
1、 可以使用 ansible-config list | grep -i forks,查看forks使用方式
[student@workstation projects-inventory]$ ansible-config list | grep -i forks
DEFAULT_FORKS:
description: Maximum number of forks Ansible will use to execute tasks on target
- {name: ANSIBLE_FORKS}
- {key: forks, section: defaults}
name: Number of task forks
2、 指定forks=1,查看运行效果
# 使用forks,使用n个cpu来执行,forks取决于本机cpu数量
[student@workstation projects-inventory]$ cat ansible.cfg
[defaults]
inventory = inventory
forks = 1
[student@workstation projects-inventory]$ cat install.yml
---
- name: install software
hosts: all
vars:
packages:
- httpd
- ftp
remote_user: root
tasks:
- name: install software
yum:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
# 此时发现一次运行一个任务,然后运行下一个任务……
[student@workstation projects-inventory]$ ansible-playbook install.yml
PLAY [install software] *********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [workstation.lab.example.com]
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
ok: [serverc.lab.example.com]
ok: [serverd.lab.example.com]
TASK [install software] *********************************************************************************************************************************************************************************************************************************
changed: [workstation.lab.example.com] => (item=httpd)
changed: [workstation.lab.example.com] => (item=ftp)
changed: [servera.lab.example.com] => (item=httpd)
changed: [servera.lab.example.com] => (item=ftp)
changed: [serverb.lab.example.com] => (item=httpd)
changed: [serverb.lab.example.com] => (item=ftp)
changed: [serverc.lab.example.com] => (item=httpd)
changed: [serverc.lab.example.com] => (item=ftp)
changed: [serverd.lab.example.com] => (item=httpd)
changed: [serverd.lab.example.com] => (item=ftp)
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
workstation.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.2 指定一次执行任务数
serial:指定一次执行多少个任务,写在playbook里面
# 指定forks为4
[student@workstation projects-inventory]$ cat ansible.cfg
[defaults]
inventory = inventory
forks = 4
# 指定一次执行2个task
[student@workstation projects-inventory]$ cat install.yml
---
- name: install software
hosts: all
vars:
packages:
- httpd
- ftp
remote_user: root
serial: 2
tasks:
- name: install software
yum:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
# 发现运行的时候,每次运行两个任务
[student@workstation projects-inventory]$ ansible-playbook install.yml
PLAY [install software] *********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [workstation.lab.example.com]
TASK [install software] *********************************************************************************************************************************************************************************************************************************
changed: [servera.lab.example.com] => (item=httpd)
changed: [workstation.lab.example.com] => (item=httpd)
changed: [servera.lab.example.com] => (item=ftp)
changed: [workstation.lab.example.com] => (item=ftp)
PLAY [install software] *********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [serverc.lab.example.com]
TASK [install software] *********************************************************************************************************************************************************************************************************************************
changed: [serverb.lab.example.com] => (item=httpd)
changed: [serverc.lab.example.com] => (item=httpd)
changed: [serverb.lab.example.com] => (item=ftp)
changed: [serverc.lab.example.com] => (item=ftp)
PLAY [install software] *********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [serverd.lab.example.com]
TASK [install software] *********************************************************************************************************************************************************************************************************************************
changed: [serverd.lab.example.com] => (item=httpd)
changed: [serverd.lab.example.com] => (item=ftp)
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
workstation.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.3 多线程优化练习
3.3.1 题目要求
- 开启实验环境
- 环境中有playbook.yml和remove_apache.yml用于测试
- playbook.yml安装软件包,remove_apache.yml卸载软件包
- ansible.cfg文件中有参数:forks=4,决定每次使用cpu数量
- 在plyabook中加入serial:X,决定一次执行任务数
- 使用time测试运行时间
3.3.2 练习
[student@workstation ~]$ lab projects-parallelism start
Setting up workstation for lab exercise work:
· Verifying Ansible installation.............................. SUCCESS
· Creating working directory.................................. SUCCESS
· Deploying ansible.cfg....................................... SUCCESS
· Deploying Ansible inventory................................. SUCCESS
· Deploying playbook.yml playbook............................. SUCCESS
· Deploying remove_apache.yml playbook........................ SUCCESS
· Remove apache............................................... SUCCESS
[student@workstation ~]$ cd projects-parallelism/
[student@workstation projects-parallelism]$ ls
ansible.cfg inventory playbook.yml remove_apache.yml
[student@workstation projects-parallelism]$ cat ansible.cfg
[defaults]
inventory=inventory
remote_user=devops
forks=4
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[student@workstation projects-parallelism]$ cat playbook.yml
---
- name: Update web server
hosts: webservers
tasks:
- name: Latest version of apache installed
yum:
name: httpd
state: latest
notify:
- Restart apache
handlers:
- name: Restart apache
service:
name: httpd
enabled: yes
state: restarted
[student@workstation projects-parallelism]$ cat remove_apache.yml
---
- hosts: webservers
tasks:
- service:
name: httpd
enabled: no
state: stopped
- yum:
name: httpd
state: absent
# 使用force=4,查看playbook运行时间
[student@workstation projects-parallelism]$ time ansible-playbook playbook.yml
...
real 0m4.426s
user 0m1.689s
sys 0m0.503s
...
# 将force改为1,查看playbook运行时间
...
real 0m12.090s
user 0m1.870s
sys 0m0.570s
...
# 将force设置为4,serial设置为3,查看playbook运行时间
[student@workstation projects-parallelism]$ time ansible-playbook playbook.yml
...
real 0m7.193s
user 0m1.650s
sys 0m0.567s
...
# 将force设置为2,serial设置为2,查看playbook运行时间
[student@workstation projects-parallelism]$ time ansible-playbook playbook.yml
...
real 0m7.130s
user 0m1.687s
sys 0m0.538s
...
4、 包含和导入
对于一个比较大型的项目,不可避免会出现playbook会写的很长,可以通过include或者import的方式减少playbook文件的大小
4.1 使用import_playbook参数
将其他位置的playbook直接导入到这个playbook中来
特别不灵活,不建议使用
[student@workstation control-flow]$ cat web.yml
---
- name: install httpd
hosts: all
tasks:
- name: install httpd
yum:
name: httpd
state: latest
[student@workstation control-flow]$ cat new.yml
---
- name: install httpd
import_playbook: web.yml
[student@workstation control-flow]$ ansible-playbook new.yml
PLAY [install httpd] ************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [install httpd] ************************************************************************************************************************************************************************************************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.2 使用import_tasks参数(静态导入)
通过写好task任务,调用tasks的方式来执行playbook
- 不能使用when
- 不能使用loop
- 可以使用变量
[student@workstation control-flow]$ cat tasks.yml
- name: install httpd
yum:
name: httpd
state: latest
- name: Start service httpd, if not started
service:
name: httpd
state: started
enabled: 1
[student@workstation control-flow]$ cat new.yml
---
- name: install httpd
hosts: all
tasks:
- name: import tasks
import_tasks: tasks.yml
[student@workstation control-flow]$ ansible-playbook new.yml
PLAY [install httpd] ************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [install httpd] ************************************************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [Start service httpd, if not started] **************************************************************************************************************************************************************************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.3 使用inclue_tasks参数(动态导入)
作用和import_tasks差不多
- 可以使用when做判断
- 可以使用ansible-playbook --list-tasks列出tasks
- 可以使用--start-at-tast进行单步调试
- 不能使用notify指定标记运行handlers
[student@workstation control-flow]$ cat tasks.yml
- name: install httpd
yum:
name: httpd
state: latest
- name: Start service httpd, if not started
service:
name: httpd
state: started
enabled: 1
[student@workstation control-flow]$ cat new.yml
---
- name: install httpd
hosts: all
tasks:
- name: include tasks
4.4 import和include区别
- 使用import相当于导入
[student@workstation control-flow]$ ansible-playbook new.yml --list-tasks
playbook: new.yml
play #1 (all): install httpd TAGS: []
tasks:
install httpd TAGS: []
Start service httpd, if not started TAGS: []
- include相当于包括
[student@workstation control-flow]$ ansible-playbook new.yml --list-tasks
playbook: new.yml
play #1 (all): install httpd TAGS: []
tasks:
include tasks TAGS: []
4.5 将task参数改为变量形式
[student@workstation control-flow]$ cat vars.yml
---
package: httpd
package_state: latest
service: httpd
state: started
[student@workstation control-flow]$ cat tasks.yml
- name: install {{ package }}
yum:
name: "{{ package }}"
state: "{{ package_state }}"
- name: Start {{ service }}
service:
name: "{{ service }}"
state: "{{ state }}"
enabled: 1
[student@workstation control-flow]$ cat new.yml
---
- name: install software
hosts: all
vars_files:
- vars.yml
tasks:
- name: include tasks
include_tasks: tasks.yml
[student@workstation control-flow]$ ansible-playbook new.yml
PLAY [install software] ********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [include tasks] ***********************************************************************************************************************************************************************************************************
included: /home/student/control-flow/tasks.yml for servera.lab.example.com, serverb.lab.example.com
TASK [install httpd] ***********************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [Start httpd] *************************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
PLAY RECAP *********************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.6 include和import练习
4.6.1 题目要求
- 开启实验环境
- 查看tasks和plays目录下文件
- tasks目录下文件主要用于开启web服务,放行防火墙
- plays目录下文件主要用于测试
- 创建playbook文件,根据tasks中提示变量,完成实验
- 结束实验
4.6.2 实验
[student@workstation ~]$ lab projects-file start
Setting up workstation for lab exercise work:
· Verifying Ansible installation.............................. SUCCESS
· Creating working directory.................................. SUCCESS
· Deploying ansible.cfg....................................... SUCCESS
· Deploying Ansible inventory................................. SUCCESS
· Creating task directory..................................... SUCCESS
· Deploying environment task files............................ SUCCESS
· Deploying firewall task files............................... SUCCESS
· Deploying placeholder task files............................ SUCCESS
· Creating play directory..................................... SUCCESS
· Deploying play files........................................ SUCCESS
[student@workstation ~]$ tree projects-file/
projects-file/
├── ansible.cfg
├── inventory
├── plays
│ └── test.yml
└── tasks
├── environment.yml
├── firewall.yml
└── placeholder.yml
[student@workstation ~]$ cd projects-file/
[student@workstation projects-file]$ ls
ansible.cfg inventory plays tasks
[student@workstation projects-file]$ cat ansible.cfg
[defaults]
inventory=inventory
remote_user=devops
[privilege_escalation]
become=True
become_method=sudo
beome_user=root
become_ask_pass=False
[student@workstation projects-file]$ cat inventory
servera.lab.example.com
[student@workstation projects-file]$ cat tasks/
environment.yml firewall.yml placeholder.yml
[student@workstation projects-file]$ ls plays/
test.yml
# 查看tasks中定制好的task
[student@workstation projects-file]$ cat tasks/environment.yml
---
- name: Install the {{ package }} package
yum:
name: "{{ package }}"
state: latest
- name: Start the {{ service }} service
service:
name: "{{ service }}"
enabled: true
state: started
[student@workstation projects-file]$ cat tasks/firewall.yml
---
- name: Install the firewall
yum:
name: "{{ firewall_pkg }}"
state: latest
- name: Start the firewall
service:
state: started
name: "{{ firewall_svc }}"
enabled: true
- name: Open the port for {{ rule }}
firewalld:
service: "{{ item }}"
immediate: true
permanent: true
state: enabled
loop: "{{ rule }}"
[student@workstation projects-file]$ cat tasks/placeholder.yml
---
- name: Create placeholder file
copy:
content: "{{ ansible_facts['fqdn'] }} has been customized using Ansible.\n"
dest: "{{ file }}"
[student@workstation projects-file]$ cat plays/test.yml
---
- name: Test web service
hosts: localhost
become: no
tasks:
- name: connect to internet web server
uri:
url: "{{ url }}"
status_code: 200
# 根据上方预留变量,补足变量完成play
[student@workstation projects-file]$ cat playbook.yml
---
- name: configure web server
hosts: servera.lab.example.com
tasks:
- name: 使用include environment
include_tasks: tasks/environment.yml
vars:
package: httpd
service: httpd
when: ansible_facts['os_family'] == 'RedHat'
- name: 配置防火墙
import_tasks: tasks/firewall.yml
vars:
firewall_pkg: firewalld
firewall_svc: firewalld
rule:
- http
- https
- name: 创建主页
import_tasks: tasks/placeholder.yml
vars:
file: "/var/www/html/index.html"
- name: import_play file
import_playbook: plays/test.yml
vars:
url: http://servera.lab.example.com
[student@workstation projects-file]$ ansible-playbook playbook.yml
PLAY [configure web server] ****************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [使用include environment] ***************************************************************************************************************************************************************************************************
included: /home/student/projects-file/tasks/environment.yml for servera.lab.example.com
TASK [Install the httpd package] ***********************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [Start the httpd service] *************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [Install the firewall] ****************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [Start the firewall] ******************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [Open the port for ['http', 'https']] *************************************************************************************************************************************************************************************
changed: [servera.lab.example.com] => (item=http)
changed: [servera.lab.example.com] => (item=https)
TASK [Create placeholder file] *************************************************************************************************************************************************************************************************
changed: [servera.lab.example.com]
PLAY [Test web service] ********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [connect to internet web server] ******************************************************************************************************************************************************************************************
ok: [localhost]
PLAY RECAP *********************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
servera.lab.example.com : ok=8 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 测试
[student@workstation projects-file]$ curl http://servera.lab.example.com
servera.lab.example.com has been customized using Ansible.
# 结束实验
[student@workstation projects-file]$ lab projects-file finish
Cleaning up the lab on servera:
· Remove firewall configuration............................... SUCCESS
· Remove web content.......................................... SUCCESS
· Remove httpd package........................................ SUCCESS
5、 综合实验
管理大项目
5.1 题目要求
- 开启实验环境
- 将playbook进行拆分
- 第1~3个tasks放入tasks/web_tasks.yml中,使用import_tasks方式导入
- 第4~6个tasks放入tasks/firewall_tasks.yml中,使用import_tasks方式导入
- 从tasks/web_tasks.yml和tasks/firewall_tasks.yml中抽取出install packages和enable services 放到新的tasks/install_and_enable.yml中,通过变量的方式,使用import_tasks方式导入
- 如果files/tune.conf发生变化,则会执行handlers任务,实现滚动更新功能,一次执行主机数为2(serial:2)
- 检查plyabook,执行playbook
5.2 练习
[student@workstation ~]$ lab projects-review start
Setting up workstation for lab exercise work:
· Verifying Ansible installation.............................. SUCCESS
· Creating working directory.................................. SUCCESS
· Deploying ansible.cfg....................................... SUCCESS
· Creating inventory directory................................ SUCCESS
· Deploying inventory script.................................. SUCCESS
· Creating files directory.................................... SUCCESS
· Deploying play files........................................ SUCCESS
· Deploying playbook.......................................... SUCCESS
[student@workstation ~]$ cd projects-review/
[student@workstation projects-review]$ ls
ansible.cfg files inventory playbook.yml
# 查看inventory动态清单文件
[student@workstation projects-review]$ cat inventory/inventory.py
#!/usr/bin/python3
from subprocess import Popen,PIPE
import sys
import json
result = {}
result['all'] = {}
pipe = Popen(['getent', 'hosts'], stdout=PIPE, universal_newlines=True)
result['all']['hosts'] = []
for line in pipe.stdout.readlines():
s = line.split()
if s[1].startswith(('w','s')):
result['all']['hosts'].append(s[1])
result['all']['vars'] = {}
if len(sys.argv) == 2 and sys.argv[1] == '--list':
print(json.dumps(result))
elif len(sys.argv) == 3 and sys.argv[1] == '--host':
print(json.dumps({}))
else:
print("Requires an argument, please use --list or --host <host>")
# 添加可执行权限,否则无法执行
[student@workstation projects-review]$ chmod +x inventory/inventory.py
[student@workstation projects-review]$ ansible-inventory --list
{
"_meta": {
"hostvars": {
"servera.lab.example.com": {},
"serverb.lab.example.com": {},
"serverc.lab.example.com": {},
"serverd.lab.example.com": {},
"workstation.lab.example.com": {}
}
},
"all": {
"children": [
"ungrouped"
]
},
"ungrouped": {
"hosts": [
"servera.lab.example.com",
"serverb.lab.example.com",
"serverc.lab.example.com",
"serverd.lab.example.com",
"workstation.lab.example.com"
]
}
}
# 编写yum脚本
[student@workstation projects-review]$ cat playbook.yml
---
- name: Install and configure web service
# 使用通配符
hosts:
- server*.lab.example.com
serial: 2
tasks:
# 使用import_tasks
- name: start web service
import_tasks: tasks/web_tasks.yml
# 使用import_tasks
- name: start firewalld service
import_tasks: tasks/firewall_tasks.yml
handlers:
- name: restart httpd
service:
name: httpd
state: restarted
[student@workstation projects-review]$ cat tasks/web_tasks.yml
- name: Install httpd
# 使用import_tasks
import_tasks: install_and_enable.yml
vars:
packages: httpd
services: httpd
- name: Tuning configuration installed
copy:
src: files/tune.conf
dest: /etc/httpd/conf.d/tune.conf
owner: root
group: root
mode: 0644
notify:
- restart httpd
# 使用import_tasks
[student@workstation projects-review]$ cat tasks/firewall_tasks.yml
- name: Install firewalld
import_tasks: install_and_enable.yml
vars:
packages: firewalld
services: firewalld
- name: Open the port for http
firewalld:
service: http
immediate: true
permanent: true
state: enabled
# 使用变量方式
[student@workstation projects-review]$ cat tasks/install_and_enable.yml
- name: Install {{ packages }}
yum:
name: "{{ packages }}"
state: latest
- name: Enable and start the {{ services }}
service:
name: "{{ services }}"
enabled: true
state: started
[student@workstation projects-review]$ ansible-playbook playbook.yml
PLAY [Install and configure web service] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [Install httpd] *********************************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [Enable and start the httpd] ********************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [Tuning configuration installed] ****************************************************************************************************************************************************************************************
ok: [serverb.lab.example.com]
ok: [servera.lab.example.com]
TASK [Install firewalld] *****************************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [Enable and start the firewalld] ****************************************************************************************************************************************************************************************
ok: [servera.lab.example.com]
ok: [serverb.lab.example.com]
TASK [Open the port for http] ************************************************************************************************************************************************************************************************
changed: [servera.lab.example.com]
changed: [serverb.lab.example.com]
PLAY [Install and configure web service] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************
ok: [serverd.lab.example.com]
ok: [serverc.lab.example.com]
TASK [Install httpd] *********************************************************************************************************************************************************************************************************
changed: [serverc.lab.example.com]
changed: [serverd.lab.example.com]
TASK [Enable and start the httpd] ********************************************************************************************************************************************************************************************
changed: [serverc.lab.example.com]
changed: [serverd.lab.example.com]
TASK [Tuning configuration installed] ****************************************************************************************************************************************************************************************
changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]
TASK [Install firewalld] *****************************************************************************************************************************************************************************************************
ok: [serverd.lab.example.com]
ok: [serverc.lab.example.com]
TASK [Enable and start the firewalld] ****************************************************************************************************************************************************************************************
ok: [serverc.lab.example.com]
ok: [serverd.lab.example.com]
TASK [Open the port for http] ************************************************************************************************************************************************************************************************
changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]
RUNNING HANDLER [restart httpd] **********************************************************************************************************************************************************************************************
changed: [serverd.lab.example.com]
changed: [serverc.lab.example.com]
PLAY RECAP *******************************************************************************************************************************************************************************************************************
servera.lab.example.com : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc.lab.example.com : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd.lab.example.com : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 判断成绩
[student@workstation projects-review]$ lab projects-review grade
Grading the student's work on workstation:
· Ensuring Ansible playbook is present........................ PASS
· Ensuring web task file is present........................... PASS
· Ensuring firewall task file is present...................... PASS
· Ensuring install_and_enable task file is present............ PASS
· Ensuring dynamic inventory script is executable............. PASS
· Checking playbook has configured 'serial' directive......... PASS
Grading the student's work on servera:
· Checking packages
· Checking firewalld........................................ PASS
· Checking httpd............................................ PASS
· Ensuring services are started
· Checking httpd............................................ PASS
· Checking firewalld........................................ PASS
· Checking for Apache tune.conf............................. PASS
· Ensuring the web server is reachable........................ PASS
Grading the student's work on serverb:
· Checking packages
· Checking firewalld........................................ PASS
· Checking httpd............................................ PASS
· Ensuring services are started
· Checking httpd............................................ PASS
· Checking firewalld........................................ PASS
· Checking for Apache tune.conf............................. PASS
· Ensuring the web server is reachable........................ PASS
Grading the student's work on serverc:
· Checking packages
· Checking firewalld........................................ PASS
· Checking httpd............................................ PASS
· Ensuring services are started
· Checking httpd............................................ PASS
· Checking firewalld........................................ PASS
· Checking for Apache tune.conf............................. PASS
· Ensuring the web server is reachable........................ PASS
Grading the student's work on serverd:
· Checking packages
· Checking firewalld........................................ PASS
· Checking httpd............................................ PASS
· Ensuring services are started
· Checking httpd............................................ PASS
· Checking firewalld........................................ PASS
· Checking for Apache tune.conf............................. PASS
· Ensuring the web server is reachable........................ PASS
Overall lab grade.............................................. PASS