Ansible-playbook介绍

前言

之前有写过基于简单的ansible命令的方式对多台服务器进行批量操作,但是这种方式不适用于复杂场景的应用,于是我们可以使用playbook以及roles实现复杂任务的部署和批量操作,这是单纯Ansible命令无法实现的。

playbook

ansible-playbook是一系列ansible命令的集合。通过Playbook任务,能够集中管理多个任务,将多个任务关联起来,从而实现更加复杂工作,满足生产环境的各个需求,提高运维人员管理服务器效率

playbook使用YAML文件编写,类似XML接口(Tomcat)文件,内部有固定语法、参数等,要掌握常用的YAML语法编写,掌握满足运维管理方向的语法即可。

playbook核心组成

  • hosts: 要执行任务管理的主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息。
  • name: 任务描述信息,主要为了方便理解任务。
  • remote_user: 远程执行任务的用户。
  • vars: 要使用的变量。
  • tasks: 定义要在远程主机上执行的任务列表。
  • handlers: 指定task执行完后需要调用的任务(配合notify使用),主要用来重启服务或者重载配置文件。
  • roles:角色,将hosts剥离出去,由tasks、handlers等所组成的一种特定的结构集合。
  • sudo: 设置为yes时,执行任务时用root权限。
  • templates: 模板,即使用模板语法的文件,比如配置文件等。

ansible-playbook命令用法

ansible-playbook命令常跟有一些选项,常用的选项如下:

  • —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:从指定的任务开始往下运行;
  • –limit #主机列表 只针对主机列表中的某个主机或者某个组执行
  • -f #指定并发数,默认为5个
  • -t #指定tags运行,运行某一个或者多个tags。(前提playbook中有定义tags)
  • -v #显示过程 -vv -vvv更详细

常用选项示例:

# yaml文件语法检测
$ ansible-playbook --syntax-check test_echo.yml
playbook: test_echo.yml // 这样代表语法没有错误

# 预测试看是否能执行成功,不会真正执行
$ ansible-playbook -C test_echo.yml
159.75.83.204              : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
42.194.184.177             : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

# 查看受影响的主机
$ ansible-playbook --list-hosts test_echo.yml

playbook: test_echo.yml

  play #1 (tencent): tencent	TAGS: []
    pattern: ['tencent']
    hosts (2):
      42.194.184.177
      159.75.83.204
      
# 查看文件中的标签
$ ansible-playbook --list-tags test_echo.yml

playbook: test_echo.yml

  play #1 (tencent): tencent	TAGS: []
      TASK TAGS: []

通常情况下可以先执行 ansible-playbook -C命令进行测试,测试没问题后再执行 ansible-playbook 命令。

编写一个简单的playbook示例,用到常用的命令模块,tags的使用,以及handlers的用法。示例如下:

---
- hosts: tencent
  remote_user: root
  vars:
   - filename: test.txt
  tasks:
   - name: 创建playbook文件夹
     file: path=/tmp/playbook state=directory

   - name: cd到 /usr/ 目录下执行Ls
     command: chdir=/usr/ ls
     tags: ls
     notify: # 配置触发条件
      - touch file test # 指定要执行的handlers名字
  
  handlers: # 配置handlers,名字用来给notify触发
    - name: touch file test
      shell: cd /tmp/playbook/ && touch {{ filename }}

这个playbook执行后,会创建/tmp/playbook/目录如果该目录不存在,并显示/usr/目录下的所有文件及文件夹,最后通过notify执行对应的handlers模块创建一个test.txt文件。

tags用法

一个动作可以执行多个标签,也可以多个动作执行多个标签,执行标签动作需要加上-t选项:

  • ansible-playbook -t config insall.yml 触发一个标签
  • ansible-playbook -t “config,service” install.yml 触发两个标签
# 通过tags方式执行,只会执行标记了tags相关的任务
ansible-playbook -t "ls"  Ansible/Playbooks/test_echo.yml

# 执行tags以外的内容
ansible-playbook --skip-tags='ls' Ansible/Playbooks/test_echo.yml

vars用法

变量定义有几种不同的方式:

  • ansible-playbook命令
  • playbooks的yaml文件
  • hosts文件
  • 独立的yaml文件
# playbooks文件
- hosts: tencent
  remote_user: root
  vars:
   - filename: test.txt
  vars_files:    # 引用变量文件
    - ./var.yml   # 指定变量文件的path(这里可以是绝对路径,也可以是相对路径)
  tasks:
   - name: 创建playbook文件夹
     file: path=/tmp/playbook state=directory

   - name: cd到 /usr/ 目录下执行Ls
     command: chdir=/usr/ ls
     tags: ls
     notify: # 配置触发条件
      - touch file test # 指定要执行的handlers名字
  
  handlers: # 配置handlers,名字用来给notify触发
    - name: touch file test
      shell: cd /tmp/playbook/ && touch {{ filename }},{{filename1}}

