linux ansible Playbook剧本

实验环境

网络环境

底层系统

系统都为:Red Hat Enterprise Linux release 8.0 (Ootpa)

ansible主机清单

了解剧本前,应先熟悉ansible常用模块的使用方法,linux ansble常用模块详解

 

Playbook

playbook 剧本是由一个或多个“play”组成的列表。
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作。
Playbook 文件是采用YAML语言编写的。

执行配置文件

playbook配置文件使用YAML语法,具有简洁明了、结构清晰等特点。playbook配置文件类似于shell脚本,是一个YAML格式的文件,用于保存针对特定需求的任务列表。上面介绍的ansible命令虽然可以完成各种任务,但是当配置一些复杂任务时,逐条输入就显得效率非常低下。

更有效的方案是在playbook配置文件中放置所有的任务代码,利用ansible-playbook命令执行该文件,可以实现自动化运维。YAML文件的扩展名通常为.yaml或.yml。

核心元素

首先介绍剧本的核心元素,编写一个简单的yml文件能更清楚明了的说明:

列出主机列表,确认无误

[root@ansible /]# grep -v ^# /etc/ansible/hosts |grep -v ^$
[web1]
192.168.26.2
192.168.26.3
[web2]
192.168.26.4

编写剧本文件

所有的“-”和“:”后面均有空格,剧本对格式要求极为严格!!!,注意对齐极为重要!!!
[root@ansible /]# vi /etc/ansible/test.yml
---
- hosts: web1                       <!--针对web1组中的操作-->                               
  remote_user: root                 <!--远端执行用户身份为root-->
  tasks:                            <!--任务列表--> 
    - name: "创建组"                <!--任务名称--> 
      group: name=wlclass system=yes    <!--执行group模块,创建组-->            
      tags: group                       <!--创建tag标签-->  
    - name: "创建用户"
      user: name=wl1 state=present password=123456 group=wlclass
      tags: user
- hosts: web2
  remote_user: root
  tasks:
    - name: "传输文件"
      copy: src=/data/test.txt dest=/data
      tags: file

实现的效果:在web1组中创建wlclass组并创建wl1用户添加至该组;在web2组中将ansible服务器中的test.txt文件传输至web2组的data文件夹内

按照剧本文件开始介绍核心元素

  • hosts:              任务的目标主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息;
  • remote_user:远程主机上,运行此任务的默认身份为root;
  • tasks:              任务,即定义的具体任务,由模块定义的操作列表;
  • handlers:        触发器,类似tasks,只是在特定的条件下才会触发的任务。某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers进行触发执行;
  • roles:               角色,将hosts剥离出去,由tasks、handlers等所组成的一种特定的结构集合;

剧本用法

playbook文件定义的任务需要通过ansible-playbook命令进行调用并执行。ansible-playbook命令用法如下:

 ansible-playbook [option] [yml]

常用选项:

  • –syntax-check:     检测yaml文件的语法;
  • -C(—check):      预测试,不会改变目标主机的任何设置;
  • –list-hosts:           列出yaml文件影响的主机列表;
  • –list-tasks:           列出yaml文件的任务列表;
  • –list-tags:             列出yaml文件中的标签;
  • -t TAGS(—tags=TAGS):      表示只执行指定标签的任务;
  • –skip-tags=SKIP_TAGS:        表示除了指定标签的任务,执行其他任务;
  • –start-at-task=START_AT:   从指定的任务开始往下运行;

示例:

检查语法是否有问题

[root@ansible /]# ansible-playbook --syntax-check /etc/ansible/test.yml 
playbook: /etc/ansible/test.yml    这样子表示就没有问题

执行任务!!!

[root@ansible /]# ansible-playbook /etc/ansible/test.yml

列出剧本内的主机

[root@ansible /]# ansible-playbook --list-hosts /etc/ansible/test.yml 

playbook: /etc/ansible/test.yml

  play #1 (web1): web1  TAGS: []
    pattern: ['web1']
    hosts (2):
      192.168.26.2
      192.168.26.3

  play #2 (web2): web2  TAGS: []
    pattern: ['web2']
    hosts (1):
      192.168.26.4

 

触发器

