說明:這篇文章依賴上一篇的環境
http://ximenfeibing.blog.51cto.com/8809812/1669162
Yml介紹
Playbook是使用yaml語言定製的,YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark Evans在2001年在首次發表了這種語言,另外Ingy dt Net與Oren Ben-Kiki也是這語言的共同設計者。
Yml語法:
- host: websrvs #定義執行的主機 remote_user: root #定義執行的用戶 tasks: #定義任務 - task1 #定義第一個任務名稱 module_name: module_args #定義使用的模塊,和模塊參數 - task 2 #定義第二個任務名稱
簡單示例1:
定義一個yml:對webserver組中的主機,調用group和user模塊創建組和用戶;對dbserver組中的主機調用copy模塊複製文件。
執行yml
執行第二遍,返回的所有結果爲ok不是表示執行ok而是所有條件都滿足
簡單示例2:
搭建一個apache環境
準備需要複製到被管理主機的httpd.conf配置文件,修改監聽端口爲8080
[root@node1 ~]# mkdir conf [root@node1 ~]# cp /etc/httpd/conf /httpd.conf conf/ [root@node1 ~]# vim conf/httpd.conf Listen 8080
應用之前先停止webserver組中的httpd服務,並卸載
[root@node1 ~]# ansible webserver -a 'service httpd stop' [root@node1 ~]# ansible websrvs -m yum -a 'name=httpd state=absent'
執行:
驗證:httpd軟件包已經安裝,服務開機自動啓動,而且也監聽8080端口
[root@node2 ~]# rpm -qa httpd httpd-2.2.15-39.el6.centos.x86_64 [root@node2 ~]# chkconfig --list httpd httpd 0:off1:off2:on3:on4:on5:on6:off [root@node2 ~]# netstat -lntp | grep 8080 tcp 0 0 :::8080 :::* LISTEN 40826/httpd
YAML中的變量
1、自定義變量
2、facts
收集被管理主機的信息時,會返回很多變量,這裏就是調用了返回的ipv4地址變量
示例:將客戶端返回的ip地址,創建webserver組中主機的/tmp/test.ans文件。
執行結果如下:
驗證:使用的變量名一樣,但是生成的內容卻是被管理主機的ip地址
[root@node2 ~]# cat /tmp/test.ans [u'172.16.4.101'] [root@node3 ~]# cat /tmp/test.ans [u'172.16.4.102']
3、主機變量
示例:對webserver組中的主機,定義testvar變量,值爲ip地址後兩位
[root@node1 ~]# vim /etc/ansible/hosts [webserver] 172.16.4.101 testvar="4.101" 172.16.4.102 testvar="4.102" [dbserver] 172.16.4.103
設置yml文件,和使用其他變量一樣的方法調用變量:
執行yml
驗證:相同變量,不同主機得到了不同的值
[root@node2 ~]# cat /tmp/test.ans [u'172.16.4.101'],4.101 [root@node3 ~]# cat /tmp/test.ans [u'172.16.4.102'],4.102
4、配置文件中引用變量(模版)
示例:使用變量指定httpd.conf配置文件中一些參數的值
定義配置文件中使用的變量
[root@node1 ~]# vim temolastes/httpd.conf.j2 <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients {{ maxClients }} MaxRequestsPerChild 4000 </IfModule> Listen {{ http_port }} ServerName {{ ansible_fqdn }}
修改Ansible的hosts文件定義主機變量
[root@node1 ~]# vim /etc/ansible/hosts [webserver] 172.16.4.101 http_port=80 maxClients=100 172.16.4.102 http_port=8080 maxClients=200 [dbserver] 172.16.4.103
定義yml:定義的過程中使用變量,根據不同主機定義的值不同,生成的配置文件參數也不同
執行過程
驗證:相同的playbook由於對hosts指定的變量不同,所以生成不同的配置文件
node2: <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 100 MaxRequestsPerChild 4000 </IfModule> Listen 80 ServerName node2 node3: <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 200 MaxRequestsPerChild 4000 </IfModule> Listen 8080 ServerName node3
條件測試
When語句
示例:添加用戶,但是隻對主機名爲node2的主機添加。
執行結果如下:
迭代
當有需要重複性執行的任務時,可以使用迭代機制。其使用格式爲將需要迭代的內容定義爲item變量引用,並通過with_items語句來指明迭代的元素列表即可。例如:
上面語句的功能等同於下面的語句:
- name: create user user: name=testuser1 - name: create user user: name=testuser2
事實上,with_items中可以使用元素還可爲hashes,例如:
ansible的循環機制還有更多的高級功能,具體請參見官方文檔(http://docs.ansible.com/playbooks_loops.html)。
Playbook
playbook是由一個或多個“play”組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,即可以讓它們聯同起來按事先編排的機制同唱一臺大戲。
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
任務列表和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
Inventory
ansible的主要功用在於批量主機操作,爲了便捷地使用其中的部分主機,可以在inventory file中將其分組命名。默認的inventory file爲/etc/ansible/hosts。
inventory文件格式:
inventory文件遵循INI文件風格,中括號中的字符爲組名。可以將同一個主機同時歸併到多個不同的組中;此外,當如若目標主機使用了非默認的SSH端口,還可以在主機名稱之後使用冒號加端口號來標明。
ntp.xmfb.com [webservers] www1.xmfb.com:2222 www2.xmfb.com [dbservers] db1.xmfb.com db2.xmfb.com db3.xmfb.com
如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機,例如:
[webservers] www[01:50].example.com [databases] db-[a:f].example.com
組嵌套
inventory中,組還可以包含其它的組,並且也可以向組中的主機指定變量。不過,這些變量只能在ansible-playbook中使用,而ansible不支持。例如:
[apache] httpd1.xmfb.com httpd2.xmfb.com [nginx] ngx1.xmfb.com ngx2.xmfb.com [webservers:children] apache nginx [webservers:vars] ntp_server=ntp.xmfb.com
Handlers
示例:定義配置文件發生修改之後,在執行yml文件,會重啓httpd服務。
定義的內容:
修改配置文件的監聽端口爲80
[root@node1 ~]# vim conf/httpd.conf Listen 80
執行結果
驗證:webserver組中的主機httpd端口更改與否
[root@node2 ~]# netstat -lntp | grep httpd tcp 0 0 :::80 :::* LISTEN 41848/httpd
tags
tags用於讓用戶選擇運行或路過playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷。
示例:將修改配置文件部分定義爲tags,一旦配置文件發生改變,可以跳過安裝和啓動服務,只執行復制配置文件和handlers
驗證:使用tags執行conf,只是出現了conf這個任務的執行
Roles
ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。
創建role的步驟
(1)創建以roles命名的目錄;
(2)在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等;
(3)在每個角色命名的目錄中分別創建files、handlers、meta、tasks、templates和vars目錄;用不到的目錄可以創建爲空目錄,也可以不創建;
(4)在playbook文件中,調用各角色;
role內各目錄中可用的文件
tasks目錄:至少應該包含一個名爲main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其它的位於此目錄中的task文件;
files目錄:存放由copy或script等模塊調用的文件;
templates目錄:template模塊會自動在此目錄中尋找Jinja2模板文件;
handlers目錄:此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;在handler中使用include包含的其它的handler文件也應該位於此目錄中;
vars目錄:應當包含一個main.yml文件,用於定義此角色用到的變量;
meta目錄:應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關係;ansible 1.3及其以後的版本才支持;
default目錄:爲當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;
示例:定義一個簡單的roles
創建相關目錄
[root@node1 ~]# mkdir -pvansible_playbooks/roles/{webserver,dbserver}/{tasks,files,templates,meta,handlers,vars} [root@node1 ~]# tree ansible_playbooks/ ansible_playbooks/ └── roles ├── dbserver │ ├── files │ ├── handlers │ ├── meta │ ├── tasks │ ├── templates │ └── vars └── webserver ├── files ├── handlers ├── meta ├── tasks ├── templates └── vars 15 directories, 0 files
Webserver創建配置文件
[root@node1 ~]# cp /etc/httpd/conf/httpd.confansible_playbooks/roles/webserver/files/
在tasks目錄下,定義yml,此處只需要定義執行的任務
在handlers目錄下,定義handlers
在目錄名同級目錄,定義roles,只需要指明運行的主機和用戶身份已經調用的角色即可
執行結果
定義多個roles,實現重用效果
示例:在4.101配置web服務,在4.102配置數據庫,在4.103及配置web又配置數據庫;
複製mysql配置文件
[root@node1 ~]# cp /etc/my.cnfansible_playbooks/roles/dbserver/files/
定義tasks
定義handlers
定義site.yml,在4.101配置web服務,在4.102配置數據庫,在4.103及配置web又配置數據庫。
執行結果: