天天看點

ansible使用及YAML文法介紹

一、簡介 

1、ansible 簡介

    ansible官方的title是“Ansible is Simple IT Automation”——簡單的自動化IT工具。這個工具的目标有這麼幾項:自動化部署APP;自動化管理配置項;自動化的持續傳遞;自動化的(AWS)雲服務管理。

    所有的這幾個目标本質上來說都是在一個台或者幾台伺服器上,執行一系列的指令而已,而如果你要管理的伺服器是成千上萬台的,那你用一台伺服器去管理控制這大批量的伺服器,勢必會造成這台主要機的相當可觀的資源消耗和性能的低下(即使可以使用 ansible -f 參數并行執行),這時就需要有種 p2p 的概念,讓每一台被同步、配置的伺服器也可以做為一台 ansible 中控機去同步配置其它的伺服器。

    Ansible 無需安裝服務端和用戶端,隻要 SSH 即可。這意 味着,任何一台裝有 Ansible 的機器都可以成為強大的管理端。Ansible 上手十分快,用 Ad-Hoc 可以應付簡單的管理任務,麻煩點的也可以定義 Playbook 文 件來搞定。

2、強大的自動化運維工具

    強大的自動化工具有:ansible,puppet,saltstack

    puppet與saltstack這2個軟體都需要安裝用戶端,而saltstack與ansible很相似,都是屬于python流的,但saltstack不是很穩定,是以ansible的搜尋率是saltstack的3倍也不是沒有原因的。puppet雖然穩定,但指令執行的時候,需要配置子產品兒,非常麻煩,而且還需要安裝用戶端,如果公司和别的公司有合作關系的話,很顯然,安裝用戶端是一個不得不考慮的因素;是以,ansible在性能方面并不弱于這兩個工具,而且使用還并不繁瑣,關鍵ansible是基于paramiko 開發的,paramiko是一個純Python實作的ssh協定庫。ansible不需要在遠端主機上安裝client/agents,因為它是基于ssh來和遠端主機通訊的。

3、ansible的特點

(1) No agents:不需要在被管控主機上安裝任意用戶端;

(2) No server:無伺服器端,使用時直接運作指令即可;

(3) Modules in any languages:基于子產品工作,可使用任意語言開發子產品

(4) YAML,not code:使用yaml語言定制劇本playbook;

(5) SSH by default:基于SSH工作;

(6) Strong multi-tier solution:可實作多級指揮;

二、ansible基本使用

1、安裝ansible

1

<code> </code><code>[root@localhost ~]</code><code># yum install -y ansible</code>

2、主要檔案

2

3

<code>[root@DBSlave ~]</code><code># ls /etc/ansible/</code>

<code>ansible.cfg  </code><code>#主配置檔案,可不修改</code>

<code>hosts        </code><code>#添加需操作的主機組</code>

3、ansible使用格式

4

5

6

7

<code>ansible &lt;host-pattern&gt; [-f forks] [-m module_name] [-a args]</code>

<code>    </code><code>host-pattern </code><code># 可以是all,或者配置檔案中的主機組名</code>

<code>    </code><code>-f forks  </code><code># 指定并行處理的程序數</code>

<code>    </code><code>-m module </code><code># 指定使用的子產品,預設子產品為command</code>

<code>    </code><code>-a args   </code><code># 指定子產品的參數</code>

<code>如果你有多台伺服器的話,想并發運作,可以使用-f參數,預設是并發5</code>

4、檢視各子產品的使用方法

<code>ansible-doc [options] [modules]  :Show Ansible module documentation</code>

<code> </code><code>-l 列出所有的ansible子產品</code>

<code> </code><code>-s 列出該子產品的相關指令</code>

5、首次使用ansible

(1)安裝ansible

<code>[root@localhost ~]</code><code># yum install -y ansible</code>

(2)設定主機組(host-pattern)

8

9

10

<code># vim /etc/ansible/hosts</code>

<code>[web servers]</code>

<code>192.168.200.211</code>

<code>192.168.200.212</code>

<code>192.168.200.213</code>

<code>192.168.200.214</code>

<code>[db servers]</code>

<code>192.168.200.215</code>

<code>192.168.200.216</code>

(3)建立SSH公鑰與私鑰

<code> </code><code>[root@localhost ~]</code><code># ssh-keygen</code>

(4)将公鑰檔案複制到目标伺服器  [注: ssh-copy-id 把公鑰追加到遠端主機的 .ssh/authorized_key 上.]

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code> </code><code>...</code>

(5)連接配接與驗證測試 

<code>[root@localhost ~]</code><code># ansible -i /etc/ansible/hosts all -m ping</code>

(6)子產品兒

    檢視各子產品的使用方法

<code>可以直接使用 ansible-doc 子產品兒名 來檢視子產品兒的使用,如</code>

<code># ansible-doc htpasswd</code>

    幾個示例

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<code>ansible all -a </code><code>"/bin/echo hello"</code>  <code>(不寫-m,預設子產品是shell)</code>

<code>ansible all -m </code><code>command</code> <code>-a </code><code>"/bin/echo hello, world"</code>

<code>ansible all -m shell -a </code><code>"ping baidu.com -c 1"</code>

<code>ansible all -m </code><code>ping</code> <code># ping操作   -i 參數可不指定,預設找 /etc/ansible/hosts</code>

<code>ansible </code><code>"web servers"</code> <code>-a </code><code>'date'</code> <code>(可省略-m </code><code>command</code><code>) </code><code># 執行date指令</code>

<code>ansible </code><code>"db servers"</code> <code>-m copy -a “src=</code><code>/root/ansible</code><code>.rpm dest=</code><code>/tmp/</code><code>” </code><code># 複制檔案</code>

<code>ansible all -m </code><code>cron</code> <code>-a ‘name=</code><code>"custom job"</code> <code>minute=*</code><code>/3</code> <code>hour=* day=* month=* weekday=* job=</code><code>"/usr/sbin/ntpdate 192.168.200.16"</code><code>’ </code><code># 配置crontab任務</code>

<code>ansible all -m user -a </code><code>'name=mysql shell=/sbin/nologin createhome=no'</code>

<code>ansible all -m user -a </code><code>"name=tester remove=yes state=absent"</code>

<code>ansible all -m group -a </code><code>"name=mysql gid=36 system=yes"</code> <code># 建立組</code>

<code>ansible all -m yum -a </code><code>"name=httpd state=present"</code> <code># 通過yum安裝httpd</code>

<code>ansible all -m service -a </code><code>"name=httpd state=started enabled=yes"</code> <code># 配置服務開啟啟動</code>

<code>ansible </code><code>test</code> <code>-m </code><code>file</code> <code>-a </code><code>'dest=/root/test.txt  owner=text group=text mode=644 state=touch'</code>

<code>ansible </code><code>test</code> <code>-m </code><code>file</code> <code>-a </code><code>'src=/root/test.txt  dest=/tmp/test.txt mode=440 owner=test group=test state=link'</code>

<code>建立遞歸檔案夾</code>

<code>    </code><code># ansible 192.168.200.225 -m file -a "dest=/tmp/a/b/c owner=root group=root mode=755 state=directory"</code>

<code>    </code><code>192.168.200.225 | success &gt;&gt; {</code>

<code>    </code><code>"changed"</code><code>: </code><code>true</code><code>, </code>

<code>    </code><code>"gid"</code><code>: 0, </code>

<code>    </code><code>"group"</code><code>: </code><code>"root"</code><code>, </code>

<code>    </code><code>"mode"</code><code>: </code><code>"0755"</code><code>, </code>

<code>    </code><code>"owner"</code><code>: </code><code>"root"</code><code>, </code>

<code>    </code><code>"path"</code><code>: </code><code>"/tmp/a/b/c"</code><code>, </code>

<code>    </code><code>"size"</code><code>: 4096, </code>

<code>    </code><code>"state"</code><code>: </code><code>"directory"</code><code>, </code>

<code>    </code><code>"uid"</code><code>: 0</code>

<code>}</code>

<code>檢視結果:</code>

<code>    </code><code>192.168.200.225 | success | rc=0 &gt;&gt;</code>

<code>/tmp</code>

<code>|-- a</code>

<code>|   `-- b</code>

<code>|       `-- c</code>

<code>`-- hsperfdata_root</code>

<code>    </code><code>`-- 14306</code>

<code>4 directories, 1 </code><code>file</code>

    常用子產品兒

    常用的子產品:copy、command、service、yum、apt、file、raw、shell、script、cron、user、state、template、

<code>ansible -i </code><code>/etc/ansiblehosts</code> <code>all -m </code><code>'service'</code> <code>-a </code><code>'name=httpd state=stoped'</code>

<code>ansible -m yum -a </code><code>'name=gcc state=present'</code>

    yum子產品常用來安裝軟體

    service子產品常用來對服務的開關操作

    shell子產品可以用來執行指令以及腳本

    raw和command、shell類似,但是它可以傳遞管道

三、YAML文法

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

    YAML的文法和其他高階語言類似,并且可以簡單表達清單、散清單、标量等資料結構。其結構(Structure)通過空格來展示,序列(Sequence)裡的項用"-"來代表,Map裡的鍵值對用":"分隔。下面是一個示例。

    YAML檔案擴充名通常為.yaml,如example.yaml。

<code>name: John Smith</code>

<code>age: 41</code>

<code>gender: Male</code>

<code>spouse:</code>

<code>    </code><code>name: Jane Smith</code>

