凉城旧巷
Python从入门到自闭,Java从自闭到放弃,数据库从删库到跑路,Linux从rm -rf到完犊子!!!

ansible(二)—— playbook

playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。

一、playbook核心

Tasks:任务,由模板定义的操作列表
Variables:变量
Templates:模板,即使用模板语法的文件
Handlers:处理器 ,当某条件满足时,触发执行的操作
Roles:角色
---
- name: My playbook   # playbook 名
  hosts: all   			#指定主机
  remote_user: root         #指定在被管理的主机上执行任务的用户
  tasks:						 #任务列表↓
     - name: Leaving a mark			#任务名
       command: "touch /tmp/ansible_was_here"		#调用command模块 执行命令
       notify: 
       		- restart httpd
	 - name: start httpd               #任务名
  	   service: name=httpd state=started 		  #调用service模块 开启httpd 服务
  handlers:
     - name: restart httpd
       service: name=httpd state=retarted
ansible-playbook a.yml --syntax-check    # 检查yaml文件的语法是否正确
ansible-playbook a.yml     # 执行playbook

 

二、tasks

  • task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在每一个主机上完成第一个任务后再开始第二个任务。
    在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。

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

  • 大部分 module 都是使用 key=value 来定义参数,但是有 2 个特别的 module: command和 shell,它们不使用 Key=value 格式

 

三、Variables

任何变量都将覆盖任何playbook关键字,任何命令行选项以及任何配置设置。定义变量可在task中引用,引用变量用{{}}

1、在yaml中定义变量

- hosts: vpc
  remote_user: root
  vars:
  	- package: httpd
  	- service: httpd
  tasks:
  	- name: install httpd package
  	  yum: name={{package}} state=latest
  	- name: install cfg file
  	  copy: src=/opt/httpd.cfg dest=/etc/httpd/httpd.cfg
  	  notify:
  	  	- restart httpd
  	- name: start httpd service
  	  service: enabled=true name={{service}} state=started
  handlers:
  	- name: restart httpd
  	  service: name={{service}} state=restarted

 

2、引用主机变量

变量可以在/etc/ansible/hosts中定义,

# vim /etc/ansible/hosts

[vpc]
192.168.136.180 testvar=httpd
- hosts: vpc
  remote_user: root
  tasks:
  	- name: install httpd package
  	  yum: name={{testvar}} state=latest

 

四、templates

Jinja是基于Python的模板引擎。template类是Jinja的另一个重要组件,可以看作一个编译过的模块文件,用来生产目标文本,传递Python的变量给模板去替换模板中的标记

  • templates文件必须存放于templates目录下,且命名为".j2"结尾yaml/yml文件需要和templates目录平级,这样我们在yml文件中调用模板的时候,就不需要写模板文件的路径,否则需要描述模板文件的路径,因为template模块会自动去找templates目录下的模板文件

  • template模板去动态生成的配置文件,不是拷贝,拷贝是将文件原封不动的拷贝过去

  • 定义模板

    # vim templates/httpd.conf.j2
    
      Listen {{http_port}}
      ServerName {{server_name}}
      MaxClients {{access_num}}
    
  • /etc/ansible/hosts中添加变量

    [vpc]
    192.168.136.180 http_port=80 server_name="localhost" access_num=100
    
  • 利用templates同步

    - hosts: vpc
      remote_user: root
     
      tasks:
        - name: install httpd
          yum: name=httpd
        - name: template config to remote hosts
          template: src=httpd.conf.j2 dest=/etc/httpd/httpd.conf
    

     

五、Handlers

Handlers 也是一些 task 的列表,通过名字来引用,它们和一般的 task 并没有什么区别。

Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行。不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。

最佳的应用场景是用来重启服务,或者触发系统重启操作。除此以外很少用到了。

  • notify后面使用的是handlers的name

 

六、roles

官方文档: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需在playbook中使用include指定即可。

