ansible分享

栏目: 服务器 · 发布时间: 5年前

内容简介:本文主要介绍了ansible中一些重要概念和重要特性。并不能cover住ansible的全部特性以及细节。ansible是一个IT自动化工具。可以用于:ansible具有如下特点:

本文主要介绍了ansible中一些重要概念和重要特性。并不能cover住ansible的全部特性以及细节。

ansible是一个IT自动化工具。可以用于:

  • 配置管理

  • 应用程序部署

  • 执行ad-hoc任务

    • 所谓的ad-hoc就是“ 临时命令 ”,注重于解决一些简单的或临时遇到的任务
  • 多节点编排。比如:零停机滚动升级等

ansible具有如下特点:

  • ansible是使用 Python 开发的

  • ansible系统由控制主机和被管理主机组成

  • no agents/no server:控制主机默认通过ssh连接被管理主机,因此,ansible是无服务端的,去中心化的。所以,只需要简单的复制操作,就可以完成控制主机的迁移。同时,被管理主机上无需安装agent

  • 基于模块工作,可以使用任何语言开发模块

  • 基于推送的方式:由调用者控制变更在被管理主机上的发生时间

  • 许多自带模块提供了 幂等判断机制 ,这意味着多次执行相同的任务是安全的

    • 比如,通过cron模块添加定时任务时,如果任务已经存在,那么不会重复添加
  • playbook使用yaml编写

ansible的整体架构如下图所示:

ansible分享

  • Host Inventory:由ansible管理的主机的清单。其中包含主机名、主机变量、主机分组、组变量等
  • Connection Plugins:ansible使用连接插件连接到被管理主机。默认是使用ssh
  • Plugins:插件用来扩展ansible的核心功能。ansible通过调用插件,完成特定的功能。比如,调用inventory插件,获取主机清单。ansible支持很多类型的插件,每种类型的插件,需要符合特定的接口规范
  • Core Modules:模块决定了ansible能够在被管理主机上执行哪些任务
  • Custom Modules:用户添加的扩展模块
  • Playbook: 用来编排高级的IT任务

ansible执行任务的流程,大致如下:

ansible分享

值得特别强调的点

1,ansible有两种任务执行模式:

  • ad-hoc模式:用于执行简单的、临时的任务
  • playbook模式:用于编排高级的、复杂的任务

2,尽量使用ansible自带的模块,而不是 shell 脚本,因为ansible的很多模块提供了幂等判断机制

3,模块和插件的区别:

  • 模块会被上传到被控制主机上,是在被控制主机上执行的。其实,也可以把模块理解为“Task Plugin”
  • 插件是在控制主机上,被ansible调度执行的

1,安装ansible:

 
  
xxxxxxxxxx
sudo yum install -y python-setuptools
sudo easy_install --upgrade pip
sudo pip install ansible

2,ansible按照如下的优先级顺序查找配置文件:

  • ANSIBLE_CONFIG环境变量
  • ~/.ansible.cfg
  • /etc/ansible/ansible.cfg

3,ansible配置文件:

(下面仅列出了少数参数)

 
  
xxxxxxxxxx
[defaults]
# 指定inventory文件的位置,默认值是/etc/ansible/hosts
inventory = /etc/ansible/hosts
# forks是一个非常重要的、优化时需要重点关注的参数
# + ansible会创建forks个子进程,并发地管理多台被控主机
# + 默认值是5,随着被管理主机的增多,需要适当调大
forks = 5
# ansible在通过ssh连接被控主机时,是否检查其公钥
host_key_checking = False
# ssh连接的超时时间,单位是秒
timeout = 60
# 指定存储ansible日志的文件(默认,不记录日志)
log_path = /var/log/ansible.log
[ssh_connection]
# 设置ansible通过ssh连接被控主机时,使用的参数
ssh_args = -o ControlMaster=auto -o ControlPersist=60s

4,inventory文件:

既可以使用 静态inventory 文件,也可以使用 动态inventory 。使用动态inventory的好处是:可以通过其它系统(比如,CMDB、LDAP)动态地生成主机清单,避免产生 需要在多个系统维护服务器列表 的情况。

动态inventory是一个 可执行程序 ,ansible会创建一个子进程执行这个程序,然后从该子进程的标准输出获取主机信息。因此,可以用任何语言编写动态inventory程序,只需要该程序满足ansible的 规范 即可。(更多关于如何编写动态inventory的信息,请移步参考文档)

可以在inventory中对主机进行分组。ansible可以同时操作属于一个组的多台主机。在定义主机的时候,可以为主机指定主机变量。也可以为组指定组变量,相当于同时为组内的所有主机指定变量。这些变量可以被插件(比如,连接插件)、模块等使用。

下面是一个非常简单的例子:

 
  
xxxxxxxxxx
[mongodb]
mongodb-101 ansible_ssh_host=192.168.10.101
mongodb-102 ansible_ssh_host=192.168.10.102
[mongodb:vars]
ansible_ssh_private_key_file=/etc/ansible/id_rsa

如果想要获取更多关于inventory的信息,可以跟进 这个链接

5,执行第一个ad-hoc任务:

使用ansible命令,执行ad-hoc任务,其使用方法是:

 
  
xxxxxxxxxx
ansible <host-pattern> [-f forks] [-m module_name] [-a args]

其中:

  • <host-pattern>用于指定对哪些机器和分组执行任务
  • -f用于指定ansible启动多少个子进程来执行任务
  • -m用于指定要在被控制主机上执行的模块(任务)
  • -a用于指定传递给模块的参数

比如,使用yum模块,在所有主机上安装最新版本的httpd-tools:

 
  
xxxxxxxxxx
ansible all -m yum -a "name=httpd-tools state=latest" -b

ansible内建了几百个模块。可以使用 ansible-doc -l 列出所有的模块。还可以使用 ansible-doc -s <module_name> 查看模块的用法。

playbook是由一个或多个play组成的列表。 play的主要功能是:为事先归并为一组的主机,应用相同的配置、添加相同的变量、执行相同的任务、以及在任务执行完成之后,触发相同的动作。 playbook通过编排play,完成复杂的IT任务。。

一个play由以下部分组成:

  • Target section:

    • hosts:用于指定在哪些主机上运行play
    • user:用于指定在远程主机上,以哪个用户的身份执行任务
    • ...
  • Variable section:定义运行play时,使用的变量

  • Task section:定义要在远程主机上运行的任务列表

    • name:任务的名字。用来描述任务是做什么的

    • 'module: options':调用的module和传递给module的参数

    • notify:用于指定在任务完成后,触发哪些handler

      • 需要注意的是:默认情况下,只有任务执行成功,并且改变了远程主机的状态的情况下,才会发起notify
    • ...

  • Handler section: 定义在任务完成后,触发的动作

    • handler也是task
    • 对于一个handler而言,即使它被notify了次,也只会在play中的所有task执行完之后,执行一次
    • handler会按照声明的顺序执行

下面是一个例子:

 
  
xxxxxxxxxx
[vagrant@mongodb-103 ~]$ cat playbook.yml
#! /usr/bin/ansible-playbook
---
- hosts: all
  gather_facts: false
  vars:
    - key1: value1
      key2: value2
    -
      key3: value3
      key4: value4
  tasks:
    - name: echo vars
      command: echo key1:{{key1}},key3:{{key3}}
      notify:
        - echo something
  handlers:
    - name: echo something
      command: echo OK
...
[vagrant@mongodb-103 ~]$ chmod +x playbook.yml
[vagrant@mongodb-103 ~]$ ./playbook.yml
PLAY [all] ***********************************************************************************************************************
TASK [echo vars] *****************************************************************************************************************
changed: [mongodb-101]
changed: [mongodb-102]
RUNNING HANDLER [echo something] *************************************************************************************************
changed: [mongodb-101]
changed: [mongodb-102]
PLAY RECAP ***********************************************************************************************************************
mongodb-101                : ok=2    changed=2    unreachable=0    failed=0
mongodb-102                : ok=2    changed=2    unreachable=0    failed=0

可以通过setup模块,采集远程主机的基础信息(比如,硬件,操作系统等),这些信息会被保存到ansible_facts变量中。

在使用playbook的时候,这个采集行为是默认的。但是,由于该操作比较耗时。所以,在不需要主机基础信息的情况下,可以考虑关闭采集,或者对采集结果进行缓存。

比如,可以通过下面的命令获取远程主机上的所有IPV4地址:

 
  
xxxxxxxxxx
[vagrant@mongodb-103 ~]$ ansible all -m setup -a 'filter=ansible_all_ipv4_addresses'
mongodb-101 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.10.101",
            "10.0.2.15"
        ]
    },
    "changed": false
}
mongodb-102 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.10.102",
            "10.0.2.15"
        ]
    },
    "changed": false
}

角色是以特定的层级目录结构进行组织的tasks、handlers、variables、templates、files等。

按照下面的方式,定义角色:

 
  
x
role_name/(以角色名命名的目录)
  tasks/:
    如果存在 main.yml,那么其中列出的 tasks 将被添加到 play 中
    所有 include 任务可以引用该的文件,不需要指明文件的路径
  handlers/:
    如果存在 main.yml,那么其中列出的 handlers 将被添加到 play 中
  vars/:
    如果存在 main.yml,那么其中列出的 variables 将被添加到 play 中
  meta/:
    如果存在 main.yml,其中列出的 “角色依赖” 将被添加到 roles 列表中
  templates/:
    所有 templates 任务可以引用该目录中的文件,不需要指明路径
  files/:
    所有 copy 和 script 任务可以引用该目录中的文件,不需要指明路径
  defaults/:
    此目录中至少应该有一个名为main.yml的文件,用于设定默认变量

ansible配置文件中roles_path参数是冒号分隔的路径列表,ansible会去这些路径下寻找角色。比如:

 
  
