在配置集羣時,每個節點上有很多相同的配置,如啓動服務相同、安裝程序、提供相同的配置文件,甚至定製相同的任務計劃來定期執行某些操作等。如果你管理的只是三兩個節點配置起來還是相當簡單的,但是有三五十臺,甚至上百臺你還要自已一個一個手動來配置,那就太痛苦了。因些我們就需要能實現批量管理的一套組件,ansible就是實現這樣管理的工具。
ansible以它強大功能和簡單上手的應用,在2012年獲OSS(Open Source Software,開源軟件 開放源代碼軟件)一項大獎,評爲前十名,評爲最有用的,最著名的,最受歡迎的開源項目,它柔和了很多強大的功能。在配置上柔和了cfengine(配置引擎)(是一種 UNIX 管理工具,其目的是使簡單的管理的任務自動化,使困難的任務變得較容易。Cfengine 適用於管理各種環境,從一臺主機到上萬臺主機的機羣均可使用)chef、puppet等。。在批量任務執行上實現了Func的功能。能實現多層次,多級別的統一指揮。這從它下面的特性就能看的出來。
ansible的特性:
Minimal learning curve,auditability
NO bootstrapping #不需要複雜的算法
NO DAG ordering,Fails Fast
NO agents(other than sshd)-0 resource consumption when not in use#不需要代理,不需要在被管控的主機上安裝任意客戶端
NO server#沒有服務器端,有需要啓動任何服務
NO additional PKI #不基於PKI工作
Modules in any language #支持很多語言
YAML,not code #支持YAML語言實現據本定製
SSH by default #默認基於ssh進行工作
Strong multi-tier solution #可以實現多級指揮
前提準備四臺虛擬機,有一臺主機要扮演指揮員的角色,它們的地址分別爲:
主控制端:
control.edu.com 172.16.24.100
要控制的三臺主機:
node1.edu.com 172.16.24.6
node2.edu.com 172.16.24.7
node3.edu.com 172.16.24.8
所需要的安裝包搜狐epel源中有提供,將yum源指向搜狐epel源。
http://mirrors.sohu.com/fedora-epel/6/x86_64/
ansible-1.5-1.el6.noarch.rpm
epel-release-6-8.noarch.rpm
一、ansible 安裝
[root@control ~]# yum install ansible -y
#編譯安裝方式:
# 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
二、實現主機之間的互信
因爲ansible連接主機要基於ssh,如果每次都要輸密碼是不是很痛苦呀,所以實現主機之間的互信就很有必要。
ssh-keygen -t rsa -P ''
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
ssh-copy-id -i .ssh/id_rsa.pub [email protected]
三、建立hosts文件
ansible的hosts默認在/etc/ansible/目錄中,採用rpm安裝的ansible會將該hosts作爲範例,其中提示ansible是主機名和ip兩種客戶端命名格式的
[root@control ~]# vim /etc/ansible/hosts
在未行模式下輸入.,$s/^\([^[:space:]#]\)/#/g把沒有用的都註釋掉,然後添加如下:
[webservers]
node1.edu.com
nose2.edu.com
[dbservers]
node2.edu.com
node3.edu.com
注:如果沒有主機名的話這裏可以使用ip地址,這裏方括號裏是自己定義的,只要自己容易看懂,容易記住,定義什麼名無所謂。
四、測試一下主機之間是否能夠通信:
[root@control ~]# ansible all -a 'date'
node1.edu.com | success | rc=0 >>
Wed Apr 23 14:41:02 CST 2014
node3.edu.com | success | rc=0 >>
Wed Apr 23 14:41:02 CST 2014
node2.edu.com | success | rc=0 >>
Wed Apr 23 14:41:02 CST 2014
五、ansible命令詳析:
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
<host-pattern>:指定對哪些主機做操作。
[-f forks]:指定管理級別,就是一批要管理多少個主機。默認爲一批5個。
[-m module_name]:指定模塊名稱。
[-a args]:指定前定所使的模塊的參數。
六、ansible模塊詳析:
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
<host-pattern> #指定對哪些主機做操作
[-f forks] #指定並行級別,就是一批要管理多少臺主機
[-m module_name]#指定模塊名稱
[-a args] #指定模塊參數
1).command模塊,這是ansible最常用的模塊,默認可省。
例:查看一下所管理的主機web服務運行狀態
[root@control ~]# ansible all -m command -a 'service httpd status'
node3.edu.com | FAILED | rc=3 >>
httpd is stopped
node2.edu.com | FAILED | rc=3 >>
httpd is stopped
node1.edu.com | FAILED | rc=3 >>
httpd is stopped
返回的結果是關閉狀態,所以要想執行任何shall命令,直接 -m command
2)copy模塊的使用
[root@control ~]# ansible-doc -s copy
- name: Copies files to remote locations.
action: copy
src= #源文件 # Local path to a file to copy to the remote server; can be
directory_mode= # When doing a recursive copy set the mode for the director
force= #覆蓋原來的文件
dest= #複製到哪個位置
content= # When used instead of 'src', sets the contents of a file d
others= # all arguments accepted by the [file] module also work her
validate= # The validation command to run before copying into place.
backup= # Create a backup file including the timestamp information
例:把根目錄下的anaconda-ks.cfg文件複製到定義爲dbservers的兩臺主機上:
[root@control ~]# ansible dbservers -m copy -a "src=/root/anaconda-ks.cfg dest=/tmp/"
node3.edu.com | success >> {
node2.edu.com | success >> {
查看一下有沒有複製過去
[root@control ~]# ansible dbservers -a "ls /tmp/"
3)cron模塊的使用
[root@control ~]# ansible-doc -s cron
- name: Manage cron.d and crontab entries.
action: cron
name= # Description of a crontab entry.
hour= # Hour when the job should run ( 0-23, *, */2, etc )
job= # The command to execute. Required if state=present.
cron_file= # If specified, uses this file in cron.d instead of an indi
reboot= # If the job should be run at reboot. This option is deprec
month= # Month of the year the job should run ( 1-12, *, */2, etc
state= # Whether to ensure the job is present or absent.
special_time= # Special time specification nickname.
user= # The specific user who's crontab should be modified.
backup= # If set, create a backup of the crontab before it is modif
day= # Day of the month the job should run ( 1-31, *, */2, etc )
minute= # Minute when the job should run ( 0-59, *, */2, etc )
weekday= # Day of the week that the job should run ( 0-7 for Sunday
例:讓所有的主機每隔五分鐘到時間服務器上同步一下時間
[root@control ~]# ansible all -m cron -a 'name="corn job" minute=*/5 hour=* month=* weekday=* job="/usr/sbin/ntpdate 172.16.0.1"'
查看下一定製的結果
[root@control ~]# ansible all -a "crontab -l"
4)group模塊
[root@control ~]# ansible-doc -s group
- name: Add or remove groups
action: group
state= # Whether the group should be present or not on the remote host.
gid= # Optional `GID' to set for the group.
name= # Name of the group to manage.
system= # If `yes', indicates that the group created is a system group.
例:三臺主機上都添加一個mysql組:
[root@control ~]# ansible all -m group -a "gid=306 system=yes name=mysql"
5)yum模塊的使用
[root@control ~]# ansible-doc -s yum
action: yum
state= 指定是安裝(`present', `latest'), 還是卸載 remove (`absent')
disablerepo= 如果有多個yum源可能禁用一個
name= 要安裝的包名(如果只寫包名,就安裝最新的包,如果想指定安裝什麼片本的就包名+版本號)
enablerepo= 要啓用的repo
list= 列表(跟playbook相關)
disable_gpg_check= 是否開啓gpg_check
conf_file= 可以用其它服務器上的配置文件,而不使用本地的配置文件
例:所有的主機都安裝上corosync.
[root@control ~]# ansible all -m yum -a "state=present name=corosync"
查看一下是否安裝上了
[root@control ~]# ansible all -a "rpm -q corosync"
6)service模塊
root@control ~]# ansible-doc -s service
- name: Manage services.
action: service
state= 現在是什麼狀態
name= 啓動的服務名稱
runlevel= 指定在什麼級別下啓動
pattern= 指定模式
enabled= 開機是否啓動
例:設置web服務開機自動啓動
[root@control ~]# ansible all -m service -a "state=started name=httpd enabled=yes"
查看一下是否啓動了
[root@control ~]# ansible all -a "service httpd status"
七、ansible劇本playbook的定義:
playbook是由一個或多個“play”組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,
1)playbook基礎組件
Hosts和Users
playbook中的每一個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts用於指定要執行指定任務的主機,其可以是一個或多個由冒號分隔主機組;remote_user則用於指定遠程主機上的執行任務的用戶。如上面示例中的
-hosts: webnodes
remote_user: root
不過,remote_user也可用於各task中。也可以通過指定其通過sudo的方式在遠程主機上執行任務,其可用於play全局或某任務;此外,甚至可以在sudo時使用sudo_user指定sudo時切換的用戶。
- hosts: webnodes
remote_user: mageedu
tasks:
- name: test connection
ping:
remote_user: mageedu
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
定義一個劇本內容如下:
1)確保三個主機上都安裝了httpd
2)把配置文件複製給三臺主機
3)配置文件一旦複製完成要重新啓動httpd
-hosts:all
remote_user:root
tasks:
-name:ensure apache 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