天天看點

ansible

一、簡介

Ansible is a radically simple

configuration-management, application deployment, task-execution, and

multinode orchestration engine.

Design Principles

Have a dead simple setup process and a minimal learning curve

Be super fast & parallel by default

Require no server or client daemons; use existing SSHd

Use a language that is both machine and human friendly

Focus on security and easy auditability/review/rewriting of content

Manage remote machines instantly, without bootstrapping

Allow module development in any dynamic language, not just Python

Be usable as non-root

Be the easiest IT automation system to use, ever.

二、安裝

2.1 編譯安裝

解決依賴關系

# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto

# tar xf ansible-1.5.4.tar.gz

# cd ansible-1.5.4

# python setup.py build

# python setup.py install

# mkdir /etc/ansible

# cp -r examples/* /etc/ansible

2.2 rpm包安裝

三、部署

3.1 四台主機

192.168.1.220   svn.abc.com     svn

192.168.1.221   rs1.abc.com     rs1

192.168.1.222   rs2.abc.com     rs2

192.168.1.3     master.abc.com  master

3.2  系統版本

CentOS release 6.5

2.6.32-431.el6.x86_64

3.3 以220作為控制台,指揮着rs1,rs2,master

[root@svn ~]# yum list all ansib*

已加載插件:fastestmirror, security

Loading mirror speeds from cached hostfile

epel/metalink                                            | 3.2 kB     00:00     

 * base: centos.ustc.edu.cn

 * epel: mirrors.neusoft.edu.cn

 * extras: mirrors.pubyun.com

 * updates: centos.ustc.edu.cn

base                                                     | 3.7 kB     00:00     

epel                                                     | 4.4 kB     00:00     

getepel/primary_db

          33% [=====          ]  16 kB/s | 2.2 MB     04:35

Eepel/primary_db                                                        

                                   | 6.6 MB     03:24     

extras

                            | 3.4 kB     00:00     

updates      

                     | 3.4 kB     00:00     

updates/primary_db  

              | 3.8 MB     00:03     

可安裝的軟體包

ansible.noarch

                      1.9.1-1.el6                                      

                                       epel

ansible-inventory-grapher.noarch

    1.0.1-2.el6                                                        

                     epel

ansible-lint.noarch                    

 2.0.1-1.el6                                                            

                 epel

[root@svn ~]# yum install ansible

3.4 改一下本地主機庫

[root@svn ~]# cd /etc/ansible/

[root@svn ansible]# ls

ansible.cfg  hosts  roles

[root@svn ansible]# vim hosts

