ansible简单使用

一、ansible简介

ansible是新出现的 自动化 运维工具 , 基于Python研发 。 糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。 仅需在管理工作站上安装 ansible 程序配置被管控主机的 IP 信息,被管控的主机无客户端。 ansible 应用程序存在于 epel( 第三方社区 ) 源,依赖于很多 python 组件。

 

二、ansible特性

①模块化设计,调用特定的模块来完成特定的任务,本身是核心组件,短小精悍

②基于python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块实现

③部署简单,不需要在被控制端安装任何组件

④支持自定义模块功能

⑤支持playbook剧本,连续任务按先后设置顺序完成

⑥期望每个命令具有幂等性(不会重复执行相同的命令。例如不会重复安装软件)

 

三、ansible架构

ansible :  ansible自身核心模块

Modules: core modules(自带模块)、 custom modules(自定义模块)

connection plugins:连接插件,一般默认基于ssh 协议连接

host inventory:主机库,定义可管控的主机列表

Playbooks:剧本执行多个任务。并非必需让节点一次性运行多个任务

Plugins (loh、mail):借助于插件完成记录日志邮件等功能

 

四、安装ansible(操作均在主控端)

1、安装epel源
2、yum install -y ansible

这里我们使用ssh key实现 主控端于被控端的连接

# ssh-keygen -t rsa -P ''         //生成密钥
# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.12  //把公钥分配到被控端主机
# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.13
# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.14

定义 Host Inventory,定义可管控的主机

# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg   #ansible主配置文件
├── hosts         #Host Inventory配置文件
└── roles
#vim /etc/ansible/hosts
[webserver]            //主机组名
192.168.10.12      
192.168.10.13

[dbserver]
192.168.10.13
192.168.10.14

*定义可管控主机的说明

1、[ ]方括号中是组名,用于对系统进行分类,便于对不同系统进行个别的管理,一个系统也可以属于不同的组,比如一台服务可以同时属于webserver组和dbserver组

2、被控主机,可以用域名(必需可以DNS解析或更改hosts文件),也可以用IP

3、如果有主机的SSH端口不是标准的22端口,例如:可以明确表示为  192.168.12.12:8021

4、如果不是SSH key,而是使用密码,则需要设置用户名和密码,例如 : 192.168.12.12:8021  ansible_ssh_user=root  ansible_ssh_pass=123456

5、一组相似的hostname,可简写如下:

    [webserver]

    www[01:50].example.com

6、ansible_sudo   定义hosts sudo用户,例如:ansible_sudo=yadmin

      ansible_sudo_pass 定义hosts sudo密码,例如:ansible_sudo_pass=123456

      ansible_sudo_exe 定义hosts sudo路径,例如:ansible_sudo_exe=/usr/bin/sudo

 

通过上面我们知道Ansible默认的Inventory文件是/etc/ansible/hosts, 实际上Ansible还支持多个Inventory文件,这样我们就可以方便的管理不同业务或者不同环境中的机器。

1、首先准备一个文件夹,里面将存放多个Inventory文件

      mkdir /etc/ansible/Inventory

      cd /etc/ansible/Inventory

      vim docker    #定义inventory,格式和上面介绍的一样

      vim  hosts

2、修改ansible.cfg文件中的inventory的值,这里不再是指向一个文件,而是指向一个目录

  inventory      = /etc/ansible/inventory

 

五、基本使用

ansible <host-pattern> [-m module_name] [-a args] [options]

<host-pattern> :   指定组名,表示控制这个组的主机,all:表示所有的主机
-m module_name :使用哪个模块,默认是command
-a args :                 传递给模块的参数

在所有主机上执行date命令
# ansible all -m command -a 'date'   #因为command是默认是,所以可以省略,写成ansible -a 'date'
192.168.10.14 | SUCCESS | rc=0 >>
Mon May  2 16:00:52 EDT 2016

192.168.10.13 | SUCCESS | rc=0 >>
Mon May  2 16:00:53 EDT 2016

192.168.10.12 | SUCCESS | rc=0 >>
Mon May  2 16:00:53 EDT 2016

使用 ping模块检查所有主机

[root@c1 ~]# ansible all -m ping
192.168.10.14 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.10.12 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.10.13 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

使用raw模块,支持管道命令

# ansible dbserver -m raw -a "ip addr|grep 'eno16777736'"
192.168.10.14 | SUCCESS | rc=0 >>
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.10.14/24 brd 192.168.10.255 scope global eno16777736


