一、簡介
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 image 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 will not persist beyond the transaction. When specifying multiple 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
- restart httpd
handlers:
- name: restart httpd
[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 :::*
LISTEN 0 128 *:56483 *:*
LISTEN 0 128 :::52136 :::*
本文轉自 遠永201314 51CTO部落格,原文連結:http://blog.51cto.com/7336056/1859195