需要触发才能执行的任务,当之前定义在tasks中的任务执行成功后,若希望在此基础上触发其他任务,这时就需要定义handlers。例如,当通过ansible的模块对目标主机的配置文件进行修改之后,如果任务执行成功,可以触发一个触发器,在触发器中定义目标主机的服务重启操作,以使配置文件生效。handlers触发器具有以下特点:

  • handlers是Ansible提供的条件机制之一。
  • handlers和task很类似,但是它只在被task通知的时候才会触发执行。
  • handlers只会在所有任务执行完成后执行。
  • 而且即使被通知了很多次,它也只会执行一次。
  • handlers按照定义的顺序依次执行。

示例

web1组已提前按照完成httpd服务,并且是运行状态

监听一下web1组80端口

[root@ansible /]# ansible web1 -m shell -a "netstat -anpt |grep 80" 
192.168.26.3 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 
192.168.26.2 | CHANGED | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN

可以看出两台机都处于80端口监听状态,接下来开始编写yml剧本,用触发器使得web1组的httpd默认监听8080端口

[root@ansible /]# vi /etc/ansible/web1.yml 
---
 - hosts: web1
   remote_user: root
   tasks:
     - name: "修改端口"
       shell: sed -i 's/Listen\ 80/Listen\ 8080/g' /etc/httpd/conf/httpd.conf
       notify:                                <!--配置触发条件-->             
             - restart httpd                  <!--完成该任务后调用名为“restart httpd”的触发器-->     
   handlers:                           <!--配置触发器-->
     - name: restart httpd             <!--触发器名称为“restart httpd”-->           
       service: name=httpd state=restarted     <!--触发任务为重启httpd服务-->

检查语法

[root@ansible /]# ansible-playbook --syntax-check /etc/ansible/web1.yml

执行脚本

[root@ansible /]# ansible-playbook /etc/ansible/web1.yml

监听一下8080端口查看是否成功

[root@ansible /]# ansible web1 -m shell -a "netstat -anpt |grep 8080"
192.168.26.3 | CHANGED | rc=0 >>
tcp6 0 0 :::8080 :::* LISTEN 23728/httpd 
192.168.26.2 | CHANGED | rc=0 >>
tcp6 0 0 :::8080 :::* LISTEN 19886/httpd 
成功,8080端口都起来了

 

 

角色

roles目录结构

将多种不同的tasks的文件集中存储在某个目录下,则该目录就是角色。角色一般存放在 /etc/ansible/roles/ 目录,可通过ansible的配置文件来调整默认的角色目录,/etc/ansible/roles/ 目录下有很多子目录,其中每一个子目录对应一个角色,每个角色也有自己的目录结构,如下图所示:

/etc/ansible/roles/为角色集合,该目录下有自定义的各个子目录:

  • mariadb:mysql角色;
  • Apache:httpd角色;
  • Nginx:Nginx角色;

Roles各目录作用

每个角色的定义,以特定的层级目录结构进行组织。以mariadb(mysql角色)为例:

  • files:           存放由copy或script等模块调用的文件;
  • templates: 存放template模块查找所需要的模板文件的目录,如mysql配置文件模板;
  • tasks:         任务存放的目录;
  • handlers:  存放相关触发执行的目录;
  • vars:          变量存放的目录;
  • meta:        用于存放此角色元数据;
  • default:     默认变量存放的目录,文件中定义了此角色使用的默认变量;

上述目录中,tasks、handlers、vars、meta、default至少应该包含一个main.yml文件,该目录下也可以有其他.yml文件,但是需要在main.yml文件中用include指令将其他.yml文件包含进来。

创建 role

  1. 创建以roles命名的目录
  2. 在roles目录中分别创建以各角色名称命名的目录,如webservers等
  3. 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
  4. 在playbook文件中,调用各角色

范例:roles的目录结构

nginx-role.yml 
roles/
└── FTP
     ├── files
     │      └── main.yml 
     ├── tasks
     │      ├── groupadd.yml 
     │      ├── install.yml 
     │      ├── main.yml 
     │      ├── restart.yml 
     │      └── useradd.yml 
     └── vars 
          └── main.yml

playbook调用角色

编辑yml文件

[root@ansible /]# vi /etc/ansible/test2.yml
---
 - hosts: web1
   remote_user: root
   roles:                 <!--调用角色名--> 
     - mysql                         
     - nginx
     - ftp

