自动化运维工具Ansible的脚本——playbook剧本

一、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 116 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 110 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 116 19:36 hosts
drwxr-xr-x. 2 root root   6 116 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';

猜你喜欢

转载自blog.csdn.net/F2001523/article/details/112853024