# ansible-playbook命令
ansible-playbook -e “filename=test.txt,filename1=test1.txt” Ansible/Playbooks/test_echo.yml

# playbook的yaml文件
如上图,在vars中定义变量filename,直接以双括号方式使用:{{ filename }}

# 配置的host文件
$ cat /etc/ansible/host
[tencent]
42.194.184.177
159.75.83.204
[tencent:vars]
filename=test.txt

# 独立的yaml文件
$ cat var.yml 
filename: test.txt
filename1: test1.txt

条件判断when

有些时候需要在满足特定的条件后再触发某一项操作,或在特定的条件下终止某个行为,这个时候需要进行条件判断,when正是解决这个问题的最佳选项。

通过操作系统的类型来判断如何执行,ansible_os_family是内置的变量,示例如下,:

---

- hosts: tencent
  remote_user: root
  vars:
    - var1: test.txt  
  tasks:
   - name: 如果系统是centos执行
     file: path=/tmp/test state=directory
     when: ansible_os_family == 'RedHat'

   - name: 如果系统是Ubuntu执行
     file: path=/tmp/test1 state=directory
     when: ansible_os_family == 'Debian'

register注册变量

有时候我们还需要更复杂的例子,如判断前一个命令的执行结果去处理后面的操作,这时候就需要register模块来保存前一个命令的返回状态,在后面进行调用

示例如下,:

---

- hosts: tencent
  remote_user: root 
  tasks:
   - name: 获取系统负载
     shell: uptime | awk '{printf("%.2f\n",$(NF-2))}'
     register: result # 将上面的结果注册成一个变量result,在后面可以调用

   - name: 负载大则创建
     file: path=/tmp/test2 state=directory
     when: result.stdout | float > 0.7

使用循环

with_items方式

with_items是playbook的标准循环,可以用于迭代一个列表或者字典,通过{{ item }}获取每次迭代的值

示例如下:

---

- hosts: tencent
  remote_user: root 
  tasks:
   - name: 循环创建文件
     file: path=/tmp/test2/{{ item }} state=touch
     with_items:
      - test1.txt
      - test2.txt
      - test3.txt

也可以通过更复杂的嵌套子变量的形式,示例如下:

---

- hosts: tencent
  remote_user: root 
  tasks:
   - name: 循环创建文件
     file: path=/tmp/test2/{{ item.name }}.{{item.type}} state=touch
     with_items:
      - {name: 'test1',type: 'txt'}
      - {name: 'test2',type: 'yaml'}
      - {name: 'test3',type: 'conf'}

     with_items: # 另一种形式
      - 
          name: test1
          type: txt
      - 
          name: test2
          type: yaml
# 创建后的文件目录
-rw-r--r-- 1 root root 0 4月  21 10:56 test1.txt
-rw-r--r-- 1 root root 0 4月  21 10:53 test2.txt
-rw-r--r-- 1 root root 0 4月  21 10:56 test2.yaml
-rw-r--r-- 1 root root 0 4月  21 10:56 test3.conf
-rw-r--r-- 1 root root 0 4月  21 10:53 test3.txt

还有其他很多种方式的循环,可以在需要用到时查询官方文档或百度,此处不一一详解。

templates文件

template本质上是一个模版文件,为我们提供了动态配置服务,使用jinja2语言,里面支持多种条件判断、循环、逻辑运算、比较操作等。

多数情况下都将template文件放在和playbook文件同级的templates目录下(手动创建),这样playbook文件中可以直接引用,会自动去找这个文件。如果放在别的地方,也可以通过绝对路径去指定。

jinja2 语言使用字面量,有下面形式:

  • 字符串:使用单引号或双引号
  • 数字:整数,浮点数
  • 列表:[item1, item2, …]
  • 元组:(item1, item2, …)
  • 字典:{key1:value1, key2:value2, …}
  • 布尔型:true/false
  • 算术运算:+, -, *, /, //, %, **
  • 比较操作:==, !=, >, >=, <, <=
  • 逻辑运算:and,or,not
  • 流表达式:For,If,When

一个简单的templates文件定义,遵循jinja2语法,变量tencent定义在playbooks中:

worker_processes  {{ ansible_processor_vcpus*2 }}
worker_processes {{ ansible_processor_vcpus+2 }}

{% for host in tencent %}
    {% if host.name %}
    server_name {{ host.name }}
    {% endif %}
{% endfor %}

playbooks文件定义:

---

- hosts: tencent
  remote_user: root 
  vars:
   tencent:
    - host1:
      name: 123
    - host2:
      name: 456
  tasks:
   - name: 测试template文件
     template: src=test1.txt.j2 dest=/tmp/test2/text1.txt

执行后,在服务器上查看文件结果:

$ cat text1.txt 
worker_processes  4
worker_processes 4

server_name 123
server_name 456

templates文件的具体用法和示例不在此一一详解。

你可能感兴趣的:(#,Ansible,自动化运维,运维开发)