Ansible@一個高效的組態管理工具--Ansible configure management--翻譯(七),ansible--ansible
如無書面授權,請勿轉載
Larger ProjectsUntil now, we have been looking at single plays in one playbook file. This approachwill work for simple infrastructures, or when using Ansible as a simple deploymentmechanism. However, if you have a large and complicated infrastructure, then youwill need to take actions to prevent things from going out of control. This chapterwill include the following topics:• Separating your playbooks into different files, and including them from someother location• Using roles to include multiple files that perform a similar function• Methods for increasing the speed at which Ansible configures your machines
第四章 大型項目中Ansible的使用
至此,我們已經介紹了如何用一個playbook檔案運行一個plays。在小型架構或則使用Ansible做一個簡單的部署機制時這已經很有用了。但是,如果你有一個很大很複雜的系統架構,你可能需要一些額外的操作來保證事情不會超出我們的控制。本章包含以下主題:
- 將你的playbooks分離成多個檔案,儲存在不同的地方
- 使用角色包含多個檔案來完成同樣的功能
- 加速使用Ansible配置機器的方法
IncludesOne of the first issues you will face with a complex infrastructure is that yourplaybooks will rapidly increase in size. Large playbooks can become difficult to readand maintain. Ansible allows you to combat this problem by the way of includes.Includes allow you to split your plays into multiple sections. You can then includeeach section from other plays. This allows you to have several different parts builtfor a different purpose, all included in a main play.There are four types of includes, namely variable includes, playbook includes,task includes, and handler includes. Including variables from an external vars_filefiles has been discussed already in Chapter 2, Simple Playbooks. The following is asummary of what each includes does:• Variable includes: They allow you to put your variables in externalYAML files• Playbook includes: They are used to include plays from other files in a single playLarger Projects• Task includes: They let you put common tasks in other files and includethem wherever required• Handler includes: They let you put all your handlers in the one place
包含
在大型複雜架構中,你第一個要面對的問題就是不斷增長的playbooks檔案大小,一個很大的playbooks很難去理解和維護,解決辦法是使用包含includes。將你的plays分解成多個不同的段,然後在其他的plays中包含他們。不同的段根據不同目的地分類,全部包含在主play中。
有四種類型的包含,分別是變數包含、playbook包含、任務包含、處理常式handler包含。從外部變數檔案包含變數,在第二章已經討論過。下面是每個包含類型的介紹:
- 變數包含:允許你將變數存在外部YAML檔案
- playbook包含:一個大型項目中可以包含多個plays
- 任務包含:將任務放到普通檔案中,當需要的時候包含他們
- 處理常式Handler包含:允許你將所有的handlers處理常式放到一個地方
Task includesTask includes can be used when you have a lot of common tasks that will berepeated. For example, you may have a set of tasks that removes a machine, frommonitoring, and a load balancer before you can configure it. You can put these tasksin a separate YAML file, and then include them from your main task.Task includes inherit the facts from the play they are included from. You can alsoprovide your own variables, which are passed into the task and available for use.Finally, task includes can have conditionals applied to them. If you do this,conditionals will separately be added to each included task. The tasks are all stillincluded. In most cases, this is not an important distinction, but in circumstanceswhere variables may change, it is.The file to include as a task includes contains a list of tasks. If you assume theexistence of any variables and hosts or groups, then you should state them incomments at the top. This makes reusing the file much easier.So, if you wanted to create a bunch of users and set up their environment with theirpublic keys, you would split out the tasks that do a single user to one file. This filewould look similar to the following code:---# Requires a user variable to specify user to setup- name: Create user account#2user: name={{ user }} state=present#3#1- name: Make user SSH config dir#4file: path=/home/{{ user }}/.ssh owner={{ user }} group={{ user}} mode=0600 state=directory#5- name: Copy in public key#6copy: src=keys/{{ user }}.pub dest=/home/{{ user}}/.ssh/authorized_keys mode=0600 owner={{ user }} group={{ user}}#7We expect that a variable named user will be passed to us, and that their publickey will be in the keys directory. The account is created, the ssh config directoryis made, and finally we can copy this in their public key. The easiest way to use thisconfig file would be to include it with the with_items keyword we learned about inChapter 3, Advanced Playbooks. This would look similar to the following code:---- hosts: ansibletestuser: roottasks:- include: usersetup.yml user={{ item }}with_items:- mal- dan- kate
任務包含
當你有很多類似的任務需要重複執行的時候,你可以使用任務包含。比如,在你配置一台裝置之前,需要從負載平衡或者監控系統中刪除這台裝置,你可以把這種任務分別放進不同的YAML檔案中,然後在你的主任務檔案中包含他們。
被包含的任務facts會繼承包含他的play的facts,你也可以自己提供變數,他們在play中都是可用的。
此外,任務包含可以是有條件的,如果你設定了條件,那麼條件將會被添加到每一個包含它的任務中,任務會一直被包含。多數情況下,這樣沒什麼重要的區別,但如果存在變數的話,就不一樣了。一個任務檔案可以包含很多任務,如果你要設定變數,最好在檔案的頂部來注釋他們,這樣可以使得它更加易於被理解和利用。
比如你要建立很多使用者,並用他們的公開金鑰來設定環境變數。你可以先做好一個使用者的的任務放到一個檔案中,這個檔案代碼如下:
---
# Requires a user variable to specify user to setup
- name: Create user account
user: name={{ user }} state=present
- name: Make user SSH config dir
file: path=/home/{{ user }}/.ssh owner={{ user }} group={{ user
}} mode=0600 state=directory
- name: Copy in public key
copy: src=keys/{{ user }}.pub dest=/home/{{ user
}}/.ssh/author
我們預計變數名{{user}}會被傳遞給我們,他們的公開金鑰在keys目錄中。使用者建立之後,ssh config檔案夾就被建立,然後我們複製公開金鑰檔案進去。包含這個任務最簡單的辦法就是使用第三章介紹的with_items關鍵字
代碼如下:
---
- hosts: ansibletest
user: root
tasks:
- include: usersetup.yml user={{ item }}
with_items:
- mal
- dan
- kate
Handler includesWhen writing Ansible playbooks, you will constantly find yourself reusing the samehandlers multiple times. For instance, a handler used to restart MySQL is going tolook the same everywhere. To make this easier, Ansible allows you to include otherfiles in the handlers section. Handler includes look the same as task includes. Youshould make sure to include a name on each of your handlers; otherwise you will notbe able to refer to them easily in your tasks. A handler include file looks similar tothe following code:---- name: config sendmailcommand: make -C /etc/mailnotify: reload sendmail- name: config aliasescommand: newaliasesnotify: reload sendmail- name: reload sendmailservice: name=sendmail state=reloaded- name: restart sendmailservice: name=sendmail state=restartedThis file provides several common tasks that you would want to handle afterconfiguring sendmail . By including the following handlers in their own files, youcan easily reuse them whenever you need to change the sendmail configuration:• The first handler regenerates the sendmail database's config file andtriggers a reload file of sendmail later• The second handler initializes the aliases database, and also schedules areload file of sendmailThe third handler reloads sendmail ; it may be triggered by the previous twojobs, or it may be triggered directly from a task• The fourth handler restarts sendmail when triggered; this is useful if youupgrade sendmail to a new versionHandlers can trigger other handlers provided that they only triggerthe ones specified later, instead of the triggered ones. This means, youcan set up a series of cascading handlers that call each other. This savesyou from having long lists of handlers in the notify section of tasks.Using the preceding handler file is easy now. We simply need to remember that if wechange a sendmail configuration file, then we should trigger config sendmail , andif we change the aliases file, we should trigger config aliases . The followingcode shows us an example of this:---hosts: mailers#1tasks:#2- name: update sendmail#3yum: name=sendmail state=latestnotify: restart sendmail#5#4- name: configure sendmail#6template: src=templates/sendmail.mc.j2dest=/etc/mail/sendmail.mc#7notify: config sendmail#8handlers:#9- include: sendmailhandlers.yml#10This playbook makes sure sendmail is installed. If it isn't installed or if it isn'trunning the latest version, then it installs it. After it is updated, it schedules arestart so that we can be confident that the latest version will be running once theplaybook is done. In the next step, we replace the sendmail configuration file withour template. If the config file was changed by the template then the sendmailconfiguration files will be regenerated, and finally sendmail will be reloaded.
Handler 處理常式包含
當我們編寫playbooks時,Handler也是經常被重用的。比如,重啟MYSQL的handler到處可以見。我們可以在Handler選項中包含他們,和任務包含一樣,你要確定包含了每一個你需要的Handler的名字,否則在引用的時候就不那麼方便了。Handler包含的檔案類似如下代碼:
---
- name: config sendmail
command: make -C /etc/mail
notify: reload sendmail
- name: config aliases
command: newaliases
notify: reload sendmail
- name: reload sendmail
service: name=sendmail state=reloaded
- name: restart sendmail
service: name=sendmail state=restarted
這個檔案包含了許多在配置完sendmail之後需要的做的handler操作,如果我們在任務檔案本身包含他們,在你需要改變sendmail配置的時候將很容易被重用。
- 第一個handler在重建設定檔之後,重新載入了設定檔
- 第二個handler在配置玩aliases之後,重新載入了設定檔
- 第三個handler重新載入設定檔,它可以是被前面2個任務觸發,也可以在包含他的任務中直接調用他們
- 第四個handler重啟了sendmail服務,如果你升級了sendmail版本,你可能就要用到了
注意:Handlers 也可以被其他的Handlers觸發,其中會有重複的Handlers,但是只有最後一個被指定的Handlers會被執行。這樣在你的任務中的notify選項就不需要一串長長的Handlers列表了。
使用這個Handlers檔案很簡單,我們只要記住:如果我們改變了設定檔,我們就觸發config sendmai,如果我們該了aliases,我們就觸發config aliases,代碼如下:
---
hosts: mailers
tasks:
- name: update sendmail
yum: name=sendmail state=latest
notify: restart sendmail
- name: configure sendmail
template: src=templates/sendmail.mc.j2
dest=/etc/mail/sendmail.mc
notify: config sendmail
handlers:
- include: sendmailhandlers.yml
如果sendmail沒安裝或者不是最新版本,這個palybook會安裝並更新它,之後需要重啟;使用模板檔案之後,還需要重建sendmail設定檔,而這2個處理常式都被包含在sendmailhandlers.yml檔案中。
Playbook includesPlaybook includes should be used when you want to include a whole set of tasksdesignated for a set of machines. For example, you may have a play that gathersthe host keys of several machines and builds a known_hosts file to copy to all themachines.While task includes allows you to include tasks, playbook includes allows you toinclude whole plays. This allows you to select the hosts you wish to run on, andprovide handlers for notify events. Because you are including whole playbook files,you can also include multiple plays.Playbook includes allows you to embed fully self-contained files. It is for this reasonthat you should provide any variables that it requires. If they depend on any particularset of hosts or groups, this should be noted in a comment at the top of the file.This is handy when you wish to run multiple different actions at once. For example,let's say we have a playbook that switches to our DR site, named drfailover.yml , another named upgradeapp.yml that upgrades the app, another nameddrfailback.yml that fails back, and finally drupgrade.yml . All these playbooksmight be valid to use separately, but when performing a site upgrade, you willprobably want to perform them all at once. You can do this as shown in thefollowing code:---- include "drfailover.yml"- include "upgradeapp.yml"- include "drfailback.yml"#1#2#3- name: Notify management#4hosts: local#5tasks:#6- local_action: mail to="mgmt-team@example.com" msg='Theapplication has been upgraded and is now live'#7- include "drupgrade.yml"#8As you can see, you can put full plays in the playbooks that you are including otherplaybooks into.
Playbook 包含
當你需要為一批機器設計一系列任務的時候,你可以使用playbooks包含。比如,你可能想要收集一批機器的host key合并到known_hosts中,然後分發給所有機器。
playbook包含允許你選擇啟動並執行主機、handler處理常式。另外,除了包含一個playbook,你還可以包含多個playbook。
playbook包含允許您嵌入完全自包含的檔案,因此你應該提供任何需要的變數。如果它依賴某些特殊的主機或組,那你應該在檔案頂部中做好注釋。當你要一次性運行多個actions操作的時候,使用playbook包含非常方便。
比如:我們有一個檔案叫drfailover.yml用來切換我們的dr(dr是負載平衡配置的名詞,一般有一主一備2個dr,這裡不多做解釋啦,同學們可以百度之),一個叫upgradeapp.yml的檔案用來更新應用程式,一個叫drfailback.yml的檔案用來切換回原來的dr,還有一個drupgrade.yml用來升級dr。這些檔案都是獨立的,當我們想升級應用程式的時候,我們可以一次性使用它們。代碼如下:
---
- include "drfailover.yml"
- include "upgradeapp.yml"
- include "drfailback.yml"
- name: Notify management
hosts: local
tasks:
- local_action: mail to="mgmt-team@example.com" msg='The
application has been upgraded and is now live'
- include "drupgrade.yml"
使用playbook之後,你可以把所有操作都放在一個playbook中了!