YAML

一、概述

YAML是“另一种标记语言(Yet Another Markup Langure)”的外语缩写,它类似于标准通用标记语言的子集xml的数据描述语言,且能够被电脑识别,是一个可读性高并且容易被人类阅读,容易和脚本语言进行交互,用来表达资料序列的编程语言。

特点:

1、可读性好

2、和脚本语言的交互性好

3、使用实现语言的数据类型

4、有一个一致的信息模型

5、易于实现

6、可以基于流来处理

7、表达能力强,扩展性好

二、语法

YAML可以简单表达清单、散列表、哈希表、标量等数据结构,其结构(structure)通过空格来展示,序列(sequence)里的项用 ‘-’ 来代表,Map里的键值对用 ‘:’分割。例如:

name:John

age:41

gender:Male

spouse:

   name:Jane

   age:37

   gender:Female

chilren:

 - name: Jimmy

   age:17

   gender:Male

 - name: Jenny

   age:13

   gender:Female

2.1列表

列表中的所有元素均使用-’ 打头,例如:

# A list of fruits

- apple

- orange

- banana

2.2字典(dictionary

字典通过keyvalue进行标示,例如:

# A employee record

name: xxx

job: xxx

skill: xxx

也可以将key:value放于{} 中进行表示,例如:

---

# A employee record

{ name:xxx,job:xxx,skill:xxx }

 

 Ansible基础元素(变量、Inventory、条件测试、迭代)

 一、变量

1.1命名

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

 

1.2facts

facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中,要获取指定的远程主机所支持的所有facts,可以使用如下命令进行:

    ansible hostname -m setup

 

1.3 register

把任务的输出定义为变量,然后用于其他任务,示例如下:

    tasks:

     - shell: /usr/bin/boo

       register: foo_result

       ingore_error: True

 

1.4通过命令行传递变量

ansible-playbook test.yaml --extra-vars "hosts=www user=www"

 

1.5通过roles传递变量

当给一个主机应用角色的时候可以传递变量,然后再角色内使用这些变量,示例如下:

    - hosts: webserersservers

      roles:

       - common

       - { role:foo_app,dir:'/webserers/htdocs/a.com',ports:8080 }

 

二、Inventory

ansible的主要功能在于批量主机操作,为了便捷地使用其中的部分主机,可以在Inventory file中将其分组命名,默认的Inventory file/etc/ansible/hosts

Inventory file 可以有多个,且也可以通过Dynamic Inventory来动态生效。

 1Inventory文件格式

Inventory文件遵循INI文件风格,中括号的字符为组名,可以将同一个主机同时归并到不同的组中;此外,当如若目标主机使用了非默认的ssh端口,还可以在主机名称之后用冒号加端口号来注明。

    ntp.example.com

    [webserers]

    linux-node2.example.com:2222

    linux-node3.example.com

    [dbserers]

    linux-node2.example.com

    linux-node3.example.com

    

如果主机名遵循相似的命名模式,还可以使用列表的方式标识各主机。例如:

    [webserers]

    linux-node[01:50].example.com

 

2、主机变量

可以在Inventory中定义主机时为其添加变量,以便于在playbook中使用,例如:

    [webserers]

    linux-node2.example.com http_port=80 Maxclient=808

    linux-node3.example.com http_port=8080 Maxclient=909

 

3、组变量

组变量是指赋予给指定组内所有主机上的playbook中可以使用的变量。例如:

    [webserers]

    linux-node2.example.com

    linux-node3.example.com

    [dbserers:vars]

    ntp_server=ntp.example.com

    nfs_server=nfs.example.com

 

4、组嵌套

Inventory 中,组还可包含其他的组,并且也可以向组中的主机指定变量,不过,这些变量只能在ansible-playbook中使用,而ansible不支持。例如:

    [apache]

    httpd1.example.com

    httpd2.example.com

    [nginx]

    nginx1.example.com

    nginx2.example.com

    [webserers:children]

    apache

    nginx

    [webserers:vars]

    ntp_server=ntp.example.com

    

5Invertory参数

ansible基于ssh连接invertory中指定的远程主机时,还可以通过参数指定其交互方式,这些参数如下所示:

    ansible_ssh_port

    ansible_ssh_host

    ansible_ssh_user

    ansible_ssh_pass

    ansible_sudo_pass

    ansible_connection

    ansible_ssh_private_key_file

    ansible_shell_type

    ansible_python_interpreter

  

例:我们需要先批量创建用户,然后为其中的三台主机部署mysql,另外的三台主机部署apache,这种情况下再用单个的命令去实现就显得不那么简单了,带条件的运维操作如下如图。

  

可以看到这个简单的场景具备了下面所说的一些特点:

Ø 流程化——先创建用户,再部署程序;

Ø 具备条件——某些设备需要部署mysql,某些设备需要部署apache。为了解决这种流程化的运维操作,ansible有了PlayBook这个概念。


 Ansible playbooks

playbook是由一个或多个“play”组成的列表,play的主要功能在于将事先归并于一组的主机装扮成实现通过ansible中的task定义好的角色。从根本上将,所谓是task无非是调用ansible中的一个module,将多个play组织在一个playbook中,即可以让他们联同起来按事先编排的机制同唱一台大戏。例如:

- hosts: web
  remote_user: root
  vars:
  - http_ports: 80
  - max_client: 256 
  
  tasks:
  - name: ensure apache is at latest version
    yum: name=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started

  handlers:
  - name: restart apache
    service: name=httpd state=restarted


一、playbook基础组件

1hostsusers

hosts用于指定要执行指定任务的主机,可以是一个或多个由冒号分割的主机组,remote_user则用于指定远程主机上执行任务的用户。例如:

    - hosts: webserers

      remote_user: root

   备注:如果对所有的主机都执行某一命令的时候,可以在   hosts: all

不过,remote_user也可用于各task中,也可以通过指定其通过sudo的方式在远程主机上来执行任务。

- hosts: web
  remote_user: root
  tasks:
  - name: test connection
    ping:
    remote_user: root
    sudo:yes

 

playbook的组成结构

    Inventory

    modules

    ad hoc commands

    playbooks:

        tasks:任务,即调用模块完成的基本操作

        variables:变量

        template:模块

        handlers:处理器,由某事件发生触发的操作

        roles:角色

基本结构:

    - hosts: webserers

      remote_user: root

      tasks:

       - task1:

       - task2:

2、任务列表和action

play的主体部分是task listtask list中各任务按次序逐个在hosts中指定的所有主机上运行,即在所有主机上完成第一个任务后再开始第二个,在运行自上而下某playbook时,如果中途发生错误,所有已执行任务都有可能回滚,因此,在更正playbook后重新执行一次即可。

每个task都应该有其name,用于playbook的执行结果输出

定义task时可以使用“actions:modules options”或“module”:

 tasks:
- name: ensure apache running
  service: name=httpd state=started

 

在众多模块中,只有commandshell模块仅需要给定一个列表而无需使用“key=value”格式。例如:

    tasks:

     - name: disable selinux

       command: /sbin/setenforce 0

     

     tasks:

      - name: running this command and ingore the result

        shell: /usr/bin/boo || /bin/true

或使用ingnore_error来忽略错误信息

tasks:

 - name: running this command and ingore the result

   shell: /usr/bin/boo

   ingore_error: True

 

例子:

- hosts: webserers
  remote_user: root
  tasks:
  - name:  create nginx group
    group: name=nginx system=yes gid=606
    
  - name:  crete nginx user
    user: name=nginx system=yes uid=604 gid=nginx

         

3handlers

用于当关注的某资源发生变化时采取的一定操作。

notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时都执行指定的操作,取而代之,仅在所有的变化完成后一次性执行的指定操作。在notify中列出的操作叫handler,也即notify中调用handler中定义的操作。

- name: template configuration file

  template: src=template.j2 dest=/etc/foo.configuration

  notify:

  - restart memcached

  - restart apache

 

handlertask列表,这些task与前述的task基础上没有本质上的不同:

handlers:

- name:  restart memcached

  service: name=memcached status=restarted

- name: restart apache

  service: name=httpd status=restarted

      

例子:

- hosts: webserers

  remote_user: root

  tasks:

  - name: install apache

    yum: name=httpd status=latest

  - name: install configuration file

    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httdp.conf

  - name: start apache

    service: name=httpd status=started enable=true        

当配置文件发生改变时:

- hosts: webserers

  remote_user:root

  tasks:

  - name: install apache

    yum: name=httpd status=latest

  - name: install configuration file

    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httdp.conf

    notify:

    - restart apache

  - name: start apache

    service: name=httpd status=started enable=true

  handlers:

  - name: restart apache

    service: name=httpd status=restart


4、使用ansible的注意事项

- hosts: web
  remote_user: root
  vars:
  - dir: /root/aaa/
  tasks:
  - name: copy file
    copy: src=/root/ceshi/updatecode.sh dest={{ dir }}
  - name: aa
    copy: src=/alidata/www/tuiguang/index.php dest={{ dir }}
  


备注:
①在每一个冒号后面必须要有一个空格
②必须要给每一个任务其一个名字,如果在同一个名字下出现几个相同的任务,只会执行最后一个
③vars是定义变量,变量可以有多个,里面调用变量是采用jinjia2模板
④yaml语言是通过层级区分不同的任务

⑤在每一个主机前面必须一个 -,而且要顶格


二、如何在playbook中使用变量

1、定义变量(变量名:变量值)

    vars:

    - service:httpd

    - package:httpd

    调用:

    name = {{ service }}

    name = {{ package }}

 

2ansible所获得的变量也可以定义

    获取变量方法:ansible+ip(192.168.88.133) -m setup

    例子:

    - hosts:webserers

      remote_user:root

      tasks:

      - name: copy file

        copy: content="{{ ansible_all_ipv4_address }}" dest=/tmp/var.ans

 

3、在inventory中定义变量(/etc/ansible/hosts)

    [webserers]

    192.168.88.134 testvar=88.134

    192.168.88.136 testvar=88.136

调用方法:

    copy: content="{{ ansible_all_ipv4_address }},{{ testvar }}" dest=/tmp/var.ans

 

4、在playbook使用条件测试

    如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用条件测试

    when语句

    task后添加when子句即可使用条件测试,when语句支持jinja2表达式语法。例如

    tasks:

    - name: shutdown Debian flavored system

      command: /sbin/shutdown -h now

      when: ansible_os_family == "Debian"

    when语句还可以使用jinja2的大多"filter",例如要忽略此前某语句的错误,并基于此结果(faild或者success)运行后面指定的语句,可使用类似的如下形式

    tasks:

    - command: /bin/false

      register: result

      ignore_error: True

    - command:/bin/something

      when:result/faild

    - command: /bin/something_else

      when:result/success

    - command: /bin/something_else

      when: result/skipped

      

    此外,when语句还可以使用facts或者playbook中定义的变量

    例如:如果对方主机名是node2.example.com,才创建user10用户,否则不创建

    - hosts: all

      remote_user: root

      vars:

      - username:user10

      tasks:

      - name: create {{ username }} user

        user: name={{ username }}

        when: ansile_fqdn == "node2.example.com"

      

5、迭代(即循环)重复执行同类的task时使用

  当有需要重复性执行的任务时,可以使用迭代机制,其使用格式为将需要迭代的内容定义为 item变量引用,并通过 with_items语句来指明迭代的元素列表即可,例如:

    - name: add serveral users

      user:name={{ item }} state=present groups=wheel

      with_items:

       - testuser1

       - testuser2

       - testuser3

       

 上面的语句功能等同于下面的语句:

    - name: add user testuser1

      user: name=testuser1 state=present groups=wheel

    - name: add user testuser2

      user: name=testuser2 state=present groups=wheel

    - name: add user testuser3

      user: name=testuser3 state=present groups=wheel

 

事实上,with_items中还可以使用元素为hashes。例如:

    - name: add serveral users

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

      with_items:

       - { name:'testuser1',group:'wheel' }

       - { name:'testuser2',group:'wheel' }

       - { name:'testuser3',group:'wheel' }

 

6、模板元素(一般以 .j2命名)

把经常发生变化的元素改成变量

 

7tags标签

playbook中可以为某个或某些任务定义一个"标签",在执行此playbook命令使用--tags 选项能实现仅指定的task而非所有的

运行方式:ansible-playbook+文件名(.yaml)+ --tags="自定义标签名"

特殊的tagsalways

    tags:

    - always

    

三、roles

ansible1.2版本后引入的新特性,用于层次性、结构化地组织playbookroles能够根据层次型结构自动装载变量文件、tasks以及handles等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include 它们的一种机制。角色一般基于主机构建服务的场景中,但也可以用于构建守护进程场景中。

    一个roles的案例如下所示:

    site.yml

    webserers.yml

    dbserers.yml

    roles/

        common/

         file/

         template/

         tasks/

         handlers/

         vars/

         meta/

        webserers/

          file/

         template/

         tasks/

         handlers/

         vars/

         meta/

    playbook中,可以这样使用roles

    - hosts:webserers

      roles:

       - common

       - webserers

    也可以向roles传递参数,如:

    - hosts:webserers

      roles:

       - common

       - { role:foo_app,dir:'/dir/a',port:5000 }

       - { role:foo_app,dir:'/dir/b',port:5001 }

    甚至可以使用条件式使用roles,如:

    - hosts:webserers

      roles:

       - { role:foo_app,when:"ansible_os" == "centos" }



 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值