Linux 第60,61天 ansible的playbook

Linux 第60,61天 ansible的playbook

时间: 20180922

时间: 20180924


目录

playbook(重点)

YAML

playbook 核心元素

运行playbook

playbook定义

playbook中的变量使用

playbook中的条件when

playbook中的with_items

templates 模板

template 里的for,if

roles

总结


playbook(重点)

playbook是由一个或多个play组成的列表

play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。

从根本上来讲,task是调用ansible的一个module将多个play组织在一个playbook中,即

可以让它们联同起来按事先编排的机制,将目标主机格式化成所定义好的角色


playbook采用YAML语言编写


YAML 是一个可读性高的用来表达资料序列的格式。YAML参考了其它多种语言,包括xml,C,python,

perl以及电子邮件格式C2822等. YAML (Ain't Markup Language) (Yet Another Markup 

Language)


特性

可读性好

和脚本语言的交互性好

使用现实语言的数据类型

有一个一致的信息模型

易于实现

可以基于流来处理

表达能力强,扩展性好

可参阅资料 www.yaml.org


语法简介

在一档案中,可用连接三个连字号---区分多个档案,另外还有选择性的连续三个点号

...用来表示档案结尾

次行开始正常写playbook的内容,一般建议写明该playbook的功能

使用#号注释代码

缩进必须是统一的,不能空格和tab混用

缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进

结合换行来实现的

yaml文件内容也区分大小写k/v的值大小写敏感

k/v的值可同行写也可换行写。同行使用:分隔

k可是一个字符串,也可是另一个列表

一个完整的代码块功能需最少元素包括name:task

一个name只能包括一个task

yaml文件扩展名通常为yml或yaml


list: 列表,其所有元素均使用-打头

example: 

# a list of tasty fruits

- apple

- orange

- strawberry

- mango


dictionary 字典,通常由多个key与value构成

example:

# An employee record

name: example Developer

job: Developer

skill: Elite

也可以将key:value放置于{}中进行表示,用","分隔多个key:value

example:

# an employee record

{name: Example Developer,job: Developer,skill: Elite}


yaml的语法和其它高阶语言类似,并且可以简单表达清单,散列表,标量等数据结构。其结构

(structure)通过空格来展示,序列(Sequence)里的项用"-"来表示,Map时的键值用":"分隔

example:

name: John Smith

age: 41

gender: Male

spouse:

name: Jane Smith

age: 37

gender: Female

children:

- name: Jimmy Smith

  age: 17

  gender: Male

- name: Jenny Smith

  age:13

  gender: Female


playbook 核心元素

hosts 执行的远程主机列表

tasks 任务集

variables 内置变量或自定义变量在playbook中调用

templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件

handlers 和notify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行

tags 标签,指定某条任务执行,用于择选运行playbook中的部分代码。ansible具有幂等性

因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间

依然 会非常地长。此时,如果确信其没有变化就可以通过tag跳过这些代码片断

remote_user: 可用于host和task中,也可以通过指定sudo的方式远程主机上执行任务,其可用

于play全局或某任务,此外甚至可以在sudo时使用sudo_user指定sudo时切换的用户 

ansible-playbook -t tagsname useradd.yml


cat test.yml

- hosts: webser

  remote_user: root

  tasks:

    - name: test connection

      pint:

      remote_user: user1

      sudo: yes

      sudo_user: admin


task列表和action

play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有

主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等

的,这意味着多次执行是安全的,因为其结果均一致

每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述

任务执行步骤。如果未提供name,则action的结果将用于输出

格式: 1 action: module arguments

  2 module: arguments (建议使用)

注意 shell和command模块后面跟命令,而非key=value

某任务的状态在运行后为changed时,可通过notify通知给相应的handlers


任务通过tags打标签,而后在ansible-playbook命令上使用-t指定进行调用

example: 

tasks:

  - name: disable selinux

    command: /sbin/setenforce 0


