目录
3.play剧本执行报错 SELinux is disabled
一、理论
1.playbooks
(1)概念
ansbile-playbook是一系统ansible命令的集合,其利用yaml 语言编写,运行过程,ansbile-playbook命令根据自上而下的顺序依次执行。同时,playbook开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。

(2)组成
Target section: 定义将要执行 playbook 的远程主机组
Variable section: 定义 playbook 运行时需要使用的变量
Task section: 定义将要在远程主机上执行的任务列表
Handler section: 定义 task 执行完成以后需要调用的任务
(3)目录层
其对应的目录层为五个,如下:
一般所需的目录层有:(视情况可变化)
vars 变量层
tasks 任务层
handlers 触发条件
files 文件
template 模板
(4)Playbook的核心元素
Tasks:任务,由模板定义的操作列表。调用模块完成的某操作,一个任务对应一个模块的调用。
Variables:变量
Templates:模板,即使用模板语法的文件
Handlers:由特定条件触发的Tasks
Roles:角色。可以组织 playbook。基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers
2.YAML
(1)概念
YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。
(2)特性
YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。其特性:
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
(3)语法
YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。下面是一个示例。
---.表明YAML一个文件的开始
#表中的所有成员都开始于相同的缩进级别, 并且使用一个 "- " 作为开头(一个横杠和一个空格):如:
---
# 一个美味水果的列表
- Apple
- Orange
- Banana
- Mango
#一个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格):如
---
# 一位职工的记录
name: Example Developer
job: Developer
skill: Elite
#字典也可以写成一行,但要用大括号{}把它括起来
---
# 一位职工的记录
{name: Example Developer, job: Developer, skill: Elite}
3.使用ansible批量安装apache服务
(1) 环境
表1 环境
| 192.168.204.199 | ansible | |
| 192.168.204.69 | 客户端 | webservers |
| 192.168.204.186 | 客户端 | dbservers |

(2)配置文件
vim test1.yaml
--- #yaml文件以---开头,以表明这是一个yaml文件,可省略
- name: first play #定义一个play的名称,可省略
gather_facts: false #设置不进行facts信息收集,这可以加快执行速度,可省略
hosts: dbservers #指定要执行任务的被管理主机组,如多个主机组用冒号分隔
remote_user: root #指定被管理主机上执行任务的用户
tasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
- name: test connection #自定义任务名称
ping: #使用 module: [options] 格式来定义一个任务
- name: disable selinux
command: '/sbin/setenforce 0' #command模块和shell模块无需使用key=value格式
ignore_errors: True #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
- name: disable firewalld
service: name=firewalld state=stopped #使用 module: options 格式来定义任务,option使用key=value格式
- name: install httpd
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件
notify: "restart httpd" #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
- name: start httpd service
service: enabled=true name=httpd state=started
handlers: #handlers中定义的就是任务,此处handlers中的任务使用的是service模块
- name: restart httpd #notify和handlers中任务的名称必须一致
service: name=httpd state=restarted
##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
运行playbook
ansible-playbook test1.yaml
补充参数
-k(–ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码
-u:指定用户
ansible-playbook test1.yaml --syntax-check #检查yaml文件的语法是否正确
ansible-playbook test1.yaml --list-task #检查tasks任务
ansible-playbook test1.yaml --list-hosts #检查生效的主机
ansible-playbook test1.yaml --start-at-task='install httpd' #指定从某个task开始运行
4.定义、引用变量
vim test2.yaml
- name: second play
hosts: dbservers
remote_user: root
vars: #定义变量
- groupname: mysql #格式为 key: value
- username: nginx
tasks:
- name: create group
group: name={
{groupname}} system=yes gid=306 #使用 {
{key}} 引用变量的值
- name: create user
user: name={
{username}} uid=306 group={
{groupname}}
- name: copy file
copy: content="{
{ansible_default_ipv4}}" dest=/opt/vars.txt #在setup模块中可以获取facts变量信息
在命令行里定义变量
ansible-playbook test2.yaml -e "username=nginx"
dbservers验证
[root@mysql01 home]# cat /etc/passwd | grep nginx
nginx:x:306:306:Nginx web server:/var/lib/nginx:/sbin/nologin
5.指定远程主机sudo切换用户
---
- hosts: dbservers
remote_user: gzia
become: yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become_user: root #指定sudo用户为root
执行playbook时:ansible-playbook test1.yml -K <密码>
6.when条件判断
在Ansible中,提供的唯一一个通用的条件判断是when指令,当when指令的值为true时,则该任务执行,否则不执行该任务。
when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务
vim test3.yaml
---
- hosts: all
remote_user: root
tasks:
- name: shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.204.186" #when指令中的变量名不需要手动加上 {
{}}
或
when: inventory_hostname == "<主机名>"
运行playbook
ansible-playbook test3.yaml
dbservers查看
[root@mysql01 ~]# cat /etc/passwd
……
test1:x:1001:1001::/home/test1:/bin/bash
test2:x:1002:1002::/home/test2:/bin/bash
7.迭代
Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。
vim test4.yaml
---
- name: play1
hosts: dbservers
gather_facts: false
tasks:
- name: create directories
file:
path: "{
{item}}"
state: directory
with_items: #等同于 loop:
- /tmp/test1
- /tmp/test2
- name: add users
user: name={
{item.name}} state=present groups={
{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
或

本文围绕Ansible展开,介绍了playbooks、YAML等理论知识,包括其概念、特性和语法。通过实验展示了使用Ansible批量安装apache服务、定义引用变量等操作。同时,列举了play剧本执行时出现的多种报错及解决方法,最后总结了playbook的组成和使用要点。

被折叠的 条评论
为什么被折叠?