项目实战

实现httpd角色

两台服务器需要提前关闭服务器与准备好yum源仓库
[root@ansible /]# mkdir -p /etc/ansible/roles/httpd/{tasks,handlers,files} 
创建角色相关记录 
[root@ansible /]# cd /etc/ansible/roles/httpd/

配置http模板

[root@ansible httpd]# vi files/test.conf
<virtualhost *:80>
documentroot /web/web1         
servername 192.168.26.2
<Directory "/web/web1">
    Require all granted
</virtualhost>

<virtualhost *:80>
documentroot /web/web2
servername 192.168.26.3
<Directory "/web/web2">
    Require all granted
</virtualhost>
:wq

配置网页文件

[root@ansible httpd]# vi files/index1.html
web1
:wq

[root@ansible httpd]# vi files/index2.html
web2
:wq

编写剧本

[root@ansible httpd]# vi tasks/main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
:wq

[root@ansible httpd]# vi tasks/user.yml
- name: "创建用户"
  user: name=apache system=yes shell=/sbin/nologin home=/home/ uid=80 group=apache
:wq

[root@ansible httpd]# vi tasks/group.yml
- name: "创建用户组"
  group: name=apache system=yes gid=80 
:wq

[root@ansible httpd]# vi tasks/install.yml
- name: "安装http服务"
  yum: name=httpd
:wq

[root@ansible httpd]# vi tasks/config.yml
- name: "传输配置文件"
  copy: src=test.conf dest=/etc/httpd/conf.d/test.conf backup=yes
  notify: restart
:wq

[root@ansible httpd]# vi tasks/index.yml
- name: "创建目录1"
  file: path=/web/web1 state=directory
- name: "创建目录2" 
  file: path=/web/web2 state=directory
- name: "传输网页1"
  copy: src=index1.html dest=/web/web1/index.html
- name: "传输网页2"
  copy: src=index2.html dest=/web/web2/index.html
:wq

[root@ansible httpd]# vi tasks/service.yml
- name: "启动服务"
  service: name=httpd state=started enabled=yes
:wq

[root@ansible httpd]# vi handlers/main.yml
- name: restart 
  service: name=httpd state=restarted
:wq

#检查文件目录
[root@ansible httpd]# tree /etc/ansible/roles/httpd/
/etc/ansible/roles/httpd/
├── files
│   ├── test.conf
│   ├── index1.html
│   └── index2.html 
├── handlers
│   └── main.yml
└── tasks
    ├── config.yml
    ├── group.yml
    ├── index.yml
    ├── install.yml
    ├── main.yml
    ├── service.yml
    └── user.yml

3 directories, 10 files

#在playbook中调用角色
[root@ansible httpd]# vi /etc/ansible/role_httpd.yml
---
 - hosts: web1
   remote_user: root
   roles:
     - httpd
:wq

检查语法

[root@ansible tasks]# ansible-playbook --syntax-check /etc/ansible/role_httpd.yml 

playbook: /etc/ansible/role_httpd.yml

执行脚本

[root@ansible tasks]# ansible-playbook /etc/ansible/role_httpd.yml 

PLAY [web1] ********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.26.2]
ok: [192.168.26.3]

TASK [httpd : 创建用户组] ***********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 创建用户] ************************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 安装http服务] ********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 传输配置文件] **********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 创建目录1] ***********************************************************
changed: [192.168.26.2]
changed: [192.168.26.3]

TASK [httpd : 创建目录2] ***********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 传输网页1] ***********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 传输网页2] ***********************************************************
changed: [192.168.26.3]
changed: [192.168.26.2]

TASK [httpd : 启动服务] ************************************************************
changed: [192.168.26.2]
changed: [192.168.26.3]

RUNNING HANDLER [httpd : restart] **********************************************
changed: [192.168.26.2]
changed: [192.168.26.3]

PLAY RECAP *********************************************************************
192.168.26.2               : ok=11   changed=10   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.26.3               : ok=11   changed=10   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible httpd]# 

访问测试,成功

 

作者: 红烧悠鸽
本文采用 CC BY-NC-SA 4.0 协议

评论

  1. 社长
    5月前
    2021-7-04 21:11:05

    厉害呀

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