xxxxxxxxxx
[defaults]
roles_path = /etc/ansible/roles

在playbook中,可以用类似下面的方式引用role:

 
  
#! /usr/bin/ansible-playbook
---
- hosts: all
  gather_facts: false
  roles:
    - test
...

更多关于角色的细节,可以查看 这篇文档

可以通过when语句实现: 在某些条件满足的情况下,才执行任务(或角色) 。使用when语句非常简单,并且在when语句中,可以使用jinja2表达式。

比如:

 
  
xxxxxxxxxx
tasks:
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"

这个例子的含义是:只有当远程主机的操作系统是Debian时,才执行关机命令。

更多关于条件选择的细节,可以查看 这篇文档

可以通过循环实现:使用不同的参数,多次执行同一个任务。比如,向远程主机批量添加用户:

 
  
xxxxxxxxxx
- name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1
     - testuser2

更多关于循环的细节,可以查看 这篇文档

大规模集群的一些思考

当集群规模变大的时候,主控机的压力就会随之增大,因此,需要找到一些方式,降低主控机的压力,从而避免出现性能瓶颈:

  • 按业务线对服务器进行分组,这样可以将一个大的集群,就被拆分成若干个规模较小的集群了

  • 分批次执行任务。这样做有2点好处:

    • 如果正在执行的操作有误,可以减小故障影响
    • 单次操作的服务器数据规模变小了
  • 下发文件时,走专门的下载通道,降低主控机压力

  • 对主控机做备份。一方面可以防止环境丢失;另外一方面因为主控机往往具有较高权限,重新授权代价较大

  • 异步执行任务。下面会介绍

  • 使用ansible-pull。下面会介绍

ansible支持异步地执行任务,也就是:在将任务下发之后,不再保持连接,而是每隔一段时间轮询一次执行结果,直到任务完成。这对于执行时间较长的任务尤其有用。

想要让任务异步执行,需要在task中,加入两个参数:async和poll。

其中:

  • async用于指定任务执行时间的上限。如果任务执行时间超过这个上限,则认为任务执行失败。如果未设置这个参数,那么任务会同步执行
  • poll用于指定轮询的时间间隔。如果设为0,则表示不关心任务的执行结果
 
  
#! /usr/bin/ansible-playbook
---
- hosts: all
  gather_facts: false
  tasks:
    - name: sleep for long time
      command: /bin/sleep 10s
      async: 20
      poll: 2
...

如果想要更方便的查看轮询结果,可以使用async_status模块,比如:

 
  
x
#! /usr/bin/ansible-playbook
---
- hosts: all
  gather_facts: false
  tasks:
    - name: sleeper
      command: /bin/sleep 30s
      async: 40
      poll: 0
      register: job_sleeper
    - name: checker
      async_status: jid={{job_sleeper.ansible_job_id}}
      retries: 30
      register: job_checker
      until: job_checker.finished
...

在这个例子中:

第一个任务是一个异步任务,其执行结果被注册到了job_sleeper变量中。

第二个任务使用async_status模块轮询第一个任务的执行结果,并返回轮询结果。最多轮询30次。

ansible默认使用推模式。而asible-pull则是使用拉模式。

其原理是:去指定的VCS源上拉取playbook,然后在 本机 执行。比如:

 
  
xxxxxxxxxx
ansible-pull -U https://github.com/tim-chow/drawdotio.git/ -i /etc/ansible/hosts -d /home/vagrant/myrepo/ myplaybook.yml

其中:

  • -U:用于指定VCS源
  • -i:用于指定inventory文件
  • -d:ansible-pull会把VCS源检出到-d所指定的目录
  • myplaybook.yml:要执行的playbook,可以是任意名字

因为VCS可以做到水平扩展,所以,ansible-pull可以无限的水平扩展。

通常把ansible-pull与crontab一起使用,这样就可以做到:定期的在本地执行playbook了。

  • 自定义插件和模块

    • 扩展ansible的功能。比如,可以通过定义新的回调机制,在playbook执行成功时,发送邮件给各部门,组织新一轮测试工作,免去人工干预;在playbook执行失败时,发送短信给开发人员,尽快人工干预,排查错误等
  • ansible api

    • 为ansible开发更友好的Web客户端

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

1024·人与机器共同进化

1024·人与机器共同进化

东西文库 / 译言·东西文库/电子工业出版社 / 2013-12-20 / 55元

《1024》:国内第一本专注于科技文化的mook。 本期创刊号将目光定焦在“人与机器”这个超热点领域。 如果把机器获得思维能力看作是一种进化, 那人类具备不朽之躯同样也是一种进化。 这是一个野心勃勃但又充满不确定性的未来。 在我们一厢情愿地猜测机器将在不远的将来赶超自己而惶惶不可终日时,人类其实还有一个机会——变得更像机器。这并非科幻小说,而是正在发生的现实。人类创造......一起来看看 《1024·人与机器共同进化》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具