文章目录
一、playbook剧本概述
1.剧本的三要素
剧本 playbook
1.场地 1.主机组hosts
2.演员 2.授权执行的用户 remote_user
3.故事情节 3.执行的任务 tasks(调用的是各种ansible模块)
2.剧本的组成
通过task调用ansible的模块将多个play组织在一个playbook中运行,playbook本身由一下各部分组成:
1.Tasks:任务,即调用ansible模块完成的某操作
2.Variables:自定义变量
3.Templates:模板(主要对修改配置文件非常的友好)
4.Handlers:处理器,当某条件满足时,触发执行的操作
5.Roles:角色
3.playbook的一些常用命令
# ansible-playbook first.yml --syntax-check #检查yaml文件的语法是否正确
# ansible-playbook first.yml --list-task #检查tasks任务
# ansible-playbook first.yml --list-hosts #检查生效的主机
# ansible-playbook first.yml --start-at-task='Copy Nginx.conf' #指定从某个task开始运行
# ansible-playbook first.yml -k #用来交互输入ssh密码
# ansible-playbook first.yml -K #用来交互输入sudo密码
# ansible-playbook first.yml -u #指定用户
二、YAML概述
2.1 什么是YAML?
- YAML:是一种非标记语言。是用来写配置文件的语言,非常简洁和强大
- YAML语法和其他语言类似,也可以表达散列表、标量等数据结构结构通过空格来展示;
- 序列里配置项通过-来代表;
- Map里的键值用:来分隔;
- YAML的扩展名为yaml
2.2 基本语法规则
- 1.大小写敏感
- 2.使用缩进表示层级关系(同级别的格式要对齐)
- 3.缩进时不允许使用Tab键,只允许使用空格
- 4.缩进的空格数目不重要,只要相同层级的元素左侧对其即可
- 5.’#'表示注释
2.3 YAML支持的数据结构
1.对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典
例如:name:Example Developer
键 值
2.数组:一组按次序排序的值,又称为序列(squence) / 列表(list)
例如:-Apple
-Orange
3.纯量:单个的、不可再分的值
例如:number:12.30
sure: true
hosts和users的介绍
- hosts: mysql #指定主机组,可以是一个或多个组
remote_user: root #指定远程主机执行的用户名
三、实例操作
3.1 环境
master:192.168.1.10
node1: 192.168.1.11
node2:192.168.1.12
3.2 实操
3.2.1 测试主控端与被控端的连通性性脚本
[root@master ~]# vim demo.yaml
- hosts: all
remote_user: root
tasks:
- name: test connection
ping:
remote_user: root 指定远程主机执行tasks的运行用户为root
[root@master ~]# ansible-playbook demo.yaml --syntax-check
[root@master ~]# ansible-playbook demo.yaml
3.2.2 指定远程主机sudo切换用
成功后,后面如在处理事务或执行任务当中,都是mysql用户来处理
[root@master ~]# vim demo.yaml
- hosts: all
remote_user: root
become: yes #之前用的是sudo,现在用的是become
become_user: mysql #指定sudo用户为root
[root@master ~]# ansible-playbook demo.yaml --syntax-check
[root@master ~]# ansible-playbook demo.yaml
3.2.3 安装httpd,关闭防火墙脚本
[root@master ~]# vim demo.yaml
- hosts: mysql
remote_user: root
tasks:
- name: stop firewalld #关闭防火墙
service: name=firewalld state=stopped
- name: disable selinux #关闭核心防护
command: '/sbin/setenforce 0'
- name: install httpd #安装httpd
yum: name=httpd
- name: start httpd #开启httpd
service: name=httpd state=started
[root@master ~]# ansible-playbook demo.yaml --syntax-check
[root@master ~]# ansible-playbook demo.yaml
3.2.4 安装apache服务并开启服务,创建测试网页,关闭防火墙
[root@master ~]# ansible-playbook demo.yaml --syntax-check
- hosts: mysql
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=started
- name: stop firewalld
service: name=firewalld state=stopped
- name: touch index
copy: content="this is the fa" dest=/var/www/html/index.html
[root@master ~]# ansible-playbook demo.yaml 运行
测试:
在节点服务器上
在物理机上测试访问节点的apache页面
3.2.5 ignore_errors忽略
在我们编写脚本完成后,执行脚本的时候如前面模块语句错误时会发生回滚,就不会继续执行下面的模块语句了,这个时候我们就可以利用一个叫ignore_errors: True的参数,它就作用就就是如果你前面执行的错误了,它会直接跳过那个错误的继续往下执行
[root@master ~]# vim demo.yaml
- hosts: mysql
remote_user: root
tasks:
- name: disable selinux
command: '/sbin/setenforce 0'
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=http state=started #这边我故意少加一个d
- name: stop firewalld
service: name=firewalld state=stopped
[root@master ~]# ansible-playbook demo.yaml --syntax-check
[root@master ~]# ansible-playbook demo.yaml #执行的时候会报错
然后去节点2服务器上查看
[root@node2 ~]# rpm -q httpd
[root@node2 ~]# systemctl status httpd
[root@node2 ~]# systemctl status firewalld
可以看到错误是开启httpd端口那边报错发生了回滚,所以后面的端口没有被开启,但是下面的防火墙也没有关闭掉
这个时候我们只需要加入ignore_errors: True的参数
[root@master ~]# vi demo.yaml
- hosts: mysql
remote_user: root
tasks:
- name: disable selinux
command: '/sbin/setenforce 0'
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=http state=started
ignore_errors: True #添加:忽略错误
- name: stop firewalld
service: name=firewalld state=stopped
[root@master ~]# ansible-playbook demo.yaml
再次去节点2上去查看可以看到httpd端口因为报错所以没有执行,但是下面关闭防火墙的命令依然执行了
3.2.6 Handlers介绍
在playbook中充当处理器,当某条件满足时,触发执行的操作
- Handlers也是一些task的列表,和一般的task并没有什么区别
- 是由通知者进行的notify,如果没有被notify,则Handlers不会执行,假如被notify了,则Handlers被执行
- 不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次
3.2.6.1 示例
- hosts: mysql
remote_user: root
tasks:
- name: install httpd package # 安装最新版本服务
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf # 拷贝文件
notify:
- restart httpd
- name: start httpd service
service: enabled=true name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
拷贝完后文件需要重启服务,notify 用了 restart httpd, handlers 搜索到了 restart httpd 就会自动去执行,然后再执行 start httpd service;若是没有搜索到 restart httpd,则不会执行 start httpd service
引入变量
[root@master ~]# vi aaa.yaml
- hosts: server1
remote_user: root
vars: # 引用变量
- aaa: tomcat # tomcat 引用变量为 aaa
tasks:
- name: install httpd
yum: name={{aaa}}
- name: start httpd
service: name={{aaa}} state=started
[root@master ~]# ansible-playbook aaa.yaml
测试
[root@node2 ~]# rpm -q tomcat
tomcat-7.0.76-2.el7.noarch
[root@node1 ~]# systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; vendor preset: disabled)
Active: active (running) since 日 2021-01-16 06:56:22 CST; 34s ago
Main PID: 69323 (java)
3.2.7 playbook定义变量的4个场景
- 1.在hosts主机清单中定义变量
- 2.在剧本中定义变量
- 3.在命令中 “-e 想定义的变量” 的格式来定义
- 4.还有一种特殊的场景,直接可以使用系统内置(自带)的变量
3.2.7.1 在hosts主机清单中定义变量
[root@master ~]# vi k.yaml
- hosts: mysql
remote_user: root
vars:
- user: # 引用变量为空
tasks:
- name: add new user
user: name={{user}}
[root@master ~]# vi /etc/ansible/hosts
测试
[root@node2 ~]# id fa
uid=1000(fa) gid=1000(fa) 组=1000(fa),10(wheel)
3.2.7.2 通过在剧本中定义变量
[root@master ~]# vi demo.yaml
- hosts: mysql
remote_user: root
vars:
- user: lisi
tasks:
- name: add new user
user: name={{user}}
测试
[root@node2 ~]# id lisi
uid=1002(lisi) gid=1002(lisi) 组=1002(lisi)
3.2.7.3 在命令中 “-e 想定义的变量” 的格式来定义
[root@master ~]# vi demo.yaml
- hosts: mysql
remote_user: root
vars:
- user:
tasks:
- name: add new user
user: name={{user}}
测试
[root@node2 ~]# id zhangsan
uid=306(zhangsan) gid=306(mysql) 组=306(mysql)
3.2.7.4 直接ansible中内置的变量
[root@master ~]# vi demo.yaml
- hosts: mysql
remote_user: root
tasks:
- name: copy file
copy: content="{{ansible_all_ipv4_addresses}}" dest=/opt/addr.txt
[root@master ~]# ansible-playbook demo.yaml
测试
统计的是它自已的虚拟地址与IP地址
[root@node2 ~]# cat /opt/addr.txt
["192.168.122.1", "192.168.1.12"]
3.2.8 条件测试
如果是名叫CentOS的机器就关机
[root@master ~]# vim demo.yaml
- hosts: mysql
remote_user: root
tasks:
- name: "shutdown CentOS"
command: /sbin/shutdown -h now -h是关机,-r是重启
when: ansible_distribution == "CentOS"
执行成功后,会报几行红字,那个其实不是报错,因为脚本执行后机器关机后,因为连接不上机器导致的,属于正常现象
3.2.9 Templates模板
3.2.9.1 作用
主要用于用户修改服务中的配置文件,与传统运维不同的是,它可以根据不同的节点,而产生出不同变量所产生出的配置文件,从而实现一键化,大大减轻了资源的占用率以及手动配置的时间
3.2.9.2 示例
实现效果:
2台被控端node1有安装apache,node2没有安装,我们要通过templates来实现node2节点也安装上apache而且配置文件不和node1一致,而是自已对应的配置文件
实操:
首先先远程复制控制端上把node1上的apache配置文件拷到当前目录
[root@master ~]# scp root@192.168.1.11:/etc/httpd/conf/httpd.conf ./
[root@master ~]# mv httpd.conf demo/
[root@master ~]# cd demo/
[root@master demo]# ll
总用量 12
-rw-r--r-- 1 root root 11753 1月 16 21:26 httpd.conf
因为这个配置文件到达其他节点会发生改变所以需要设置变量
[root@master ~]#cd demo
[root@master demo]# vi httpd.conf
设置端口变量为:Listen {{http_port}}
设置域名:ServerName {{server_name}}
连接数:MaxClients {{access_num}}
把httpd.conf移动都httpd.conf.j2中为模板引擎
j2又称jinjia2,是基于python的模板引擎,它在templates模块中可以直接识别使用,而产生一个指定性的文件
[root@master demo]# mv httpd.conf httpd.conf.j2
因为上面只设置了变量,没有设置值,需要给它找一个地方设置值,从而才可以产生配置文件
在hosts名单中定义变量值
[root@master demo]# vi /etc/ansible/hosts
编写编排的yaml文件
- hosts: mysql
remote_user: root
vars:
- server: httpd
tasks:
- name: install httpd #安装apache
yum: name={{server}} state=latest
- name: config file #使用template模块来生成配置文件
template: src=/root/demo/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify: #使用notify来调用
- restart httpd
- name: start httpd
service: name={{server}} state=started
handlers:
- name: restart httpd
service: name{{server}} state=restarted enabled=true
[root@master ~]# ansible-playbook apache.yaml --syntax-check
[root@master ~]# ansible-playbook apache.yaml
测试
[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node2 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 六 2021-01-16 22:45:46 CST; 9min ago
Docs: man:httpd(8)
man:apachectl(8)
查看配置文件是否修改
[root@node2 ~]# vi /etc/httpd/conf/httpd.conf
Listen 192.168.1.12:80
ServerName www.kgc.com:80
MaxClients 500
3.2.10 tags模块
3.2.10.1 作用
如你有写了很长的playbook剧本,当剧本中很多任务时,你想全部执行也没事,但可能你执行想执行其中的一部分任务,或者是执行那一条任务,而不是执行全部的任务,这个时候我们可以利用tags标签模块来指定实现一部分任务
3.2.10.2 示例
[root@master ~]# vi hosts.yaml
- hosts: mysql
remote_user: root
tasks:
- name: copy hosts01
copy: src=/etc/hosts01 dest=/opt/hosts
tags: # 第一个任务打上标签 a
- a
- name: touch hosts02
file: path=/opt/hosts state=touch
[root@master ~]# ansible-playbook hosts.yaml --tags="a"
# 执行任务调用 a标签,只会执行第一个任务,后面第二个任务不会执行
测试
只执行了打上标签的任务
[root@node2 ~]# cd /opt/
[root@node2 opt]# ll
总用量 2
-rw-r--r--. 1 root root 158 1月 10 19:36 hosts
再次在后面添加一个任务,并打上相同的标签
[root@master ~]# vi hosts.yaml
- hosts: webserver
remote_user: root
tasks:
- name: copy hosts01
copy: src=/etc/hosts dest=/opt/hosts
tags:
- b
- name: touch hosts02
file: path=/opt/hosts02 state=touch
- name: mkdir directory
file: path=/opt/hosts03 state=directory
tags:
- b
[root@master ~]# ansible-playbook hosts.yaml --tags="b"
# 依旧执行任务调用 b 标签
测试
执行了打上相同标签的任务
[root@node1 ~]# cd /opt/
[root@node1 opt]# ll
总用量 4
-rw-r--r--. 1 root root 158 1月 16 19:36 hosts
drwxr-xr-x. 2 root root 6 1月 16 19:36 hosts03
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';