:.,$s/^\([^[:space:]#]\)/#\1/g注釋掉例子再配

[webservers]

rs1.abc.com

rs2.abc.com

[dbservers]

master.abc.com

3.5 任何svn聯系被控制主機,基于ssh連接配接

[root@svn ansible]# ssh-keygen -t rsa -P ''

Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa): 

Your identification has been saved in /root/.ssh/id_rsa.

Your public key has been saved in /root/.ssh/id_rsa.pub.

The key fingerprint is:

71:dd:e4:81:47:bc:39:f3:b2:2b:9e:72:87:bc:60:b8 [email protected]

The key's randomart p_w_picpath is:

+--[ RSA 2048]----+

|             ++  |

|           ..+o. |

|        . . ..oo |

|         o    =  |

|        S      + |

|         .    . .|

|        . o. . o |

|         o..=.o  |

|        E  +++.. |

+-----------------+

[root@svn ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

[root@svn ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

[root@svn ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

3.6 ansible基本文法

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

預設子產品 -m command

執行一個事例測試一下

[root@svn ansible]# ansible all -m ping

rs2.abc.com | success >> {

    "changed": false, 

    "ping": "pong"

}

rs1.abc.com | success >> {

master.abc.com | success >> {

時間是否一緻

[root@svn ~]# ansible all -a 'date'

rs2.abc.com | success | rc=0 >>

Thu Jun 18 20:53:03 CST 2015

rs1.abc.com | success | rc=0 >>

Tue Jun 23 21:48:44 CST 2015

master.abc.com | success | rc=0 >>

Mon Jun  1 19:11:27 CST 2015

更改一下時間

[root@svn ~]# ansible all -m command -a 'ntpdate time.nist.gov'

24 Jun 11:43:43 ntpdate[33091]: adjust time server 128.138.141.172 offset 0.003317 sec

24 Jun 11:43:57 ntpdate[4133]: step time server 64.113.32.5 offset 46706.282835 sec

24 Jun 11:43:58 ntpdate[12483]: step time server 64.113.32.5 offset 482046.302774 sec

Wed Jun 24 11:44:05 CST 2015

3.7 列出ansible支援子產品

[root@svn ~]# ansible-doc -l

   把一個檔案複制到3台主機上

[root@svn ~]# ansible webservers -m copy -a "src=/root/epel-release-6-8.noarch.rpm dest=/tmp/"

    "checksum": "2b2767a5ae0de30b9c7b840f2e34f5dd9deaf19a", 

    "dest": "/tmp/epel-release-6-8.noarch.rpm", 

    "gid": 0, 

    "group": "root", 

    "mode": "0644", 

    "owner": "root", 

    "path": "/tmp/epel-release-6-8.noarch.rpm", 

    "size": 14540, 

    "state": "file", 

    "uid": 0

rs1.abc.com | FAILED >> {

    "failed": true, 

    "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"

}                        //提示出錯,去rs1那台主機安裝yum install libselinux-python吧

再來試一次

    "changed": true, 

    "md5sum": "2cd0ae668a585a14e07c2ea4f264d79b", 

    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 

    "src": "/root/.ansible/tmp/ansible-tmp-1435139261.54-223429784911851/source", 

    驗證

[root@svn ~]# ansible webservers -a 'ls /tmp'

epel-release-6-8.noarch.rpm

mysql

lost+found

3.8 在每一個主機定義crontab任務

[root@svn ~]# ansible-doc -s cron

less 436

Copyright (C) 1984-2009 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.

For information about the terms of redistribution,

see the file named README in the less distribution.

Homepage: http://www.greenwoodsoftware.com/less

- name: M a n a g e   c r o n . d   a n d   c r o n t a b   e n t r i e s .

  action: cron

      backup                 # If set, create a backup of the crontab before it 

      cron_file              # If specified, uses this file in cron.d instead of

      day                    # Day of the month the job should run ( 1-31, *, */

      hour                   # Hour when the job should run ( 0-23, *, */2, etc 

      job                    # The command to execute. Required if state=present

      minute                 # Minute when the job should run ( 0-59, *, */2, et

      month                  # Month of the year the job should run ( 1-12, *, *

      name=                  # Description of a crontab entry.

      reboot                 # If the job should be run at reboot. This option i

      special_time           # Special time specification nickname.

      state                  # Whether to ensure the job is present or absent.

      user                   # The specific user whose crontab should be modifie

      weekday        

[root@svn

~]# ansible all -m cron -a 'name="custom job" minute=*/1 hour=* day=*

month=* weekday=* job="/usr/sbin/ntpdate time.nist.gov"'

    "jobs": [

        "custom job"

    ]

[root@svn ~]# ansible all -a "crontab -l"

#Ansible: custom job

*/1 * * * * /usr/sbin/ntpdate time.nist.gov

3.9 定義一個組

[root@svn ~]# ansible-doc -s group

- name: A d d   o r   r e m o v e   g r o u p s

  action: group

      gid                    # Optional `GID' to set for the group.

      name=                  # Name of the group to manage.

      state                  # Whether the group should be present or not on the remote host.

      system                 # If `yes', indicates that the group created is a system group.

[root@svn ~]# ansible all -m group -a "gid=306 system=yes name=mysql"

    "gid": 306, 

    "name": "mysql", 

    "state": "present", 

    "system": true

驗證

[root@svn ~]# ansible all -a "tail -l /etc/group"

tcpdump:x:72:

oprofile:x:16:

slocate:x:21:

mysql:x:306:

zabbix:x:498:

ldap:x:55:

apache:x:48:

zabbixsrv:x:497:

li:x:501:

ganglia:x:495:

stapusr:x:156:

stapsys:x:157:

stapdev:x:158:

sshd:x:74:

nscd:x:28:

postfix:x:89:

cgred:x:499:

3.10 安裝corosync

[root@svn ~]# ansible-doc -s yum

- name: M a n a g e s   p a c k a g e s   w i t h   t h e   I ( y u m )   p a c k a g e   m a n a g e r

  action: yum

      conf_file              # The remote yum configuration file to use for the transaction.

    disable_gpg_check      # Whether to disable the GPG checking of

signatures of packages being installed. Has an effect only if state is

`present' or `latest'.

      disablerepo            # `Repoid' of

repositories to disable for the install/update operation. These repos

will not persist beyond the transaction. When specifying multiple repos,

separate them wi

      enablerepo             # `Repoid' of

repositories to enable for the install/update operation. These repos

separate them wit

      list                   # Various

(non-idempotent) commands for usage with `/usr/bin/ansible' and `not'

playbooks. See examples.

      name=                  # Package

name, or package specifier with version, like `name-1.0'. When using

state=latest, this can be '*' which means run: yum -y update. You can

also pass a url or a loc

      state                  # Whether to install (`present', `latest'), or remove (`absent') a package.

      update_cache           # Force updating the cache. Has an effect only if state is `present' or `latest'.

[root@svn ~]# ansible all -m yum -a "state=present name=corosync"

[root@svn ~]# ansible all -a "rpm -q corosync"

corosync-1.4.7-1.el6.x86_64

3.11 啟動服務

[root@svn ~]# ansible all -a "service httpd status"

rs2.abc.com | FAILED | rc=3 >>

httpd 已停

rs1.abc.com | FAILED | rc=3 >>

master.abc.com | FAILED | rc=3 >>

[root@svn ~]# ansible all -m service -a "state=started name=httpd enabled=yes"

    "enabled": true, 

    "name": "httpd", 

    "state": "started"

四、YAML

4.1 YAML介紹

YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark

Evans在2001年在首次發表了這種語言,另外Ingy dt Net與Oren Ben-Kiki也是這語言的共同設計者。

YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思其實是:"Yet Another Markup Language"(仍是一種标記語言)。其特性:

YAML的可讀性好

YAML和腳本語言的互動性好

YAML使用實作語言的資料類型

YAML有一個一緻的資訊模型

YAML易于實作

YAML可以基于流來處理

YAML表達能力強,擴充性好

更多的内容及規範參見http://www.yaml.org。

4.2 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。

五、ansible 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 the 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

5.1 playbook基礎元件

5.1.1 Hosts和Users

playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的使用者身份執行任務。hosts用于指定要執行指定任務的主機,其可以是一個或多個由冒号分隔主機組;remote_user則用于指定遠端主機上的執行任務的使用者。如上面示例中的

-hosts: webnodes

remote_user: root

不過,remote_user也可用于各task中。也可以通過指定其通過sudo的方式在遠端主機上執行任務,其可用于play全局或某任務;此外,甚至可以在sudo時使用sudo_user指定sudo時切換的使用者。

 remote_user: mageedu

   - name: test connection

     ping:

     remote_user: mageedu

     sudo: yes

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一行的内容過多,也中使用在行首使用幾個空白字元進行換行。

tasks:

 - name: make sure apache is running

   service: name=httpd state=running

在衆多子產品中,隻有command和shell子產品僅需要給定一個清單而無需使用“key=value”格式,例如:

 - name: disable selinux

   command: /sbin/setenforce 0

如果指令或腳本的退出碼不為零,可以使用如下方式替代:

 - name: run this command and ignore the result

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

或者使用ignore_errors來忽略錯誤資訊:

   shell: /usr/bin/somecommand

   ignore_errors: True

5.1.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

     service: name=apache state=restarted

案例:

heartbeat.yaml

- hosts: hbhosts

   - name: ensure heartbeat latest version

     yum: name=heartbeat state=present

   - name: authkeys configure file

     copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys

   - name: authkeys mode 600

     file: path=/etc/ha.d/authkeys mode=600

     notify:

       - restart heartbeat

   - name: ha.cf configure file

     copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf

     notify: 

      - restart heartbeat

 - name: restart heartbeat

   service: name=heartbeat state=restarted

六、測試

6.1 建一個以.yaml結尾檔案

[root@svn ~]# vim test.yaml

//注意文法 “- 空格 parameter"

- hosts: all

  remote_user: root

  tasks:

    - name: add a group

      group: gid=1000 name=testgroup system=no

    - name: excute a commad

      command: /bin/date

[root@svn ~]# ansible-playbook test.yaml 

//把一個任務所有主機執行一遍,在執行第二個任務

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 

ok: [master.abc.com]

ok: [rs2.abc.com]

ok: [rs1.abc.com]

TASK: [add a group] *********************************************************** 

changed: [rs1.abc.com]

changed: [rs2.abc.com]

changed: [master.abc.com]

TASK: [excute a commad] ******************************************************* 

changed: [master.abc.com]  //出現changed 表明添加成功,注意的是執行結果不會返饋回來

PLAY RECAP ******************************************************************** 

master.abc.com             : ok=3    changed=2    unreachable=0    failed=0   

rs1.abc.com                : ok=3    changed=2    unreachable=0    failed=0   

rs2.abc.com                : ok=3    changed=2    unreachable=0    failed=0   

6.2更改httpd.conf配置檔案

[root@svn ~]# vim web.yaml

   - name: ensure apche latest version

     yum: state=latest name=httpd

   - name: apache configure file

     copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf force=yes

     notify:

        - restart httpd

  handlers:

   - name: restart httpd

     service: name=httpd state=restarted

[root@svn ~]# ansible-playbook web.yaml 

TASK: [ensure apche latest version] ******************************************* 

TASK: [apache configure file] ************************************************* 

NOTIFIED: [restart httpd] ***************************************************** 

master.abc.com             : ok=4    changed=2    unreachable=0    failed=0   

rs1.abc.com                : ok=3    changed=0    unreachable=0    failed=0   

rs2.abc.com                : ok=3    changed=0    unreachable=0    failed=0   

[root@svn ~]# ansible all -a "ss -tnl"

State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port 

LISTEN     0      128                      :::111                     :::*     

LISTEN     0      128                       *:111                      *:*     

LISTEN     0      128                      :::8080                    :::*     

LISTEN     0      128                       *:1011                     *:*     

LISTEN     0      128                      :::22                      :::*     

LISTEN     0      128                       *:22                       *:*     

LISTEN     0      128               127.0.0.1:631                      *:*     

LISTEN     0      128                     ::1:631                     :::*     

LISTEN     0      100                     ::1:25                      :::*     

LISTEN     0      100               127.0.0.1:25                       *:*     

LISTEN     0      128                      :::36551                   :::*     

LISTEN     0      128                       *:49863                    *:*     

LISTEN     0      128                       *:58527                    *:*     

LISTEN     0      128                      :::54598                   :::*     

繼續閱讀