如果命令或脚本的退出码不为0可以使用如下方式替换

命令后加|| /bin/true

ignore_errors: True


运行playbook

ansible-playbook <filename.yml> ...[options]


options:

--check

--list-hosts

--limit 主机列表  限制在哪里主机上执行

-v -vv -vvv

-t tagsName 指定执行某段代码块


playbook定义

---

- hosts: all

  tasks:

  - name: install httpd

    yum: name=httpd

  - name: copy confg

    copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/

  - name: start httpd

    service: name=httpd state=started


handler和触发条件notify, tags

- hosts: webser

  remote_user: root

  tasks:

  - name: install httpd

    yum: name=httpd

  - name: copy confg

    copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/

    notify: restart httpd

  - name: start httpd

    service: name=httpd state=started

    tags: start

  handlers:

  - name: restart httpd

    service: name=httpd status=restarted


含义当name: copy confg有发生change状态则会执行hangdler里的restart httpd

ansible-playbook -t start name.yml 则会只执行tag所包含的模块


playbook中的变量使用

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

变量定义 key=value   如 http_port=80

ansible-playbook -e 选项指定变量

ansible-playbook -e "hosts=www user=root"

在yml文件中指定变量

vars:

- username: user1

- groupname: group1

在inventory中指定主机变量/etc/ansible/hosts

[appser]

192.168.0.5 http_port=80

...

组变量 即给一组主机定义变量

[apper:vars]

ntp_server=192.168.5.8

nfs_server=184.0.4.8

变量调用方式: 

通过{{ variable_name }}调用变量,且变量名前后必须有空格,有时用"{{ varName }}"

setup变量  setup是一个模块,该模块是向主机发送指令前会先从主机上收集一些目标主机的

信息,并用一些变量名将这些信息保存,所以用户可以直接调用这些变量名来动态的生成

配置文件,或调用这些变量名来给其它地方引用

如根据目标主机的cpu核数来判定要运行http进程数

根据目标主机的memory来判断memcache要指定的内存大小等


playbook中的条件when

即当某条件满足时才执行action

tasks:

name: install httpd

yum: name=httpd

when: ansible_distribution_major_version == "6"

此条目表示当目标主机的主版本为6时才会执行此条目


tasks:

  - name: install conf file to centos7

    template: src=nginx.conf.c7.j2

    when: ansible_distribution_major_version == "7"

  - name: install conf file to centos6

    template: src=nginx.conf.c6.j2

    when: ansible_distribution_major_version == "6"

根据不同系统版本复制不同的配置文件



playbook中的with_items

当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为"item"

要在task中引用with_items给定要迭代的元素列表

列表格式:

字符串

字典

如 添加多用户

- name: add users

  user: name={{ item }} groups=opt

  with_items:

    - opt1

    - opt2


字典引用

- name: add some users

  user: name={{ item.name }} group={{ item.group }} state=present

  with_items:

- { name: 'user1', group: 'group1' }

- { name: 'user2', group: 'group2' }

- { name: 'user3', group: 'group3' }



templates 模板

文本文件,嵌套有脚本(使用模板编程语言编写)

Jinja2语言,有以下形式

字符串: 使用单引号或双引号

数字: 整数,浮点数

列表: [item1,item2,...]

元组: (item1,item2,...)

字典: {key1:value1,key2:value2,...}

布尔型: true/false

算术运算: +,-,*,/,//(除完取整),%,**

比较操作: ==, !=, >, >=, <, <=

逻辑运算: and, or, not

流表达式: for if when


templates功能

根据模块文件动态生成指定目标主机的配置文件

templates文件必须存放于templates目录下,且命名为.j2结尾

yaml/yml 文件需要和templates目录平级,目录结构如下

./

├── temnginx.yml

└── templates

└── nginx.conf.j2


示例: 利用templates同步nginx配置文件

准备templates/nginx.conf.j2文件

vim temnginx.yml

-hosts: webser

  remote_user: root


  tasks:

    - name: template config to remote host

      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf


ansible-playbook temnginx.yml

template的src指定的路径只需要写文件名即可。因为会自动去templates文件夹下去找

这便是templates文件必须和.yml文件在同级目录下的原因


上述只是讲了如何调用templates文件,但是没有操作templates文件

上述文件里nginx.conf.j2文件可以将某些参数的值改为变量,然后同步至目录主机时

会先将变量生成对应主机的值,然后放置至目标主机的相应目录里如

worker_processes {{ ansible_processor_vcpus }};

worker_processes {{ ansible_processor_vcpus*2 }};



template for if

(一定要注意格式对齐不然会报错的)

    temnginx.yml

- hosts: mageduweb

  remote_user: root

  vars:

nginx_vhosts:

      - web1:

listen: 8080

server_name: "web1.magedu.com"

root: "/var/www/nginx/web1/"

      - web2:

listen: 8080

root: "/var/www/nginx/web2/"

      - web3:

listen: 8080

server_name: "web3.magedu.com"

root: "/var/www/nginx/web3/“

  tasks:

    - name: template config

      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf


templates/nginx.conf.j2

{% for vhost in nginx_vhosts %}

server {

listen {{ vhost.listen }}

{% if vhost.server_name is defined %}

server_name {{ vhost.server_name }}

{% endif %} (加一段判断name是否存在)

root {{ vhost.root }}

}

{% endfor %}

生成结果:

server {

listen 8080

server_name web1.magedu.com

root /var/www/nginx/web1/

}

server {

listen 8080

root /var/www/nginx/web2/

}

server {

listen 8080

server_name web3.magedu.com

root /var/www/nginx/web3/

}

即将所定义的列表逐个在客户端执行生成 



roles

ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次

型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用

include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及触发器放置于

单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场

景中,但也可以是用于构建守护进程等场景中

复杂场景:建议使用roles,代码复用度高

变更指定主机或主机组

如命名不规范维护和传承成本大

某些功能需多个Playbook,通过includes即可实现


角色(roles):角色集合

roles/

mysql/

httpd/

nginx/

memcached/


roles目录结构

每个角色,以特定的层级目录结构进行组织

roles目录结构:

playbook.yml

roles/

project/

tasks/

files/

vars/

templates/

handlers/

default/ 不常用

meta/ 不常用

Roles各目录作用

/roles/project/ 项目名称,有以下子目录

project/files/ 存放由copy或script模块等调用的文件

prject/templates/ template模块查找所需要模板文件的目录

prject/tasks/ 定义task,role的基本元素,至少应该包含一个名为main.yml的文件

其它的文件需要在此文件中通过include进行包含

prject/handlers/ 至少应该包含一个名为main.yml的文件;其它的文件需要在此文

件中通过include进行包含

prject/vars/ 定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要

在此文件中通过include进行包含

prject/meta/ 定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为

main.yml的文件,其它文件需在此文件中通过include进行包含

prject/default/ 设定默认变量时使用此目录中的main.yml文件


playbook调用角色

调用角色方法1

- hosts: websrvs

  remote_user: root

  roles:

- mysql

- memcached

- nginx

调用角色方法2

传递变量给角色

- hosts:

  remote_user:

  roles:

    - mysql

    - { role: nginx, username: nginx }

键role用于指定角色名称

后续的k/v用于传递变量给角色

调用角色方法3:还可基于条件测试实现角色调用

roles:

- { role: nginx, username: nginx, when: ansible_distribution_major_version

== ‘7’ } (一行命令)


总结

1 handlers 里写tags不可以被单独被单独调用,只可以定在tasks里

2 playbook 里一个yml文件只能完成一项单独的任务比如安装某程序,不可以在任务里定义

某个服务即开启又关闭,没有选择流程,都是顺序执行,开启和关闭只能分开写在两个

yml文件里


猜你喜欢

转载自blog.51cto.com/winthcloud/2286083