Ansible-Playbook

前置

Playbook介绍
  1. playbook 剧本是由一个或多个“play”组成的列表
  2. Playbook 文件是采用YAML语言编写的
  3. 用户通过ansible命令直接调用yml语言写好的playbook,playbook由多条play组成,每条play都有一个任务(task)相对应的操作,然后调用模块modules,应用在主机清单上,通过ssh远程连接,从而控制远程主机或者网络设备
YAMl 语言介绍

YAML是一个可读性高的用来表达资料序列的格式。YAML 官方网站:http://www.yaml.org

YAML 语言特性
  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YAML使用实现语言的数据类型
  • YAML有一个一致的信息模型
  • YAML易于实现
  • YAML可以基于流来处理
  • YAML表达能力强,扩展性好
YAML语法简介
  • 在单一文件第一行,用连续三个连字号“-” 开始,还有选择性的连续三个点号( … )用来表示文件的结尾
  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
    YAML文件内容是区别大小写的,key/value的值均需大小写敏感
  • 多个key/value可同行写也可换行写,同行使用,分隔
  • v可是个字符串,也可是另一个列表
  • 一个完整的代码块功能需最少元素需包括 name 和 task
  • 一个name只能包括一个task
  • YAML文件扩展名通常为yml或yaml

Playbook核心元素

  • Hosts 执行的远程主机列表
  • Tasks 任务集
  • Variables 内置变量或自定义变量在playbook中调用
  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

handlers和notify结合使用触发条件

task列表和action
  • play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自上而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此再更正playbook后重新执行一次即可。
  • task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
  • 每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。
Handlers

        用于当关注的资源发生变化时,才会采取一定的操作。Notify可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作成为handler,也即notify中调用handler中定义的操作。

例如:方便直观看到变化,我们执行更新文件task(触发重启mysql服务的handler),然后执行关闭mysql服务task,最后观察重启的handler是否生效。

- hosts: yzb
  remote_user: root
  tasks:
  - name: task1
    file: path=/opt/testfile
          state=touch
    notify: restart mysqld
  - name: task2
    systemd:
      name: mysqld
      state: stopped
  handlers:
    - name: restart mysqld
      systemd:
        name: mysqld
        state: restarted

可以看到此时mysql启动时间为18号17:15

我们使用ansible-playbook执行对应的playbook,可以看到连接成功,task对应颜色为黄色,表示执行成功且发生了变动。

此时我们回到被控制端,查看mysql状态,可以看到启动时间已经变为最近时间

由此我们可以得出结论,剧本是按照顺序执行的,但是handler仅在所有的变化发生完成后才会去一次性地执行指定操作。

handlers也可以触发多个

- hosts: yzb
  remote_user: root
  tasks:
  - name: task1
    file: path=/opt/testfile
          state=touch
    notify: 
      - restart mysqld
      - restart nginx
  - name: task2
    systemd:
      name: mysqld
      state: stopped
  handlers:
    - name: restart mysqld
      systemd:
        name: mysqld
        state: restarted
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted

当然,也能实现立即执行对应handler,这要用到- meta: flush_handlers模块

tags标签

通过指定标签来执行特定的动作

        -t 指定执行某一标签对应的所有任务

        --skip-tags 表示要跳过的指定的标签任务

---
- hosts: websrvs
  remote_user: root
 
  tasks:
    - name: install httpd package
      yum: name=httpd
      tags: inshttpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
      notify: restart service
    - name: start service
      service: name=httpd state=started enabled=yes
      tags: rshttpd
 
  handlers:
    - name: restart service
      service: name=httpd state=restarted
执行启动服务的tags
[root@ansible145 ansible]# ansible-playbook -t rshttpd httpd.yml
也可以针对多个标签执行脚本
#执行多个tags
[root@ansible145 ansible]# ansible-playbook -t inshttpd,rshttpd httpd.yml 
跳过某个标签执行脚本
ansible-playbook httpd.yml --skip-tags rshttpd