roles就是通过分别将变量、文件、任务、模板以及处理器放置于单独目录中,并可以便捷的使用include指令将他们组织在一块的一种机制。角色一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。复杂场景建议使用roles,代码复用度高。

---
- hosts: websers
  remote_user: root
   
  roles:
    - roles_name 

1、目录结构

  • roles是依赖目录的命名和摆放,默认tasks/main.yml是所有任务的入口,所以使用roles的过程可以理解为目录规范化命名的过程。每个目录下均由main.yml定义该功能的任务集,tasks/main.yml默认执行所有指定的任务。
site.yml
webservers.yml
fooservers.yml
roles/
    common/
        tasks/
        handlers/
        library/
        files/
        templates/
        vars/
        defaults/
        meta/
    webservers/
        tasks/
        defaults/
        meta/
  • files/目录主要存放copy或scripts模块等调用的文件;
  • templates/目录主要存放template模块查找所需要的模板文件;
  • tasks/定义task,role的基本元素,至少应该包含一个名为main.yml的文件(tasks目录的入口文件),其他的文件需要在此文件中通过include进行包含
  • handlers/目录主要存放触发器任务的yml文件,同样它里面至少需要有一个main.yml的入口文件,其文件内容通过include指令引用其下文件;
  • vars/目录主要存放定义的变量文件,同样也需要有main.yml文件
  • meta/目录定义当前角色的特殊设定以及依赖关系,同样这个目录也需要有一个main.yml的入口文件
  • default/设定默认变量时使用此目录中的main.yml文件

2、roles目录配置

roles目录可以摆放在/etc/ansible/ansible.cfgroles_path定义路径,也可以和入口playbook文件存放在同级目录,ansible没有强制的要求,但还是建议将代码存放在代码集预先规划的目录,以便管理

3、创建角色

  1. 创建以roles命名的目录
  2. roles目录中分别创建以各自角色名称命名的目录,如nginx等
  3. 在每个角色命名的目录中分别创建fileshandlersmetataskstemplates、和vars目录;若角色用不到的目录可以是空目录,也可以不创建
  4. 在playbook文件中,调用各角色

4、示例

1)普通版

$ tree
.
├── install_nginx.yml
# cat install_nginx.yml

---
- hosts: vpc
  remote_user: root
 
  tasks:
    - name: install nginx
      shell: rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    - name: install nginx
      shell: yum install -y nginx
      notify: restart nginx
  handlers:
    - name: restart nginx
      service: name=nginx state=started

2)roles版

$ tree

.
├── install_nginx.yml
└── roles
    └── nginx
        ├── handlers
        │   ├── main.yaml
        │   └── start_nginx.yml
        └── tasks
            ├── add_rpm.yaml
            ├── install_nginx.yaml
            └── main.yaml
$ cat tasks/add_rpm.yaml

- name: add rpm
  shell: rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

#############################################################
  
$ cat tasks/install_nginx.yaml

- name: install nginx
  shell: yum install -y nginx
  notify: start nginx

#############################################################

$ cat tasks/main.yaml

- include: add_rpm.yaml
- include: install_nginx.yaml

#############################################################

$ cat handlers/start_nginx.yml

- name: start nginx
  service: name=nginx state=started

#############################################################

$ cat handlers/main.yaml

- include: start_nginx.yml

#############################################################

$ cat install_nginx.yml

---
- hosts: vpc
  remote_user: root
  roles:
     - nginx

 

七、其它

1、条件判断

  • when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行
  • 如果需要根据变量、facts(setup)或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when子句。
  • 在task后添加when子句即可使用条件,when子句支持jinjia2表达式或语法
# 满足系统为CentOS 7 或 Ubuntu 18时,执行关机命令
- hosts: vpc
  remote_user: root
  tasks:
  	- name: "shutdown"
  	  command: shutdown -h now
  	  when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or 
  	  			(ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "18")

posted on 2022-01-27 16:35  凉城旧巷  阅读(293)  评论(0编辑  收藏  举报