ansible playbook

492 阅读6分钟

Playbooks简介

Playbooks 与 adhoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的.
playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署
Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务

我们使用 adhoc 时,主要是使用 /usr/bin/ansible 程序执行任务.而使用 playbooks 时,更多是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范

Playbook 语言的示例

Playbooks 的格式是YAML(详见:YAML 语法),语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并不是一个配置模型或过程的模型.

playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表.

在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible 模块的调用,这在前面章节学习过.

‘plays’ 好似音符,playbook 好似由 ‘plays’ 构成的曲谱,通过 playbook,可以编排步骤进行多机器的部署,比如在 webservers 组的所有机器上运行一定的步骤, 然后在 database server 组运行一些步骤,最后回到 webservers 组,再运行一些步骤,诸如此类.

“plays” 算是一个体育方面的类比,你可以通过多个 plays 告诉你的系统做不同的事情,不仅是定义一种特定的状态或模型.你可以在不同时间运行不同的 plays.

对初学者,这里有一个 playbook,其中仅包含一个 play:

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

在下面,我们将分别讲解 playbook 语言的多个特性

Playbook核心元素

hosts

你可以为 playbook 中的每一个 play,个别地选择操作的目标机器是哪些,以哪个用户身份去完成要执行的步骤(called tasks).

hosts行的内容是一个或多个组或主机的 patterns,以逗号为分隔符。支持并集交集等逻辑分组

---
- hosts: nginx,db
  remote_user: root
  tasks:
      - name: test connection
        ping: 

在每一个 task 中,可以定义自己的远程用户

---
- hosts: nginx,db
  remote_user: root
  tasks:
      - name: test connection
        ping: 
        remote_user: peng

支持从 sudo 执行命令

---
- hosts: nginx,db
  remote_user: root
  tasks:
      - name: test connection
        ping: 
        remote_user: peng
        sudu: yes

也可以登陆后,sudo 到不同的用户身份,而不是使用 root:

---
- hosts: nginx,db
  remote_user: root
  tasks:
      - name: test connection
        ping: 
        remote_user: peng
        sudu: yes
        sudo_user: nginx

如果你需要在使用 sudo 时指定密码,可在运行 ansible-playbook 命令时加上选项 --ask-sudo-pass (-K). 如果使用 sudo 时,playbook 疑似被挂起,可能是在 sudo prompt 处被卡住,这时可执行 Control-C 杀死卡住的任务,再重新运行一次.

tasks

每一个 play 包含了一个 task 列表(任务列表).一个 task 在其所对应的所有主机上(通过 host pattern 匹配的所有主机)执行完毕之后,下一个 task 才会执行。有一点需要明白的是(很重要),在一个 play 之中,所有 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task

在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除. 如果发生执行失败的情况,请修正 playbook 中的错误,然后重新执行即可

每个 task 的目标在于执行一个 moudle, 通常是带有特定的参数来执行.在参数中可以使用变量(variables)

modules 具有”幂等”性,意思是如果你再一次地执行 moudle(译者注:比如遇到远端系统被意外改动,需要恢复原状),moudle 只会执行必要的改动,只会改变需要改变的地方.所以重复多次执行 playbook 也很安全.

每一个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个 task 的. 如果没有定义 name,‘action’ 的值将会用作输出信息中标记特定的 task.

如果要声明一个 task,以前有一种格式: “action: module options” (可能在一些老的 playbooks 中还能见到).现在推荐使用更常见的格式:”module: options” ,本文档使用的就是这种格式

handlers

当某个属性发生改变时,调度执行handlers.必须搭配notify使用


---
- hosts: server
  tasks:
    - name : Create nginx user
      user :
        name: nginx
        shell: /sbin/nologin
        system: True
        state: present
        comment: Nginx User
        home: no

    - name : Install nginx
      yum: name=nginx-1.16.1 state=present

    - name : Copy nginx config
      copy :
        src: /tmp/nginx.conf
        dest: /etc/nginx/nginx.conf
        backup: True
    # 当属性发生更改时,执行handlers
      notify : 
        - Restart Nginx
        - Check Nginx running
        
    - name : Start Nginx
      service:
        name: nginx
        enabled: True
        state: started

  handlers:
    - name: Restart Nginx
      service: name=nginx state=restarted
    - name: Check Nginx running
      shell: killall -0 nginx > /tmp/nginx.log

tags

标签,ansible-playbook可指定标签启动,--list-tags可显示可用的tags信息


---
- hosts: server
  tasks:
    - name : Ping
      ping:
      tags: Ping
    - name : Create nginx user
      user :
        name: nginx
        shell: /sbin/nologin
        system: True
        state: present
        comment: Nginx User
        home: no
ansible-playbook -t ping xxx.yaml

单独只允许yaml其中tags为Ping的模块

变量

变更名

仅能由字母、数字和下划线组成,且只能以字母开头

变量来源

ansible setup facts远程主机的所有变量都可直接调用

在/etc/ansible/hosts中定义

# 普通变量: 主机组中主机单机定义变量,优先级高于公共变量
[nginx]
192.168.198.150 hostname=master
[db]
192.168.198.151 hostname=slave

# 公共组变量:针对主机组所有主机定义统一变量
[server:vars]
hostname=ansiblehost

在playbook中定义

---
- hosts: server
  vars:
    - name1: httpd
    - name2: vsftpd
  yum: name={{ name1,name2 }}

在命令行中定义

ansible-playbook -e "name1=httpd name2=vsftpd" xxx.yaml

在rols定义

优先级关系

命令行定义 > playbook定义 > ansible_setup_facts变量 > 主机组定义(主机 > 公共组)

运行

# 检查语法是否错误
ansible-playbook ansible.yaml --check
# 列出主机列表
ansible-playbook ansible.yaml --list-hosts
# 只在某台远程主机上执行
ansible-playbook ansible.yaml --limit webserver

ansible-vault

管理加密解密yaml文件

加密yaml文件

ansible-vault encrypt ansible.yaml

查看加密的yaml文件

ansible-vault view ansible.yaml

编辑加密的yaml文件

ansible-vault edit ansible.yaml

修改加密的yaml文件

ansible-vault rekey ansible.yaml

解密yaml文件

ansible-value decrypt ansible.yaml

创建加密yaml文件

ansible-value create ansible.yaml