变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开头。

调用:通过“{{ variable_name }}”调用变量,且变量名前后建议加空格

批量操作
[root@120 ansible]# cat task-restart.yml 
- hosts: yzb
  remote_user: root
  tasks:
  - name: task1
    systemd:
      name: "{{ item }}"
      state: restarted
    loop:
      - mysqld
      - nfs
[root@120 ansible]#
变量来源:
1.通过命令行指定变量,优先级最高
   ansible-playbook -e varname=value
   
2.在playbook文件中定义
   vars:
     - var1: value1
     - var2: value2
     
3.在独立的变量YAML文件中定义
- hosts: all
  vars_files:
    - vars.yml
    
4.在 /etc/ansible/hosts 中定义
  主机变量:主机组中主机单独定义,优先级高于组变量
  组变量:针对主机组中所有主机定义统一变量
在playbook 命令行中定义变量

范例:

vim var2.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install package
      yum: name={{ pkname }} state=present

ansible-playbook  –e pkname=httpd  var2.yml
在playbook文件中定义变量

范例:

[root@120 ansible]# cat mysql-variables.yml 
- hosts: yzb
  remote_user: root
  vars:
    - service: mysqld
  tasks:
  - name: task1
    file: path=/opt/testfile
          state=touch
    notify: restart mysqld
  - name: task2
    systemd:
      name: "{{ service }}"
      state: stopped
  handlers:
    - name: restart mysqld
      systemd:
        name: "{{ service }}"
        state: restarted

[root@120 ansible]# ansible-playbook mysql-variables.yml 
使用变量文件

可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高

范例:

[root@120 ansible]# cat mysql-variables-2.yml 
- hosts: yzb
  remote_user: root
  vars_files:
    - ./vars.yaml
  tasks:
  - name: task1
    file: path=/opt/testfile
          state=touch
    notify: restart mysqld
  - name: task2
    systemd:
      name: "{{ service }}"
      state: stopped
  handlers:
    - name: restart mysqld
      systemd:
        name: "{{ service }}"
        state: restarted
[root@120 ansible]# cat vars.yaml 
service: mysqld
[root@120 ansible]# ansible-playbook mysql-variables-2.yml 
主机清单文件中定义变量

范例:

vim /etc/ansible/hosts

[websrvs]
192.168.0.101 hname=www1 
192.168.0.102 hname=www2 

[websvrs:vars]
mark=“-”
domain=magedu.org

ansible  websvrs  –m hostname –a ‘name={{ hname }}{{ mark }}{{ domain }}’

templates

即用一个文件作为模板,传送到远程的被控机上去,并且针对被控机的配置去改写文件,一般是配置文件。template不能作为命令行调用,只能写在playbook中进行调用。

范例:以yum安装nginx为例

1.创建templates文件
[root@ansible ansible]# mkdir templates
2.复制nginx的配置文件到templates中,并重命名
[root@ansible ansible]# cp /etc/nginx/nginx.conf templates/nginx.conf.j2
3.编辑脚本
---
- hosts: websrvs
  remote_user: root
 
  tasks:
    - name: install package
      yum: name=nginx
    - name: copy template
      template: src=/nginx.conf.j2 dest=/ect/nginx/nginx.conf
    - name: start service
      service: name=nginx state=started enabled=yes

注意:

如果j2文件放在templates文件下,可以直接写template: src=nginx.conf.j2,ansible可以自动识别出来;

如果j2文件没有放在templates文件下,需要加上绝对路径template: src=xx/xx/nginx.conf.j2

4.检查并执行脚本
[root@ansible145 ansible]# ansible-playbook -C testtempl.yml
 
[root@ansible145 ansible]# ansible-playbook testtempl.yml

when

when 判断在用于控制在满足when所指定的条件的情况下 才执行相应的动作。

在when关键字中引用变量时,变量名不需要加"{{ }}",我们可以使用when关键字为任务指定条件,条件成立,则执行任务,条件不成立,则不执行任务。

