Ansible-playbook剧本
playbook
概述
playbook由YMAL语言编写。YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。通过tasks调用ansible的模板将多个play组织在一个playbook中运行。
三要素
剧本 | playbook |
---|---|
场地 | 主机组hosts |
演员 | 授权执行的用户 remote_user |
故事情节 | 执行的任务 tasks(调用的是各种ansible模块) |
组成结构
Tasks∶任务,即调用模块完成的某操作
Variables∶变量
Templates; 模板
Handlers:处理器,当某条件满足时,触发执行的操作
ansible通过不同的模块实现相应的管理,管理的方式通过定义的清单文件(hosts)所管理的主机包括认证的方式连接的端口等。
用法示例
hosts: node1 #定义的主机组,即应用的主机
vars: #定义变量
http_port: 80
max_clients: 200
user: root
tasks: #执行的任务
- name: ensure apache is at the latest version #标题
yum: pkg=httpd state=latest #操作
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify: #调用,调取 关联自动加载handlers模块
- restart apache
- name: ensure apache is running
service: name=httpd state=started #保证httpd服务器保持开启状态
handlers: #处理器
- name: restart apache
service: name=httpd state=restarted #服务重启,先关闭后启动,stop状态restarted无意义,start状态有意义
执行格式:
ansible-playbook [yaml文件名]
常用测试命令:
ansible-play play.yaml --syntax-check #检查语法
ansible-play play.yaml --list-task #检查task任务
ansible-play play.yaml --list-hosts #检查生效的主机
ansible-play play-yaml --start-at-task='ensure is runnning' #从某个任务开始执行
参数 (免密登录)∶
-k(-ask-pass)用来交互输入ssh密码
-K(-ask-become-pass) 用来交互输入sudo密码
-u 指定用户
hosts和users差别
hosts: webserver 指定主机组,可以是-一个或多个组。
remote user: root 指定远程主机执行的用户名
YAML
概述
YAML:是一种非标记语言。是用来写配置文件的语言,非常简洁和强大。和其他语言类似,也可以表达散列表、标量等数据结构。结构通过空格来展示;序列里配置项通过 - 来代表; Map里键值用 : 来分隔;YAML的扩展名为 yaml
基本语法规则
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
支持的数据结构
对象:键值对的集合,又称为映射(mapping) /哈希(hashes) /字典(dictionary)
例如:
name:Easy Developer
变量名:对象名 属性
数组: 一组按次序排列的值,又称为序列(sequence) / 列表(list)
例如:
-blue
-red
纯量: 单个的,不可再分的值
例如:
number: 10.30
sure: true
变量名:数值
示例
环境和部署流程见: ansible自动化运维-含详细模块介绍
易错点:
‘-’ 不加
‘-’和‘:’后的空格不加
格式一定要对齐,不能随便缩进,缩进表示层级关系
tab键不要用,不识别
连通性脚本
vim ping.yaml
- hosts: node1
remote_user: root
tasks:
- name: connection
ping:
remote_user: root
ansible-playbook ping.yaml --syntax-check
ansible-playbook ping.yaml
指定远程用户切换用户执行任务
在node1创建用户
useradd zhusan
passwd zhusan
master
vim zhusan.ymal
- hosts: node1
remote_user: root
become: yes
become_user: zhusan
tasks:
- name: copy
copy: src=/etc/fstab dest=/home/zhusan/fstab.bak
ansible-playbook zhusan.yaml --syntax-check
ansible-playbook zhusan.yaml
查看
tasks列表和action
Play的主体部分是task列表, task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务,在运行playbook时(从上到下执行) ,如果一个host执行task失败,tasks会回滚到报错前的状态,即在报错前的操作命令会执行,但报错后的命令不会执行;在修正playbook中的错误后,重新执行即可。
Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为其结果一致。
每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。
定义一个task, 常见的格式:”module: options" 例如: yum: name=nginx
ansible的自带模块中,command模块和shell模块无需使用key=value格式
回滚
node1/2都未曾安装apache,master编写剧本,写错started。
vim http.yaml
- hosts: node1
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=start enabled=true
- name: touch index
copy: content="shuaige" dest=/var/www/html/index.html
ansible-playbook http.yaml --syntax-check
ansible-playbook http.yaml
查看
忽略错误,继续执行。
在报错之后添加ignore_errors: True 可以忽略错误,强制返回成功,不影响之后的任务执行;
在对不确定某一条任务能否可以顺利的执行时可以,使用添加该命令,以保证后续进程继续执行。
- hosts: node1
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=start enabled=true
ignore_errors: true
- name: touch index
copy: content="shuaige" dest=/var/www/html/index.html
查看
针对不同的节点用户分别进行执行对应不同的任务
vim butong.yaml
- hosts: node1
remote_user: root
tasks:
- name: create apache group
group: name=apache system=yes gid=888
- name: create apache user
user: name=apache system=yes uid=888 group=apache
- hosts: node2
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=started enabled=true
ansible-playbook butong.yaml --syntax-check
ansible-playbook butong.yaml
查看
变量配置
Handlers 简介
Handlers也是一些task的列表,和一般的task并没有什么区别。是由通知者进行的notify,如果没有被notify, 则Handlers不会执行,假如被notify了, 则Handlers被执行。不管有多少个通知者进行了notify, 等到play中的所有task执行完成之后,handlers也只会被执行一次。
变量形式:
定义在剧本中,直接使用
定义在输入命令中,直接传输
利用系统自带的,固定变量
定义在hosts配置文件中
在剧本中定义变量
卸载两个节点的http包,修改下剧本即可。
- hosts: node1
remote_user: root
vars:
- a: httpd
tasks:
- name: install httpd
yum: name={{a}}
- name: start httpd
service: name={{a}} state=started enabled=true
- name: touch index
copy: content="shuaige" dest=/var/www/html/index.html
查看
通过ansible命令传递
删除剧本中a的赋值,即
vars:
- a:
运行
ansible-playbook http.yaml -e "a=httpd"
固定变量 (系统变量)
vi xitong.yaml
- hosts: node2
remote_user: root
tasks:
- name: copy
copy: content="{{ansible_all_ipv4_addresses}}" dest=/opt/address.text
#捕捉获取节点中ip地址,到目标位置
查看
在hosts配置文件中定义
vim /etc/ansible/hosts #添加
192.168.1.30 num="123123"
vim xitong.yaml
- hosts: node2
remote_user: root
tasks:
- name: copy
copy: content="{{ansible_all_ipv4_addresses}},{{num}}" dest=/opt/address.text
查看
条件判断
如果需要根据变量、facts (setup) 或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when。在task后添加when子句即可使用条件测试: when子句支持jinjia2表达式或语法。
添加条件判断(when)
单条件判断
多条件判断
组条件判断:when (“条件1”)or(“条件2”)
自定义条件判断:先定义变量,在when里面引用变量
单条件判断
查看系统版本
master
vim pd.yaml
- hosts: node1
remote_user: root
tasks:
- name: "shutdown CentOS"
command: /sbin/shutdown -h now
when: ansible_distribution == "CentOS"
出现报错,无法通过ssh连接到主机,原因node1系统关闭
多条件判断
- hosts: node2
remote_user: root
tasks:
- name: "shutdown CentOS"
command: /sbin/shutdown -h now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"
同理
组条件判断
vim tj.yaml
- hosts: node1
remote_user: root
tasks:
- name: "shutdown CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or(ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
skipped:跳过
迭代
当有需要重复性执行的任务时,可以使用迭代机制,其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素
组成结构:
for item(变量) in with_items(集合)
do
命令
done
安装软件
- hosts: node2
remote_user: root
tasks:
- name: install apache tomcat
yum: name={{item}}
with_items:
- httpd
- tomcat
也可以自己定义
添加用户到组
在node1
useradd zhusan
useradd taosi
groupadd mengwu
groupadd shaoliu
master
- hosts: node1
remote_user: root
tasks:
- name: add users
user: name={{item.name}} state=present group={{item.groups}}
with_items:
- { name: 'zhusan',groups: 'mengwu'}
- { name: 'taosi',groups: 'shaoliu'}
查看
Templates模板
概述
可以将带有参数的配置文件传递到目标地址,可以对文件进行属组属主的修改以及备份。Jinja是基于Python的模板引擎。template类是Jinja的另一个重要组件,可以看作一个编译过的模块文件,用来生产目标文本,传递Python的变量给模板去替换模板中的标记。
通过模板配置节点设备设置
node2 已经安装 apache 服务
master拷贝配置文件
mkdir httpd
scp root@192.168.1.30:/etc/httpd/conf/httpd.conf httpd
修改需要到其他节点上的配置为变量
vim httpd.conf
Listen 80 修改 Listen {{ip_port}} # 变量为ip_port
ServerName www.example.com:80 修改 ServerName {{server_name}}并去掉注释
MaxClients {{num}} #添加最大连接数,变量为 num
将此配置文件修改为模板文件
mv httpd.conf httpd.conf.j2
在ansible 配置文件中标识添加值
vi /etc/ansible/hosts
[node1]
192.168.1.20 ip_port=192.168.1.20:80 server_name=www.aa.com:80 num=666
设置脚本
- hosts: node1
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: config file
template: src=/root/httpd/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
handlers :
- name: restart httpd
service: name=httpd state=restarted enabled=true
查看
tags模块
单标签任务
在一个playbook中,我们一般会定义很多个task,如果我们只想执行其中的某一个或者多个task时就可以使用tags标签功能。
- hosts: node1
remote_user: root
tasks:
- name: mkdir
file: path=/opt/aaa state=directory
tags:
- q
- name: touch
file: path=/opt/bbb state=touch
查看
多标签任务
当剧本中有多个任务,但存在两个标签任务,且标签名一样时,执行时,只执行这两给任务
删除节点的目录
- hosts: node1
remote_user: root
tasks:
- name: mkdir
file: path=/opt/aaa state=directory
tags:
- q
- name: touch
file: path=/opt/bbb state=touch
- name: touch
file: path=/opt/ccc state=touch
tags:
- q
查看
always
事实上不光可以为单个或多个task指定同一个tags,playbook还提供了一个特殊的tags为always,作用就是当使用always当tags的task时,无论执行哪个tags时,定义有always的任务必须强制执行
同样的删除节点的目录和文件
- hosts: node1
remote_user: root
tasks:
- name: mkdir
file: path=/opt/aaa state=directory
tags:
- q
- name: touch
file: path=/opt/bbb state=touch
tags:
- always
- name: touch
file: path=/opt/ccc state=touch
tags:
- q
查看
roles模块
概述
Ansible roles是为了层次化、结构化地组织Playbook。roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们。roles一般用于基于主机构建服务的场景中,在企业复杂业务场景中应用的频率很高。以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;相当于函数的调用把各个功能切割成片段来执行。
roles内各目录
files: 用来存放由copy模块或script模块调用的文件
templates: 用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件
tasks: 此目录应当包含一个main.yml文件, 用于定义此角色的任务列表,此文件可以使用
include包含其它的位于此目录的task文件
handlers: 此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作
vars: 此目录应当包含一个main.yml文件,用于定义此角色用到的变量
defaults: 此目录应当包含一个main.yml文件,用于为当前角色设定默认变量
meta: 此目录应当包含一个main.yml文件, 用于定义此角色的特殊设定及其依赖关系
配置安装LAMP在节点设备上
思路:
先把lamp架构拆分成三部分:apache、mysql、php
通过roles模块,创建这三部分的功能模块以及main.yml文件
通过配置这三部分所需模块的main.yml文件,来完善模块实现的功能
配置脚本,通过roles模块来调用这三部分,完成架构的部署
创建这三部分的roles的功能模块
cd /etc/ansible/roles/
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
ls
创建各模块的main.yml文件(文件内容为空)
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml
配置这三部分所需模块的main.yml文件
apache部分
cd /etc/ansible/roles/httpd/tasks/
vim main.yml
- name: install apache
yum: pkg={{servername}} state=latest #引用变量
cd /etc/ansible/roles/httpd/vars/
vim main.yml
servername: httpd #定义变量
mysql模块
cd /etc/ansible/roles/mysql/tasks/
vim main.yml
- name: install mysqld
yum: pkg={{servername}} state=latest
vim ../vars/main.yml
servername: mariadb* #mariadb为数据库的一种(比mysql要简便)
php模块
cd ../../php/tasks/
vi main.yml
- name: install php
yum: pkg={{servername}} state=latest
cd ../vars/
vim main.yml
servername: php
编写脚本,通过roles模块调用这三部分
cd /etc/ansible/
vim lamp.yml
- hosts: mysql node1
remote_user: root
roles:
- httpd
- mysql
- php
ansible-playbook lamp.yml --syntax-check
ansible-playbook lamp.yml
查看