192.168.10.13 | SUCCESS | rc=0 >>
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.10.13/24 brd 192.168.10.255 scope global eno16777736

使用copy模块,复制文件到被控所有主机 

# ansible all -m copy -a 'src=/root/sellsa.txt dest=/root/'

还是可以指定属主,属组,权限(传输完成之后,文件在被控端的属主和属组是heboan,权限是0644)

# ansible all -m copy -a 'src=/root/sellsa.txt dest=/root/  owner=heboan group=heboan mode=0644'

使用 cron模块,为dbserver组的主机设置定时任务计划

#ansible  dbserver -m cron -a  'name="ntpdate by heboan at 2016-4-28" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate s1a.time.edu.cn"'  
# ansible dbserver -a 'crontab -l'
192.168.10.13 | SUCCESS | rc=0 >>
#Ansible: ntpdate by heboan at 2016-4-28
*/3 * * * * /usr/sbin/ntpdate s1a.time.edu.cn

192.168.10.14 | SUCCESS | rc=0 >>
#Ansible: ntpdate by heboan at 2016-4-28
*/3 * * * * /usr/sbin/ntpdate s1a.time.edu.cn

使用yum模块安装软件

# ansible webserver -m yum -a 'name=httpd state=present'

使用service模块启动服务,并开机启动

# ansible webserver -m service -a 'name=httpd state=started enabled=yes' 
192.168.10.12 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}
192.168.10.13 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}

使用group模块添加用户组

# ansible dbserver -m group -a 'name=sellsa gid=1010'

使用user模块添加用户

# ansible dbserver -m user -a 'name=sellsa uid=1010 group=sellsa password=123456'

 

六、更多模块使用帮助文档

#ansible-doc -l    列出模块名及功能描述

#ansible-doc -s  <module_name>   输出模块使用方法

 

七、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"(仍是一种标记语言)。其特性:

YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好

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

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

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

 

八、playbooks

 playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先并归为一组的 主机装扮成事先通过ansible中的task定义好的角色,从根本上来讲,所谓的task就是调用ansible的一个module。将

多个play组织在一个playbook中就可以让它们连同起来按事先安排的机制同唱一台大戏。

下面是一个简单的示例

- hosts: webnodes

  vars

     http_port: 80

     max_clients: 256

   remote_user: root

   tasks:

      - name: ensure apache is at lasted 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基础组件

1、Hosts和Users

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

        - hosts: webnodes

           remotes_user: root

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

        - hosts: webnodes

           remote_user: heboan

           tasks:

               - name: test connection

                  ping:

                  remote_user: heboan

                  sudo: yes

2、任务列表和action

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

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

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

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

         tasks:

             - name: make sure apache is running

               service: name=httpd state=running

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

                        tasks:

                            - name: disable selinux

                              command: /sbin/setenforce 0

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

                         tasks:

                            - name: run this command and ignore the result 

                              shell: /usr/bin/somecommand || /bin/true

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

                          tasks:

                              - name: run this command and ignore the result

                                shell: /usr/bin/somecommand

                                ignore_errors: True

3、handlers

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

“notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。
                              - name: template configuration file
                                template: src=template.j2 dest=/etc/foo.conf
                                notify:
                                     - restart memcached
                                     - restart apache

handler是task列表,这些task与前述的task并没有本质上的不同。
                              handlers:
                                    - name: restart memcached
                                      service: name=memcached state=restarted
                                    - name: restart apache
                                      service: name=apache state=restarted

 

 九、案例-基于playbooks事先web部署

 1、提供好Inventory文件

# cat /etc/ansible/hosts  基于秘钥认证
[webserver]
192.168.88.3
192.168.88.2

2、编辑playbooks剧本

#vim /root/web.yaml
- hosts: webserver
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd state=present
    - name: start httpd
      service: name=httpd enabled=yes state=started
    - name: httpd.conf configure file
      copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify:      #修改了配置文件需要重启服务才会生效,所以这里要关联一个重启操作
        - restart httpd
  handlers:
      - name: restart httpd    #这里是上面的 restart httpd要执行的动作
        service: name=httpd state=restarted

3、准备好配置文件

将web的配置放到指定目录 src=/root/httpd.conf   #这里我把监听端口改成了8080

4、开始部署

# ansible-playbook /root/web.yaml

posted @ 2016-05-02 17:42  sellsa  阅读(313)  评论(0)    收藏  举报