自动化运维工具之ansible

 

一,ansible简介

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,其批量系统配置、批量程序部署、批量运行命令等功能配置起来十分简单。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:

  1. <code>
  2. (1)、连接插件connection plugins:负责和被监控端实现通信;
  3. (2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
  4. (3)、各种模块核心模块、command模块、自定义模块;
  5. (4)、借助于插件完成记录日志邮件等功能;
  6. (5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
  7. </code>

ansible是我使用的第一个自动化运维工具,上手感觉非常简单,其设计原则如下:

  1. <code>
  2. 安装过程简单;
  3. 运行速度较快;
  4. 不需要服务器或客户端程序,利用现有的sshd服务;
  5. 使用一种人机友好的语言;
  6. 注重安全;
  7. 能快速管理远程机器,不用引导;
  8. 基于模块工作,可使用任意语言开发模块;
  9. 可作为非root使;
  10. 永远是最容易使用的自动化系统。
  11. </code>

二、安装

2.1 编译安装

  1. <code>
  2. [root@node1 ansible]# yum install -y PyYAML python-crypto2.6 python-httplib2 python-jinja2 python-keyczar python-paramiko python-setuptools python-simplejson #解决依赖关系
  3. [root@node1 ansible]# tar xf ansible-1.5.4.tar.gz
  4. [root@node1 ansible]# cd ansible-1.5.4
  5. [root@node1 ansible]# python setup.py build
  6. [root@node1 ansible]# python setup.py install
  7. [root@node1 ansible]# mkdir /etc/ansible
  8. [root@node1 ansible]# cp -r examples/* /etc/ansible
  9. </code>

2.2 rpm包安装

下面使用rpm包安装作为实例,使用ansible-1.9.2-1.el6.noarch.rpm!

  1. <code>
  2. [root@sta ansible]# yum install -y PyYAML python-crypto2.6 python-httplib2 python-jinja2 python-keyczar python-paramiko python-setuptools python-simplejson #解决依赖关系
  3. [root@node1 ansible]# rpm -ivh ansible-1.9.2-1.el6.noarch.rpm
  4. [root@node1 ansible]# cd /etc/ansible/
  5. [root@node1 ansible]# ls
  6. ansible.cfg hosts roles
  7. </code>

2.3 定义主机与组

  1. <code>
  2. [root@node1 ansible]# vim hosts #在hosts文件中定义主机与组
  3. :.,$s/^\([^[:space:]#]\)/#/g ------》在末行模式下,使用以下命令注释掉所有的行
  4. [webservers] ---------》在文件末添加一个webservers组
  5. node1.feiyu.com
  6. node2.feiyu.com
  7. </code>

Ansible内置了一些关于连接主机的变量,设置以下变量控制ansible与远程主机:

  1. <code>
  2. ansible_ssh_host:ansible通过ssh连接的主机地址。
  3. ansible_ssh_port:SSH连接主机的默认端口。
  4. ansible_ssh_user:默认SSH连接的用户。
  5. ansible_ssh_pass:SSH连接的密码(这是不安全的,ansible极力推荐使用--ask-pass选项或使用SSH keys)。
  6. ansible_sudo_pass:sudo用户的密码。
  7. ansible_connection:SSH连接的类型,可以是 local,ssh,paramiko,在ansible 1.2之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(支持的前提)。
  8. ansible_ssh_private_key_file:SSH连接的公钥文件。
  9. ansible_shell_type:指定主机所使用的shell解释器,默认是sh,你可以设置成csh, fish等shell解释器。
  10. ansible_python_interpreter:用来指定python解释器的路径。
  11. ansible\_\*\_interpreter:用来指定主机上其他语法解释器的路径,例如ruby,perl等其他解释器。
  12. </code>

例如:

  1. <code>
  2. feiyu ansible_ssh_port=2222 ansible_ssh_user=manager
  3. my_host ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
  4. freebsd_host ansible_python_interpreter=/usr/local/bin/python
  5. ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3
  6. </code>

组成员也支持正则表述:

  1. <code>
  2. [webserver]
  3. www[01-50].tianfeiyu.com
  4. [databases]
  5. db-[a:f].example.com
  6. </code>

三、简单应用

ansible通过ssh实现配置管理、应用部署、任务执行等功能,因此,需要事先配置ansible端能基于密钥认证的方式联系各被管理节点。

语法格式为:

  1. <code>
  2. ansible [-f forks] [-m module_name] [-a args]
  3. -m module:默认为command
  4. </code>

1,使用ping模块

  1. <code>
  2. [root@node1 ansible]# ansible all -m ping #-m指定模块,一般执行成功显示为黄色或绿色,失败为红色
  3. node1.feiyu.com | success >> {
  4. "changed": false,
  5. "ping": "pong"
  6. }
  7. node2.feiyu.com | success >> {
  8. "changed": false,
  9. "ping": "pong"
  10. }
  11. [root@node1 ansible]# ansible all -a 'date' #-a表示使用命令,没指定模块表示使用默认模块,-m command
  12. node1.feiyu.com | success | rc=0 >>
  13. Tue Aug 18 03:48:32 PDT 2015
  14. node2.feiyu.com | success | rc=0 >>
  15. Tue Aug 18 03:48:32 PDT 2015
  16. [root@node1 ansible]# ansible all -a 'service httpd status'
  17. node1.feiyu.com | FAILED | rc=3 >>
  18. httpd is stopped
  19. node2.feiyu.com | FAILED | rc=3 >>
  20. httpd is stopped
  21. </code>

注意:其不支持管道的方式!!!

  1. <code>
  2. [root@node1 ansible]# ansible-doc -l #列出所有模块
  3. </code>

2,使用copy模块

  1. <code>
  2. [root@node1 ansible]# ansible-doc -s copy #查看copy模块的用法
  3. </code>

## 复制文件到远程主机

相关选项如下:

  1. <code>
  2. backup:在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no
  3. content:用于替代“src”,可以直接设定指定文件的值
  4. dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
  5. directory_mode:递归设定目录的权限,默认为系统默认权限
  6. force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
  7. others:所有的file模块里的选项都可以在这里使用
  8. src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用“/”来结尾,则只复制目录里的内容,如果没有使用“/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
  9. [root@node1 ansible]# ansible webservers -m copy -a "src=/etc/fstab dest=/tmp "
  10. node1.feiyu.com | success >> {
  11. "changed": true,
  12. "checksum": "bea5bff6ef922e8e603fc5714edbbf6fc613e321",
  13. "dest": "/tmp/fstab",
  14. "gid": 0,
  15. "group": "root",
  16. "md5sum": "87e134fd31b425a1d4f8fe43ade63a51",
  17. "mode": "0644",
  18. "owner": "root",
  19. "secontext": "unconfined_u:object_r:admin_home_t:s0",
  20. "size": 805,
  21. "src": "/root/.ansible/tmp/ansible-tmp-1439895335.38-56321228265546/source",
  22. "state": "file",
  23. "uid": 0
  24. }
  25. node2.feiyu.com | success >> {
  26. "changed": true,
  27. "checksum": "bea5bff6ef922e8e603fc5714edbbf6fc613e321",
  28. "dest": "/tmp/fstab",
  29. "gid": 0,
  30. "group": "root",
  31. "md5sum": "87e134fd31b425a1d4f8fe43ade63a51",
  32. "mode": "0644",
  33. "owner": "root",
  34. "secontext": "unconfined_u:object_r:admin_home_t:s0",
  35. "size": 805,
  36. "src": "/root/.ansible/tmp/ansible-tmp-1439895335.39-253641776148808/source",
  37. "state": "file",
  38. "uid": 0
  39. }
  40. </code>

3,使用cron模块

  1. <code>
  2. [root@node1 ansible]# ansible all -m cron -a 'name="cron job" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate 192.168.1.1"'
  3. node1.feiyu.com | success >> {
  4. "changed": true,
  5. "jobs": [
  6. "cron job"
  7. ]
  8. }
  9. node2.feiyu.com | success >> {
  10. "changed": true,
  11. "jobs": [
  12. "cron job"
  13. ]
  14. }
  15. [root@node1 ansible]# ansible all -a "crontab -l" #查看
  16. #Ansible: cron job
  17. */3 * * * * /usr/sbin/ntpdate 192.168.1.1
  18. #Ansible: cron job
  19. */3 * * * * /usr/sbin/ntpdate 192.168.1.1
  20. </code>

4,使用group模块

  1. <code>
  2. [root@node1 ansible]# ansible all -m group -a "gid=306 system=yes name=mysql" #添加组,并创建为系统用户
  3. node1.feiyu.com | success >> {
  4. "changed": true,
  5. "gid": 306,
  6. "name": "mysql",
  7. "state": "present",
  8. "system": true
  9. }
  10. node2.feiyu.com | success >> {
  11. "changed": true,
  12. "gid": 306,
  13. "name": "mysql",
  14. "state": "present",
  15. "system": true
  16. }
  17. </code>

5,使用service模块

  1. <code>
  2. [root@node1 ansible]# ansible all -m service -a "state=started name=httpd enabled=yes"
  3. node2.feiyu.com | success >> {
  4. "changed": true,
  5. "enabled": true,
  6. "name": "httpd",
  7. "state": "started"
  8. }
  9. node1.feiyu.com | success >> {
  10. "changed": true,
  11. "enabled": true,
  12. "name": "httpd",
  13. "state": "started"
  14. }
  15. </code>

6,file模块

## 设置文件的属性

相关选项如下:

  1. <code>
  2. force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
  3. group:定义文件/目录的属组
  4. mode:定义文件/目录的权限
  5. owner:定义文件/目录的属主
  6. path:必选项,定义文件/目录的路径
  7. recurse:递归设置文件的属性,只对目录有效
  8. src:被链接的源文件路径,只应用于state=link的情况
  9. dest:被链接到的路径,只应用于state=link的情况
  10. state:
  11. directory:如果目录不存在,就创建目录
  12. file:即使文件不存在,也不会被创建
  13. link:创建软链接
  14. hard:创建硬链接
  15. touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
  16. absent:删除目录、文件或者取消链接文件
  17. [root@node1 tmp]# ansible all -m file -a "src=/etc/inittab dest=/tmp/a state=link" #创建链接
  18. </code>

四、YAML

4.1 YAML介绍

YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。

YAML Ain’t Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)。其特性:

  1. <code>
  2. YAML的可读性好
  3. YAML和脚本语言的交互性好
  4. YAML使用实现语言的数据类型
  5. YAML有一个一致的信息模型
  6. YAML易于实现
  7. YAML可以基于流来处理
  8. YAML表达能力强,扩展性好
  9. </code>

更多的内容及规范参见http://www.yaml.org

4.2 YAML语法

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来代表,Map里的键值对用”:”分隔。下面是一个示例。

  1. <code>
  2. name: John Smith
  3. age: 41
  4. gender: Male
  5. spouse:
  6. name: Jane Smith
  7. age: 37
  8. gender: Female
  9. children:
  10. - name: Jimmy Smith #定义任务的说明
  11. age: 17
  12. gender: Male
  13. - name: Jenny Smith
  14. age 13
  15. gender: Female
  16. </code>

YAML文件扩展名通常为.yaml,如example.yaml。

五、ansible playbooks

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

  1. <code>
  2. - hosts: webnodes
  3. vars:
  4. http_port: 80
  5. max_clients: 256
  6. remote_user: root
  7. tasks:
  8. - name: ensure apache is at the latest version
  9. yum: name=httpd state=latest
  10. - name: ensure apache is running
  11. service: name=httpd state=started
  12. handlers:
  13. - name: restart apache
  14. service: name=httpd state=restarted
  15. </code>

5.1 playbook基础组件

5.1.1 Hosts和Users

playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的

  1. <code>
  2. -hosts: webnodes
  3. remote_user: root
  4. </code>

不过,remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。

  1. <code>
  2. - hosts: webnodes
  3. remote_user: feiyu
  4. tasks:
  5. - name: test connection
  6. ping:
  7. remote_user: feiyu
  8. sudo: yes
  9. </code>

5.1.2 任务列表和action

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

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。

每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。

定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容。如果action一行的内容过多,也中使用在行首使用几个空白字符进行换行。

  1. <code>
  2. tasks:
  3. - name: make sure apache is running
  4. service: name=httpd state=running
  5. </code>

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

  1. <code>
  2. tasks:
  3. - name: disable selinux
  4. command: /sbin/setenforce 0
  5. </code>

如果命令或脚本的退出码不为零,可以使用如下方式替代:

  1. <code>
  2. tasks:
  3. - name: run this command and ignore the result
  4. shell: /usr/bin/somecommand || /bin/true
  5. </code>

或者使用ignore_errors来忽略错误信息:

  1. <code>
  2. tasks:
  3. - name: run this command and ignore the result
  4. shell: /usr/bin/somecommand
  5. ignore_errors: True
  6. </code>

5.1.3 handlers

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

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

  1. <code>
  2. - name: template configuration file
  3. template: src=template.j2 dest=/etc/foo.conf
  4. notify:
  5. - restart memcached
  6. - restart apache
  7. </code>

handler是task列表,这些task与前述的task并没有本质上的不同。

  1. <code>
  2. handlers:
  3. - name: restart memcached
  4. service: name=memcached state=restarted
  5. - name: restart apache
  6. service: name=apache state=restarted
  7. </code>

案例:

  1. <code>
  2. heartbeat.yaml
  3. - hosts: hbhosts
  4. remote_user: root
  5. tasks:
  6. - name: ensure heartbeat latest version
  7. yum: name=heartbeat state=present
  8. - name: authkeys configure file
  9. copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
  10. - name: authkeys mode 600
  11. file: path=/etc/ha.d/authkeys mode=600
  12. notify:
  13. - restart heartbeat
  14. - name: ha.cf configure file
  15. copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
  16. notify:
  17. - restart heartbeat
  18. handlers:
  19. - name: restart heartbeat #与notify保持一致
  20. service: name=heartbeat state=restarted
  21. </code>
     

自动化运维工具之ansible的更多相关文章

  1. 自动化运维工具之 Ansible 介绍及安装使用

    一.初识Ansible 介绍: Absible 使用 模块(Modules)来定义配置任务.模块可以用标准脚本语言(Python,Bash,Ruby,等等)编写,这是一个很好的做法,使每个模块幂等.A ...

  2. 自动化运维工具:ansible

    自动化运维工具:ansible Ansible(1):简介和基本概念 Ansible(2):安装配置 Ansible(3):ansible资源清单管理 Ansible(4):常用模块

  3. Linux实战教学笔记25:自动化运维工具之ansible (一)

    第二十五节 ansible之文件的批量分发 标签(空格分隔): Linux实战教学笔记-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转 ...

  4. 自动化运维工具之ansible(转)

    原文链接:http://os.51cto.com/art/201409/451927_all.htm

  5. 自动化运维工具Ansible详细部署 (转载)

    自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog. ...

  6. 自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客

    自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客 自动化运维工具Ansible详细部署

  7. sshpass做秘钥分发,ansible做自动化运维工具

    最近公司机器的增多,顺便还要上报表系统,考虑到服务器越来越多,手工的管理显得越来的越吃力,所以打算推进公司自动化运维工具的使用. 推进的过程中,一步一个坑踩过来的.由于公司之前未运用过自动化运维工具, ...

  8. 自动化运维工具——ansible详解(一)

    ansible 简介 ansible 是什么? ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.chef.func.fabric)的优点,实现了批量系统 ...

  9. 企业级自动化运维工具应用实战-ansible

    背景 公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运 ...

随机推荐

  1. 初识chromium thread的实现

    接触chromium已有一段时间,写点东西学习一下吧. 首先说一下用法,如何利用chromium封装好的thread类来开一个线程.在base里有一个封装该类的头文件thread.h,include它 ...

  2. Linux趣谈

    要解释操作系统是如何工作的,首先可以用这几个关键字来简单地概括一下:冯诺依曼.堆栈机制和中断机制. 提到冯诺依曼很显然就是在说存储程序了,这大概是计算机能够运行最为基础的条件,属于基石级别的.它的基本 ...

  3. mkdir、whoami、touch

    mkdir whoami touch:"摸",如果文件不存在,就建立新文件,如果存在,就改变文件的访问时间atime等时间戳信息. mkdir aa ls –ld aa 创建多级目 ...

  4. Mysql导出导入乱码问题解决

    MySQL从4.1版本开始才提出字符集的概念,所以对于MySQL4.0及其以下的版本,他们的字符集都是Latin1的,所以有时候需要对mysql的字符集进行一下转换,MySQL版本的升级.降级,特别是 ...

  5. 解决Ubuntu Server 12.04换了网卡MAC地址后 网络不可用的问题.

    重装了系统,新建了一个ubuntu虚拟机,加载原来的镜像,结果启动后网络变得不正常了,提示信息 Waiting for network configuration...Waiting up to 60 ...

  6. [Java 8] (5) 使用Lambda表达式进行设计

    使用Lambda表达式进行设计 在前面的几篇文章中,我们已经见识到了Lambda表达式是怎样让代码变的更加紧凑和简洁的. 这一篇文章主要会介绍Lambda表达式怎样改变程序的设计.怎样让程序变的更加轻 ...

  7. 基于Lucene的文件检索Demo

    通过Lucene实现了简单的文件检索功能的Demo.这个Demo支持基于文件内容的检索,支持中文分词和高亮显示. 下面简单的介绍下核心的类 1)索引相关的类 1.FileIndexBuilder -- ...

  8. [Eclipse]The type XXX cannot be resolved. It is indirectly referenced from required .class files

    在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...

  9. android中的样式和主题

    有的时候我们一个页面要用很多个textview,而且这些textview的样式非常相像,这种情况下我们可以把这些样式抽取出来,然后在每个textview中引用即可,这样修改起来也方便. 我们来看一个简 ...

  10. Oracle 设置日志模式

    在NOARCHIVELOG模式下启动和运行一个数据库. 确定闪回恢复区的位置和归档日志目标目录的位置. 步骤一 为归档的重做日志配置FRA和单独的归档日志目标. 首先,设置FRA参数DB_RECOVE ...