利用主机模式选择主机
引用清单主机
- 主机模式用于指定要作为play或临时命令的目标的主机
- 清单中受管主机或主机组的名称就是指定该主机或主机组的主机模式
- hosts指定要针对其运行play的受管主机
- 不同的主机模式来以此示例清单中受管主机的不同子集作为目标
[root@localhost ~]# cat myinventory
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]
172.16.103.129
172.16.103.130
受管主机
最基本的主机模式是单一受管主机名称列在清单中
- 如果清单中明确列出了IP地址,而不是主机名,则可以将其用作主机模式
- 如果清单中未列出IP地址,我们将无法用它来指定主机,即便该IP地址会在DNS中解析到这个主机名
实例:
[root@ansible ansible]# ansible-playbook test.yml
PLAY [192.168.230.98] **********************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.230.98]
PLAY RECAP *********************************************************************
192.168.230.98 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
注意: 在清单中通过IP地址引用受管主机存在一个问题,那就是难以记住play或临时命令所针对的主机使用了哪个IP地址但是,如果没有可解析的主机名,我们可能必须按IP地址指定主机以进行连接
针对注意可以把该名称的连接指向其IP地址
ansible_host: 192.168.230.98
使用组指定主机
---
- hosts: lab # lab为将对属于该组的成员的主机进行操作
---
- hosts: all # all为一个特别组,能匹配到所有受管主机
---
- hosts: ungrouped # ungrouped为一个特别组,能匹配到清单内不属于任何组的所有受管主机
使用通配符匹配多个主机
需要达成与all主机模式相同的目标,另一种方法是使用通配符(*)
通配符
---
- hosts: '*' #带引号的星号,表示清单中的所有主机都将匹配
---
- hosts: '*.example.com' #可以匹配以.example.com结尾的所有清单名称
---
- hosts: '192.168.2.*' #匹配开头为192.168.2.的主机或主机组的名称
---
- hosts: 'datacenter*' #匹配开头为datacenter的主机或主机组的名称
注意:匹配所有清单名称、主机和主机组。它们不区别名称是DNS名、IP地址还是组,这可能会导致一些意外的匹配
列表
通过逻辑列表来引用清单中的多个条目
主机模式的逗号(,)是用来分隔列表匹配符合任何这些主机模式的所有主机
有以下几种方式:
受管主机的逗号分隔列表,则所有这些受管主机都将是目标:
---
- hosts: httpd,apache,192.168.230.98
组的逗号分隔列表,则属于任何这些组的所有主机都将是目标:
---
- hosts: lab,datacenter1
可以混合使用受管主机、主机组和通配符:
---
- hosts: 'lab,data*,192.168.2.2'
注意:
-
可以用 “:”取代 “,”逗号是首选的分隔符(主要是ipv6地址用作受管主机时)
-
列表中的某一项以与符号(&)开头,则主机必须与该项匹配才能匹配主机模式。它的工作方式类似于逻辑AND
-
在主机模式的前面使用感叹号(!)表示从列表中排除匹配某一模式的主机。它的工作方式类似于逻辑NOT
--- - hosts: 123,abc,!yyp #在执行playbook时,只读取123(组)和abc(组),不会执行yyp(组)
管理动态清单
动态生成清单
- 静态清单是针对管理小型企业基础架构
- 动态清单是针对管理中大型企业基础架构
- 动态清单脚本的使用方式与静态清单文本文件一样
- 清单的位置可以直接在当前的ansible.cfg文件中指定,(用-i指定一个静态清单,–list查看写成动态清单是什么样子)
编写动态清单程序
可以使用任何编程语言编写自定义程序,但传递适当的选项时必须以JSON格式返回清单信息
以JSON格式显示清单文件的内容(运用ansible-inventory --list)
实例:
[root@ansible ansible]# cat inventory
[haha]
1.1.1.1
2.2.2.2
[hehe]
4.4.4.4
5.5.5.5
[root@ansible ansible]# ansible-inventory -i inventory --list
{
"_meta": {
"hostvars": {}
},
"all": {
"children": [
"haha",
"hehe",
"ungrouped"
]
},
"haha": {
"hosts": [
"1.1.1.1",
"2.2.2.2"
]
},
"hehe": {
"hosts": [
"4.4.4.4",
"5.5.5.5"
]
}
}
需要自行编写动态清单脚本可以通过部署动态清单来源,需要自行去了解https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html
开源社区脚本
有需要可以从Ansible GigHub网站自行去学习
https://github.com/ansible/ansible/tree/devel/examples
注意:
- 清单文件的解析顺序不是由文档指定的
- 如果存在多个清单文件,它们会按照字母顺序进行解析
- 如果一个清单源依赖于另一个清单源的信息,则它们的加载顺序可能会确定清单文件是按预期工作还是引发错误
- Ansible会忽略清单目录中以特定后缀结尾的文件
需要更多有关更多信息,请参阅Ansible官方文档。
使用动态清单:
https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html
开发动态清单:
https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html
配置并行
使用forks在ansible中配置并行
- 默认情况下,Ansible会以每5台主机来运行playbook,直至所有主机运行完任务
- 设置目标时不能太大,否则控制节点会瘫痪
查看Ansible所进行的最大同时连接数 ,该数值由Ansible配置文件中的forks参数控制,使用以下方式查看
[root@ansible ~]# ansible-config dump|grep -i fork 第一种方式查看
DEFAULT_FORKS(default) = 5
[root@ansible ~]# ansible-config list|grep -i fork 第二种方式查看
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
[root@ansible ~]# vim /etc/ansible/ansible.cfg 也可以使用配置文件查看
......
#forks = 5
......
管理滚动更新
默认情况下:
依次在5台主机上执行playbook中的第一个任务,然后依次在5台主机上执行playbook中的第二个任务,直到playbook中所有任务全部完成,然后执行handlers中的任务
实例:
---
- name: Rolling update
hosts: webservers
serial: 2
tasks:
- name: latest apache httpd package is installed
yum:
name: httpd
state: latest
notify: restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
serial: 5
先在前5台主机上执行playbook中的所有任务,包括handlers中的任务,然后在另外5台主机上执行playbook中的所有任务,包括handlers中的任务
重要
出于某些目的,每批主机算作在主机子集上运行的完整play。这意味着,如果整个批处理失败,play就会失败,这将导致整个playbook运行失败。
在设置了serial: 2的上一个场景中,如果出现问题并且处理的前2个主机的play失败,则playbook将中止,其余3个主机将不会通过play运行。这是一个有用的功能,因为只有一部分服务器会不可用,使服务降级而不是中断。
playbook解耦的大纲
lamp.yml (组装)
web/apache/main.yml
database/mysql/main.yml
application/php/main.yml
web
apache
files
apr-1.6.1.tar.gz
apr-utils.tar.gz
httpd-2.4.tar.gz (安装包)
vhosts.conf.j2 (配置文件)
httpd.conf.j2
vars
variables.yml
install.yml
config.yml
mian.yml
nginx
...
database
mysql
oracl
mongodb
...
application
php
tomcat
python
perl
...
系统内解耦:
IP
主机名
防护墙
SELINUX
agent
常用软件
yml
管理大型playbook
如果playbook较长或复杂,我们可以将其分开较小的文件(便于管理),简单化就是分成多个较小文件后把他组成一个主要playbook(解耦)
或者将文件中的任务列表插入play。这样可以更轻松地在不同项目中重复使用play或任务序列
包含或导入文件
可以包含内容,也可以导入内容:
- 包含内容是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容。
- 导入内容是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容
导入playbook
- 可以把一个或多个额外playbook导入到主playbook中
- import_playbook功能只能在playbook的顶层使用,不能在play内使用
- 如果导入多个playbook,则将按顺序导入并运行它们
[root@ansible playbook]# cat bash.yml
---
- hosts: "httpd"
tasks:
- name: install apache
yum:
name: httpd
state: present
[root@ansible playbook]# cat apache.yml
---
- hosts: httpd
vars:
- port: 8080
tasks:
- name: config httpd
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
[root@ansible playbook]# cat main.yml
- name: import playbook for install
import_playbook: bash.yml
- name: import playbook for install
import_playbook: apache.yml
[root@ansible playbook]# ansible-playbook main.yml
PLAY [httpd] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.230.98]
TASK [install apache] **********************************************************
ok: [192.168.230.98]
[WARNING]: Found variable using reserved name: port
PLAY [httpd] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.230.98]
TASK [config httpd] ************************************************************
changed: [192.168.230.98]
PLAY RECAP *********************************************************************
192.168.230.98 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@httpd ~]# grep 80 /etc/httpd/conf/httpd.conf
#Listen 12.34.56.78:80
Listen 8080
#ServerName www.example.com:80
还可以使用导入的playbook在主playbook中交替play
[root@ansible playbook]# cat main.yml
---
- hosts: httpd
gather_facts: no
tasks:
- name: start service
service:
name: httpd
state: started
enabled: yes
- name: import playbook for install
import_playbook: bash.yml
- name: import playbook for install
import_playbook: apache.yml
[root@ansible playbook]# ansible-playbook main.yml
PLAY [httpd] *******************************************************************
TASK [start service] ***********************************************************
ok: [192.168.230.98]
PLAY [httpd] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.230.98]
TASK [install apache] **********************************************************
ok: [192.168.230.98]
[WARNING]: Found variable using reserved name: port
PLAY [httpd] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.230.98]
TASK [config httpd] ************************************************************
ok: [192.168.230.98]
PLAY RECAP *********************************************************************
192.168.230.98 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
注意:一个文件有两个”—“,表示分隔
导入和包含任务
可以将任务文件中的任务列表导入或包含在play中
导入任务文件:
- 可以使用import_tasks功能将任务文件静态导入playbook内的play中
- 导入任务文件时,在解析该playbook时将直接插入该文件中的任务
- Playbook中的import_tasks的位置控制插入任务的位置以及运行多个导入的顺序
实例:
[root@localhost project]# cat play.yml
---
- hosts: all
tasks:
- name: install httpd
import_tasks: playbook/install.yml
- name: start httpd
import_tasks: playbook/start.yml
[root@localhost project]# ansible-playbook play.yml
PLAY [all] ****************************************************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************************************
ok: [192.168.230.98]
TASK [install httpd] ******************************************************************************************************************************************************
changed: [192.168.230.98]
TASK [start httpd] ********************************************************************************************************************************************************
changed: [192.168.230.98]
PLAY RECAP ****************************************************************************************************************************************************************
192.168.230.98 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
包含任务文件:
-
可以使用include_tasks功能将任务文件动态导入playbook内的play中
-
在play运行并且这部分play到达前,include_tasks功能不会处理playbook中的内容
-
Playbook内容的处理顺序会影响包含任务功能的工作方式:
- 使用include_tasks功能时,包含时设置的when等条件语句将确定任务是否包含在play中
- 如果运行ansible-playbook --list-tasks以列出playbook中的任务,则不会显示已包含任务文件中的任务
- 相比之下,import_tasks功能不会列出导入任务文件的任务,而列出已导入任务文件中的各个任务
- 不能使用ansible-playbook --start-at-task从已包含任务文件中的任务开始执行playbook
- 不能使用notify语句触发已包含任务文件中的处理程序名称。可以在包含整个任务文件的主playbook中触发处理程序,在这种情况下,已包含文件中的所有任务都将运行
[root@localhost project]# cat playbook.yml
---
- hosts: httpd
tasks:
- name: install httpd
include_tasks: install_httpd.yml
任务文件的用例
- 如果新服务器需要全面配置,则管理员可以创建不同的任务集合,分别用于创建用户、安装软件包、配置服务、配置特权、设置对共享文件系统的访问权限、强化服务器、安装安全更新,以及安装监控代理等。每一任务集合可通过单独的自包含任务文件进行管理
- 如果服务器由开发人员、系统管理员和数据库管理员统一管理,则每个组织可以编写自己的任务文件,再由系统经理进行审核和集成
- 如果服务器要求特定的配置,它可以整合为按照某一条件来执行的一组任务。换句话说,仅在满足特定标准时才包含任务
- 如果一组服务器需要运行某一项/组任务,则它/它们可以仅在属于特定主机组的服务器上运行
管理任务文件
为方便管理,可以创建专门用于任务文件的目录,并将所有任务文件保存在该目录中。然后playbook就可以从该目录包含或导入任务文件。这样就可以构建复杂的playbook,同时简化其结构和组件的管理
为外部play和任务定义变量
使用Ansible的导入和包含功能将外部文件中的play或任务合并到playbook中极大地增强了在Ansible环境中重用任务和playbook的能力
[root@localhost project]# cat playbook/install.yaml
- name: install {{ package }}
yum:
name: "{{ package }}"
state: present
[root@localhost project]# cat playbook/service.yaml
- name: start {{ package }} service
service:
name: "{{ package }}"
state: started
//查看变量文件
[root@localhost project]# cat files/vars.yaml
package: httpd
//查看主要执行文件
[root@localhost project]# cat playbook/main.yaml
---
- hosts: all
vars_files:
../files/vars.yaml
tasks:
- import_tasks: install.yaml
- import_tasks: service.yaml
使用相同的技术使play文件更具有可重用性
[root@localhost project]# cat playbook/mariadb.yaml
---
- hosts: all
vars_files:
../files/vars.yaml
tasks:
- name: install {{ package }}
yum:
name: "{{ package }}"
state: present
[root@localhost project]# cat files/vars.yaml
package: mariadb-server
[root@localhost project]# cat playbook/main.yaml
- name: isntall package
import_playbook: mariadb.yaml