<code>    </code><code>age: 37</code>

<code>    </code><code>gender: Female</code>

<code>children:</code>

<code>    </code><code>-  name: Jimmy Smith</code>

<code>       </code><code>age: 17</code>

<code>       </code><code>gender: Male</code>

<code>    </code><code>-  name: Jenny Smith</code>

<code>       </code><code>age 13</code>

<code>       </code><code>gender: Female</code>

四、ansible playbook(劇本)

    playbook使用:ansible-playbook test.yaml

    playbook是由一個或多個“play”組成的清單。play的主要功能在于将事先歸并為一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂task無非是調用ansible的一個module。将多個play組織在一個playbook中,即可以讓它們聯同起來按事先編排的機制同唱一台大戲

    下面就是一個隻包含了一個play的playbook,在寫playbook的時候,一定要記住在 hosts,yum(子產品兒名)等後帶空格,否則會報錯

<code>#這個是你選擇的主機</code>

<code>- hosts: webservers</code>

<code>#這個是變量</code>

<code>  </code><code>vars:</code>

<code>    </code><code>http_port: 80</code>

<code>    </code><code>max_clients: 200</code>

<code>#遠端的執行權限</code>

<code>  </code><code>remote_user: root</code>

<code>  </code><code>tasks:</code>

<code>#利用yum子產品來操作</code>

<code>  </code><code>- name: ensure apache is at the latest version</code>

<code>    </code><code>yum: pkg=httpd state=latest</code>

<code>  </code><code>- name: write the apache config </code><code>file</code>

<code>    </code><code>template: src=</code><code>/srv/httpd</code><code>.j2 dest=</code><code>/etc/httpd</code><code>.conf</code>

<code>#觸發重新開機伺服器</code>

<code>    </code><code>notify:</code>

<code>    </code><code>- restart apache</code>

<code>  </code><code>- name: ensure apache is running</code>

<code>    </code><code>service: name=httpd state=started</code>

<code>#這裡的restart apache 和上面的觸發是配對的。這就是handlers的作用。相當于tag</code>

<code>  </code><code>handlers:</code>

<code>    </code><code>- name: restart apache</code>

<code>      </code><code>service: name=httpd state=restarted</code>

1、HOSTS和Users

    playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的使用者身份執行任務。

    hosts用于指定要執行指定任務的主機,其可以是一個或多個由冒号分隔主機組;

    remote_user則用于指定遠端主機上的執行任務的使用者。如上面示例中的

<code>-hosts: webnodes</code>

<code> </code><code>remote_user: root</code>

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

<code>- hosts: webnodes</code>

<code>    </code><code>- name: </code><code>test</code> <code>connection</code>

<code>      </code><code>ping</code><code>:</code>

<code>      </code><code>remote_user: root</code>

<code>      </code><code>sudo</code><code>: </code><code>yes</code>

2、任務清單和cation

    play的主體部分是task list。task list中的各任務按次序逐個在hosts中指定的所有主機上執行,即在所有主機上完成第一個任務後再開始第二個。在運作自下而下某playbook時,如果中途發生錯誤,所有已執行任務都将復原,是以,在更正playbook後重新執行一次即可。

    task的目的是使用指定的參數執行子產品,而在子產品參數中可以使用變量。子產品執行是幂等的,這意味着多次執行是安全的,因為其結果均一緻。

    每個task都應該有其name,用于playbook的執行結果輸出,建議其内容盡可能清晰地描述任務執行步驟。如果未提供name,則action的結果将用于輸出。

    定義task的可以使用“action: module options”或“module: options”的格式,推薦使用後者以實作向後相容。如果action一行的内容過多,也中使用在行首使用幾個空白字元進行換行。

<code>tasks:</code>

<code>  </code><code>- name: </code><code>make</code> <code>sure apache is running</code>

<code>    </code><code>service: name=httpd state=running</code>

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

<code>     </code><code>- name: disable selinux</code>

<code>       </code><code>command</code><code>: </code><code>/sbin/setenforce</code> <code>0</code>

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

<code>   </code><code>- name: run this </code><code>command</code> <code>and ignore the result</code>

<code>     </code><code>shell: </code><code>/usr/bin/somecommand</code> <code>|| </code><code>/bin/true</code>

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

<code>  </code><code>- name: run this </code><code>command</code> <code>and ignore the result</code>

<code>    </code><code>shell: </code><code>/usr/bin/somecommand</code>

<code>    </code><code>ignore_errors: True</code>

3、handlers

    用于當關注的資源發生變化時采取一定的操作。

    “notify”這個action可用于在每個play的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,取而代之,僅在所有的變化發生完成後一次性地執行指定操作。在notify中列出的操作稱為handler,也即notify中調用handler中定義的操作。

<code>- name: template configuration </code><code>file</code>