示例1:

根据不同操作系统,安装不同软件

ansible_distribution 变量可以获取主机的发行版本

[root@120 ansible]# ansible yzb -m setup -a 'filter=ansible_distribution'
192.168.255.123 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}


playbook 如下
[root@120 ansible]# cat when.yml 
- hosts: yzb
  remote_user: root
  tasks:
  - name: Centos install httpd
    yum:
      name: httpd
      state: installed
    when: ansible_distribution=="CentOS"   <==判断版本语句,此处变量不需要{{ }}引用。
     # when也可以使用and与or方式进行多项匹配。
  - name: Ubuntu install httpd2
    yum:
      name: httpd2
      state: present
    when: (ansible_distribution == "CentOS")   <==判断版本语句,此处变量不需要{{ }}引用。
示例2:

判断kubelet.service 服务是否正常运行,运行就停止,不运行不作处理

[root@k8s-master-1 test]# vim when.yaml
---
- hosts: web
  remote_user: root
 
  tasks:
  - name: Check Nginx Status
    shell: systemctl status kubelet.service
    register: check_k8s
  - name: Print check_k8s
    debug:
      var:
        "check_k8s"     <==#通过debug的var输出该变量的所有内容
  - name:
    service:
      name: kubelet.service
      state: stopped
    when: check_k8s.rc == 0    <==.rc是check_nginx变量中的执行结果,见下面的执行过程

when_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制。对迭代项的引用,固定变量名为“item”,要在task中使用when_items给定要迭代的元素列表。

示例1:

批量下载程序(和变量里使用loop一样)

[root@ansible ansible]# vim testitem.yml
 
---
- hosts: yzb
  remote_user: root
 
  tasks:
    - name: create some files
      file: name=/data/{{ item }} state=touch
      when: ansible_distribution_major_version == "7"
      with_items:
        - file1
        - file2
        - file3
    - name: install some packages
      yum: name={{ item }}
      with_items:
        - htop
        - sl
        - hping3
实例2:

迭代嵌套子变量——批量创建用户名

[root@ansible ansible]# vim testitem3.yml
 
---
- hosts: yzb
  remote_user: root
 
  tasks:
    - name: create some group
      group: name={{ item }}
      when: ansible_distribution_major_version == "7"
      with_items:
        - g1
        - g2
        - g3
    - name: create some user
      user: name={{ item.name }} group {{ item.group }}
      with_items:
        - { name: 'user1', group: 'g1' }
        - { name: 'user2', group: 'g2' }
        - { name: 'user3', group: 'g3' }
        

ansible中的条件判断和tests

1、条件判断和tests

tests会将判断后的布尔值返回,如果条件成立,则返回true,如果条件不成立,tests会返回false,我们通常会在条件判断时使用到tests

示例:

---
- hosts: web
  remote_user: root
 
  vars:
    testpath: /tmp
  tasks:
  - name: test
    debug:
      msg: "file exist"
    when: testpath is exists
"is exists"中的"exists"就是tests的一种,判断ansible主机中的对应路径是否存在(注意:是ansible控制主机中的路径,与目标主机没有关系),当对应的路径存在于ansible控制节点时,"is exists"为真。
"is not exists"表示对应路径不存在时返回真。
2、判断变量的tests
  • defined:判断变量是否已经定义,已经定义返回真
  • undefind:判断变量是否已经定义,没定义就返回真
  • none:判断变量值是否为空,如果变量已经定义,但变量值为空,则返回真

示例:

---
- hosts: web
  remote_user: root
 
  vars:
    test1: vl
    test2:
  tasks:
  - debug:
      msg: "test1 is defined"
    when: test1 is defined
  - debug:
      msg: "test1 is undefind"
    when: test2 is undefined
3、判断执行结果的一些tests

success或者succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真

failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真

change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真

skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真

  • 32
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值