<code>  </code><code>template: src=template.j2 dest=</code><code>/etc/foo</code><code>.conf</code>

<code>  </code><code>notify:</code>

<code>     </code><code>- restart memcached</code>

<code>     </code><code>- restart apache</code>

    handler是task清單,這些task與前述的task并沒有本質上的不同。

<code>handlers:</code>

<code>    </code><code>- name: restart memcached</code>

<code>      </code><code>service:  name=memcached state=restarted</code>

<code>      </code><code>service: name=apache state=restarted</code>

五、playbook案例

1、heartbeat.yaml

<code>heartbeat.yaml</code>

<code>    </code><code>- hosts: hbhosts</code>

<code>    </code><code>remote_user: root</code>

<code>    </code><code>tasks:</code>

<code>        </code><code>- name: ensure heartbeat latest version</code>

<code>          </code><code>yum: name=heartbeat state=present</code>

<code>        </code><code>- name: authkeys configure </code><code>file</code>

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

<code>        </code><code>- name: authkeys mode 600</code>

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

<code>          </code><code>notify:</code>

<code>            </code><code>- restart heartbeat</code>

<code>        </code><code>- name: ha.cf configure </code><code>file</code>

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

<code>    </code><code>handlers:</code>

<code>        </code><code>- name: restart heartbeat</code>

<code>            </code><code>service: name=heartbeat state=restarted</code>

2、corosync.yaml

<code>- hosts: hanodes      </code><code>#指定要執行任務的主機,可由冒号分隔主機組</code>

<code>  </code><code>remote_user: root   </code><code>#指定遠端主機上執行任務的使用者</code>

<code>  </code><code>vars:  </code><code>#定義如下2個變量</code>

<code>    </code><code>crmsh: crmsh-1.2.6.4.el6.x86_64.rpm</code>

<code>    </code><code>pssh: pssh-2.3.1-2.el6.x86_64.rpm</code>

<code>  </code><code>tasks:    </code><code>#指定需執行的任務清單,每個task都有其name和使用的子產品及參數</code>

<code>      </code><code>ping</code><code>:        </code><code>#ping子產品無需執行參數</code>

<code>      </code><code>remote_user: jason  </code><code>#在task中指定遠端主機上執行任務的使用者</code>

<code>      </code><code>sudo</code><code>: </code><code>yes</code>   <code>#使用sudo在遠端主機上執行任務</code>

<code>    </code><code>- name: corosync installing</code>

<code>      </code><code>yum: name=corosync state=present</code>

<code>    </code><code>- name: pacemaker installing          </code><code>#定義一個軟體安裝任務</code>

<code>      </code><code>yum: name=pacemaker state=present   </code><code>#使用yum安裝,并配置需安裝的軟體名(name),及狀态(state)</code>

<code>    </code><code>- name: crmsh rpm packages</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/packages/</code><code>{{ crmsh }} dest=</code><code>/tmp/</code><code>{{ crmsh }}</code>

<code>    </code><code>- name: pssh rpm packages</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/packages/</code><code>{{ pssh }} dest=</code><code>/tmp/</code><code>{{ pssh }}</code>

<code>    </code><code>- name: crmsh installing</code>

<code>      </code><code>command</code><code>: yum -y reinstall </code><code>/tmp/</code><code>{{ crmsh }} </code><code>/tmp/</code><code>{{ pssh }}</code>

<code>    </code><code>- name: authkey configure </code><code>file</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/conf/authkey</code> <code>dest=</code><code>/etc/corosync/authkey</code>

<code>    </code><code>- name: authkey mode 400   </code><code>#定義一個檔案權限設定任務</code>

<code>      </code><code>file</code><code>: path=</code><code>/etc/corosync/authkey</code> <code>mode=400</code>

<code>      </code><code>notify:   </code><code>#定義一個通知,當此任務執行時,可以激發響應的handler</code>

<code>        </code><code>- restart corosync</code>

<code>    </code><code>- name: corosync.conf configure </code><code>file</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/conf/corosync</code><code>.conf dest=</code><code>/etc/corosync/corosync</code><code>.conf</code>

<code>      </code><code>tags:</code>

<code>        </code><code>- conf</code>

<code>      </code><code>notify:</code>

<code>    </code><code>- name: ensure the corosync service startup on boot</code>

<code>      </code><code>service: name=corosync state=started enabled=</code><code>yes</code>

<code>  </code><code>handlers:   </code><code>#定義當關注的資源發生變化時,需采取的操作</code>

<code>    </code><code>- name: restart corosync  </code><code>#定義一個服務重新開機任務</code>

<code>      </code><code>service: name=corosync state=restarted</code>

本文轉自 nmshuishui 51CTO部落格,原文連結:http://blog.51cto.com/nmshuishui/1573941,如需轉載請自行聯系原作者