概述
ansible是一款無需在被管理主機上安裝客戶端,基于SSH對多臺目標主機進行同時操作的輕量級的管理軟件,借助各個內部的功能模塊,實現了批量系統配置、批量程序部署、批量運行命令等功能。本篇就介紹一些關于ansible的基礎配置相關的內容,具體包括:
1、ansible的簡介
2、ansible的基礎應用
3、ansible常用模塊介紹
4、ansible的playbook基礎應用介紹
5、playbook中的handlers(觸發器)的介紹
6、playbook中的tags(標簽)的介紹
7、playbook中的variables(變量)的介紹
8、playbook中的templates(模板)的介紹
9、playbook中的條件判斷機制的介紹
10、playbook中的循環(迭代)機制的介紹
11、ansible的roles(角色)功能的介紹
12、ansible實戰一:利用ansible配置主備模型的keepalived+nginx
13、ansible實戰二:實戰一的基礎上在nginx后端提供httpd+php+php-mysql
14、ansible實戰三:在此前實驗基礎上配置mysql服務
第一章 ansible的簡介
1、ansible的軟件結構
Host Inventory:主機清單,也就是被管理的主機列表
Playbooks:ansible的劇本,可想象為將多個任務放置在一起,一塊執行
Core Modules:ansible的核心模塊
Custom Modules:自定義模塊
Connection Plugins:連接插件,用于與被管控主機之間基于SSH建立連接關系
Plugins:其他插件,包括記錄日志等
2、ansible的特性
<1>模塊化:調用特定的模塊,完成特定任務
<2>基于python語言實現,由Paramiko(完成基于ssh的連接),PyYAML(對YAML文件的支持),jinja2(python的模板庫)三個關鍵的模塊
<3>部署簡單:是沒有客戶端的
<4>支持自定義模塊,使用任意編程語言
<5>支持強大的playbook
<6>具有冪等性:一個操作在一個主機上執行一遍和執行N遍的結果是一樣的
第二章 ansible的基礎應用
1、ansible管理端的安裝
在EPEL源中,有包含ansible的軟件包安裝只需要配置好EPEL的yum源,yum安裝即可
安裝生成的文件
2、ansible被管控主機的定義
對希望被管控的主機的定義需要實現在ansible管理端的針對被管理主機的配置文件(/etc/ansible/hosts)中進行定義
3、配置管理節點可以基于ssh秘鑰登錄被管理節點
4、ansible命令的用法介紹
ansible HOST-PATTERN [-f FORKS] [-m MOD_NAME] [-a MOD_ARGS]
HOST_PATTERN:指明對哪些被管控主機進行操作
-f FORKS:表示一批處理幾臺主機,也就是當被管控主機很多時,ansible不是對所有主機同時發起管理操作,而是一批處理幾臺,然后再換一批,直到所有主機被處理完成,如果不指定,則默認是5臺
-m MOD_NAME:指明調用哪個模塊執行操作,各個模塊所能實現的功能不同,如果不指定,默認是用-m command模塊
-a MOD_ARGS:指明使用該模塊的執行操作時的參數
第三章 ansible常用模塊介紹
1、獲取常用模塊的列表和對應模塊的使用幫助信息
可用ansible-doc -l 來查看所有可用的模塊列表
可用ansible-doc -s MOD_NAME 來查看對應模塊的幫助信息
2、command模塊
在遠程主機執行命令,不支持管道,重定向等shell的特性
常用參數有:
chdir= 表示指明命令在遠程主機上哪個目錄下運行,也就是在命令執行前切換到哪個目錄下
creates= 在命令運行時創建一個文件,如果文件已存在,則不會執行創建任務
removes= 在命令運行時移除一個文件,如果文件不存在,則不會執行移除任務
executeble= 指明運行命令的shell程序
3、shell模塊
在遠程主機執行命令,相當于調用遠程主機的shell進程,然后在該shell下打開一個子shell運行命令
支持shell特性,如管道,重定向等
注意:command和shell模塊的核心參數直接為命令本身,而其他模塊的核心參數一般是"key=value"格式
常見參數有:
chdir= 表示指明命令在遠程主機上哪個目錄下運行
creates= 在命令運行時創建一個文件,如果文件已存在,則不會執行創建任務
removes= 在命令運行時移除一個文件,如果文件不存在,則不會執行移除任務
executeble= 指明運行命令的shell程序
4、copy模塊
拷貝ansible管理端的文件到遠程主機的指定位置
常見參數有:
dest= 指明拷貝文件的目標目錄位置,使用絕對路徑,如果源是目錄,則目標也要是目錄,如果目標文件已存在,會覆蓋原有內容
src= 指明本地路徑下的某個文件,可以使用相對路徑和絕對路徑,支持直接指定目錄,如果源是目錄,則目標也要是目錄
mode= 指明復制時,目標文件的權限
owner= 指明復制時,目標文件的屬主
group= 指明復制時,目標文件的屬組
content= 指明復制到目標主機上的內容,不能與src一起使用,相當于復制content指明的數據,到目標文件中
5、cron模塊
管理計劃任務的模塊
常見參數有:
minute= 指明計劃任務的分鐘,支持格式:0-59,*,*/2等,與正常cron任務定義的一樣的語法,省略時,默認為*,也就是每分鐘都執行
hour= 指明計劃任務的小時,支持的語法:0-23,*,*/2等,省略時,默認為*,也就是每小時都執行
day= 指明計劃任務的天,支持的語法:1-31,*,*/2等,省略時,默認為*,也就是每天都執行
month= 指明計劃任務的月,支持的語法為:1-12,*,*/2等,省略時,默認為*,也就是每月都執行
weekday= 指明計劃任務的星期幾,支持的語法為:0-6,*等,省略時,默認為*,也就是每星期幾都執行
reboot 指明計劃任務執行的時間為每次重啟之后
name= 給該計劃任務取個名稱,必須要給明。每個任務的名稱不能一樣。刪除任務時,只需要給明任務的名稱即可
job= 執行的任務是什么,當state=present時才有意義
state=present|absent 表示這個任務是創建還是刪除,present表示創建,absent表示刪除,默認是present
6、fetch模塊
從遠程主機拉取文件到本地
一般情況下,只會從一個遠程節點拉取數據
常見參數有:
dest= 從遠程主機上拉取的文件存放在本地的位置,一般只能是目錄
src= 指明遠程主機上要拉取的文件,只能是文件,不能是目錄
7、file模塊
用于設定遠程主機上的文件屬性
常見參數有:
path= 指明對哪個文件修改其屬性
src= 指明path=指明的文件是軟鏈接文件,其對應的源文件是誰,必須要在state=link時才有用
state=directory|link|absent 表示創建的文件是目錄還是軟鏈接
owner= 指明文件的屬主
group= 指明文件的屬組
mode= 指明文件的權限
創建軟鏈接的用法:
src= path= state=link
修改文件屬性的用法:
path= owner= mode= group=
創建目錄的用法:
path= state=directory
刪除文件:
path= state=absent
8、hostname模塊
管理遠程主機上的主機名
常用參數有
name= 指明主機名
9、yum模塊
基于yum機制,對遠程主機管理程序包
常用參數有:
name= 指明程序包的名稱,可以帶上版本號,不指明版本,就是默認最新版本。
state=present|latest|absent 指明對程序包執行的操作,present表示安裝程序包,latest表示安裝最新版本的程序包,absent表示卸載程序包
disablerepo= 在用yum安裝時,臨時禁用某個倉庫,倉庫的ID
enablerepo= 在用yum安裝時,臨時啟用某個倉庫,倉庫的ID
conf_file= 指明yum運行時采用哪個配置文件,而不是使用默認的配置文件
diable_gpg_check=yes|no 是否啟用gpg-check
10、service模塊
用來管理遠程主機上的服務的模塊
常見參數有:
name= 被管理的服務名稱
state=started|stopped|restarted 表示啟動或關閉或重啟
enabled=yes|no 表示要不要設定該服務開機自啟動
runlevel= 如果設定了enabled開機自動啟動,則要定義在哪些運行級別下自動啟動
11、uri模塊
如果遠端是web服務器,可以利用ansible直接請求某個網頁
常見參數有:
url= 指明請求的url的路徑,如:http://10.1.32.68/test.jpg
user= 如果請求的url需要認證,則認證的用戶名是什么
password= 如果請求的url需要認證,則認證的密碼是什么
method= 指明請求的方法,如GET、POST…
body= 指明報文中實體部分的內容,一般是POST方法或PUT方法時用到
HEADER_ 自定義請求報文中的添加的首部
12、user模塊
管理遠程主機上的用戶的賬號
常見參數有:
name= 指明要管理的賬號名稱
state=present|absent 指明是創建賬號還是刪除賬號,present表示創建,absent表示刪除
system=yes|no 指明是否為系統賬號
uid= 指明用戶UID
group= 指明用戶的基本組
groups= 指明用戶的附加組
shell= 指明默認的shell
home= 指明用戶的家目錄
move_home=yes|no 當home設定了家目錄,如果要創建的家目錄已存在,是否將已存在的家目錄進行移動
password= 指明用戶的密碼,最好使用加密好的字符串
comment= 指明用戶的注釋信息
remove=yes|no 當state=absent時,也就是刪除用戶時,是否要刪除用戶的而家目錄
13、group模塊
用來添加或刪除遠端主機的用戶組
常見參數有:
name= 被管理的組名
state=present|absent 是添加還是刪除,不指名默認為添加
gid= 指明GID
system=yes|no 是否為系統組
14、script模塊
將管理端的某個腳本,移動到遠端主機(不需要指明傳遞到遠端主機的哪個路徑下,系統會自動移動,然后執行),然后執行
一般是自動移動到遠端主機的/root/.ansible/tmp目錄下,然后自動給予其權限,然后再開個子shell然后運行腳本,運行完成后刪除腳本
15、setup模塊
可收集遠程主機的facts變量的信息,相當于收集了目標主機的相關信息(如內核版本、操作系統信息、cpu、…),保存在ansible的內置變量中,之后我們有需要用到時,直接調用變量即可
16、template模塊的使用
基于模板方式,生成一個模板文件,復制到遠程主機,讓遠程主機基于模板,生成符合遠程主機自身的文件
注意:此模塊不能在命令行使用,只能用在playbook中
常見的參數有:
src= 指明管理端本地的模板文件的目錄
dest= 指明將模板文件拷貝到遠程主機的哪個目錄下
owner= 指明拷貝到遠程主機的文件的屬主
group= 指明拷貝到遠程主機的文件的屬組
mode= 指明拷貝到遠程主機的文件的權限
第四章 ansible的playbook基礎應用介紹
當需要執行的任務有多個時,需要一條一條編輯ansible命令,然后執行,而且當需要重復執行時,又要重新編輯執行,這樣效率不高,因此ansible就可以利用playbook來完成將任務寫到一個YAML格式的文件中,然后利用ansible-playbook進行調用該文件,從而實現了多條語句,可重復執行的效果,類似shell腳本的效果,ansible的playbook要借助YAML文件來實現,YAML文件擴展名通常為.yaml或.yml
1、YAML文件的語法
YAML語法和其他高階語言類似,并可以簡單表達清單,散列表、標量等數據結構。其結構通過空格來展示,序列里的項用“-”來代表,Map你的鍵值用“;”分隔
YAML文件中列表的表示:列表中的所有元素均使用"-" 開頭,例如:
– apple
– orange
– mango
YAML文件中字典的表示:字典通過key與value進行標識,如:
name: nwc
job: manager
sex: M
也可以將key:value放置于{}中進行表示,如
{name: nwc,job: manager,sex: M}
2、playbook的核心元素
Hosts:運行在哪些主機之上
Users:遠程主機上,運行此任務的身份,不指名默認為root
Tasks:任務,也就是定義的具體任務,由模塊定義的操作的列表
Variables:變量
Templates:模板,包含了模板語法編寫的模板的文本文件
Handlers:處理器,類似Tasks,只是在特定的條件下才會觸發的任務
某任務的狀態在運行后為changed時,可通過"notify"通知給相應的handlers進行觸發執行
Roles:角色,將Hosts剝離出去,由Tasks、Variables、Templates、Handlers所組成的一種特定的結構的集合
3、playbook的基礎組件
hosts:運行指定任務的而目標主機,多個主機用:冒號分隔
remote_user:在遠程主機上執行任務的用戶;可以全局指定,也可以單個任務指定
sudo_user:表示以sudo方式運行任務時,切換為哪個用戶身份運行
tasks:
任務列表,ansible運行任務的方式為,將第一個任務在所有主機上運行完成,然后再將第二個任務在所有主機上運行…,當某個任務在某個主機上運行出現故障,會造成任務終止,再次執行任務只需直接執行即可
定義任務列表,實際就是指明使用的模塊和對應的模塊參數來完成的任務的列表,其格式有兩種:
(1)action:MODULE ARGUMENTS
(2)MODULE:ARGUMENTS
注意:shell和command模塊后面直接跟命令,而不是key=value的參數列表
4、playbook文件的執行
playbook文件定義的任務要向執行,需要利用ansible-playbook命令進行調用
ansible-playbook命令用法:
<1> 檢測語法
ansible-playbook –syntax-check /PATH/TO/PLAYBOOK.yaml
<2> 測試運行
ansible-playbook -C|–check /PATH/TO/PLAYBOOK.yaml
只檢測執行指定的YAML文件可能會發生改變,但不真正執行操作,相當于測試運行
–list-hosts 檢測YAML文件可能影響到的主機列表
–list-tasks 列出YAML文件的任務列表
–list-tags 列出YAML文件中的標簽
<3> 運行
ansible-playbook /PATH/TO/PLAYBOOK.yml
可用選項:
不加任何選項表示完整運行整個playbook文件
-t TAGS,–tags=TAGS 表示只執行那個標簽的任務
–skip-tags=SKIP_TAGS 表示除了指明的標簽的任務,其他任務都執行
–start-at-task=START_AT 從指明的任務開始往下運行
<4> 通常情況下劇本的執行過程
先要利用 ansible-playbook -C|–check /PATH/TO/PLAYBOOK.yaml進行測試,測試沒問題后
再利用 ansible-playbook /PATH/TO/PLAYBOOK.yml正式執行
第五章 playbook中的handlers(觸發器)的介紹
1、handlers的作用
用于當關注資源發生變化時采取一定的操作,可理解為:當之前定義在tasks中的任務,如果執行成功后,我們希望在此基礎上觸發某個別的任務,這時就需要定義handlers。
要想handlers生效,首先需要在tasks的任務中定義一個notify,表示執行成功后,通知執行哪個handler,然后再定義handlers中,定義handler任務,handler任務的name要與notify中定義通知給哪個handler的名稱一致
2、handlers觸發器的使用示例:
第六章 playbook中的tags(標簽)的介紹
1、tags標簽的作用
當我們定義了一個playbook文件,文件有很多任務要執行,如果我們只是希望執行其中的某一個任務,則可以在編寫該任務時,為該任務加上標簽,然后利用ansible-playbook調用時,指明只執行那個tags標簽的任務(ansible-playbook -t TAG_NANE YAML文件)
可以將多個任務提供一樣的標簽,這樣,就可以實現指定運行某標簽的任務時,同時運行多個任務;也支持一個任務定義多個標簽
可以在用ansible-playbook利用-t指明執行的標簽的任務時,支持用逗號,隔開的多個標簽,則也是多個標簽的任務都執行
2、tags標簽的示例
第七章 playbook中的variables(變量)的介紹
在playbook中可在各個任意地方使用變量,引用變量的格式為:{{ VAR_NAME }},變量名與大括號之間有空格
定義變量的方式分別為:
1、facts類型的變量:
可直接調用,是ansible收集的關于被管理主機的相關信息,其被保存在ansible的一些變量中,如果要查看某個被管理主機有哪些facts變量可用,則可以執行:
ansible 10.1.32.72 -m setup
可列出10.1.32.72主機上可用的所有的facts變量及其值
2、ansible-playbook命令的命令行中的自定義變量:
ansible-playbook -e VARS=VALUE
如果要指定多個變量,則用多個-e引導即可
3、在定義主機的hosts中(也就是/etc/ansible/hosts文件中)定義變量
<1>實現向不同的主機傳遞不同的變量
如:vim /etc/ansible/hosts
[webserver]
10.1.32.72 hname=web1 aaa=111 bbb=test
10.1.32.73 hname=web2 aaa=222
表示針對10.1.32.72這臺主機,hname這個變量的值為8080,aaa變量的值為111,bbb變量的值為test
針對10.1.32.73這臺主機,hname這個變量的值為8090,aaa變量的值為222
<2>實現向某個組內的主機,傳遞相同的變量
如:vim /etc/ansible/hosts
[webserver:vars]
http_port=8080
表示向webserver組內的主機定義相同的變量http_port,其值都為8080
<3>hosts文件中在每個主機后面可以用ansible_ssh_user和ansible_ssh_pass來指明ansible連接該主機時,不是采用我們之前自己手動執行的利用ssh秘鑰登錄,而是直接將用戶名密碼寫入到/etc/ansible/hosts文件中,每次連接都是基于用戶名密碼的登錄
如:vim /etc/ansible/hosts
[dbserver]
10.1.32.68 ansible_ssh_user=root ansible_ssh_pass=123456
10.1.32.73
注意,此類參數不能傳遞給playbook,也就是無法進行調用,只是用來ansible連接遠程主機時的定義
除了上面的兩個參數,還有:
ansible_ssh_host 連接的遠程主機
ansible_ssh_port 連接的遠程主機的端口
ansible_sudo_pass 以sudo方式運行任務時的sudo用戶的密碼
4、在playbook的yaml文件中定義變量
如:有個YAML文件為/root/test.yaml,內容為
– hosts: webserver
remote_user: root
vars:
– pkname: httpd
– yname: php
tasks:
– name: install packages
yum: name={{ pkname }} state=present
– name: install packages2
yum: name={{ yname }} state=present
第八章 playbook中的templates(模板)的介紹
1、templates模板文件的說明
templates是模板文本文件,但是此文本文件內部嵌套有腳本(腳本是使用模板編程語言編寫),主要用來提供文件模板,讓被管理主機根據模板中定義的腳本,生成符合遠程主機環境的文件,也就是相當于提供一個模板文件,拷貝到被管理主機上,被管理主機根據自身的情況,生成符合自身實際的文件,模板文件中的語法,是語句模板編程語言所定義的,在ansible中,是jinja2的語法格式(因為ansible是python語言開發,而python嵌入文本中的語言是jinja2)
2、jinja2常用的語法
數據類型(字面量):
字符串:使用單引號或雙引號引用起來的都被認為是字符串
數字:整數、浮點數,不能用引號
列表:[item1,item2,…]
元組:(item1,item2,…)
字典:{key1:value1,key2:value2,…}
字典的key一般是字符串,所以要用引號引起來
布爾型:true/false
算數運算:
+、-、*、/、//(除完以后只保留商)、%(取模,除完以后只留余數)、**(次方)
比較操作:
==、!=、>、>=、<、<=
邏輯運算:
and、or、not
變量引用:與YAML語法一樣
{{ VAR_NAME }}
迭代(循環)、條件判斷
3、template模塊
當模板文件生成后,就可以借助template模塊,將模板文件拷貝到被管控主機上,生成符合遠端主機環境的文件,注意不能用copy模塊進行拷貝,因為copy模塊拷貝時,模板文件中定義的一些jinja2的語法結構會被當做純文本信息進行拷貝,而用template模塊進行拷貝時,則會識別jinja2的語法,將對應的語法替換為符合遠端主機的具體的值,生成符合遠端主機環境的文件
template模塊的參數有:
src= 指明管理端本地的模板文件的目錄
dest= 指明將模板文件拷貝到遠程主機的哪個目錄下
owner= 指明拷貝到遠程主機的文件的屬主
group= 指明拷貝到遠程主機的文件的屬組
mode= 指明拷貝到遠程主機的文件的權限
4、template模板使用配置示例
第九章 playbook中的條件判斷機制的介紹
當我們希望在playbook文件中,完成諸如在某條件滿足時,才執行指定的任務時,就需要借助條件判斷機制。
要想使用條件判斷,可以在tasks中使用when語句,標明在什么情況下,才執行該任務,when語句支持jinja2的語法格式
示例:
第十章 playbook中的循環(迭代)機制的介紹
1、循環的相關概念
當需要重復執行同一類任務時,可以用到循環
循環實際就是對迭代項的引用,迭代項的固定變量名為item,而后在tasks使用with_items給定要迭代的元素列表
with_items在表示機制可以使用
列表:如
with_items:
– aa
– bb
…
該種方式定義的迭代項直接用:{{ item }}進行引用
也可以使用字典,如:(如果值為字符串,需要用引號引起來,變量與值之間要用空格隔開)
with_items:
– {var1: value1,var2: value2,…}
– {var1: value3,var2: value4,…}
…
該種方式定義的迭代項,應用要用 {{ item.var1 }}引用第一個變量,{{ item.var2 }}引用第二個變量…
2、循環的示例一:列表形式的迭代項的循環引用
3、循環示例二:字典形式的迭代項的循環引用
第十一章 ansible的roles(角色)功能的介紹
1、角色的相關概念
角色集合,實際是相當于多種不同的tasks的文件的集中存儲在某個目錄下,該目錄就是角色集合就是roles(默認是/etc/ansible/roles/目錄,可通過ansible的配置文件來調整默認的角色目錄),在該目錄下有很多子目錄,就是一個一個的不同角色目錄,而在每個角色目錄下就會有分別有具體的功能的實現
如:/etc/ansible/roles/ 此為角色集合,目錄下有自定義的各個子目錄,如
mysql/子目錄,也就是mysql角色
httpd/子目錄,也就是httpd角色
nginx/子目錄,也就是nginx角色
2、角色的目錄結構
每個角色的定義,以特定的層級目錄結構進行組織:以mysql/子目錄(mysql角色)為例:(每種角色的目錄結構都一樣) files/子目錄 存放由copy或script等模塊調用的文件 templates/子目錄 存放template模塊查找所需要的模板文件的目錄,如之前示例中用于給被管理主機提供nginx的模板配置文件 tasks/子目錄 任務存放的目錄,至少應該包含一個main.yml的文件,文件中定義了需要執行的任務清單,該目錄下也可以有 其他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來 handlers/子目錄 存放相關觸發執行器的目錄,至少應該包含一個main.yml的文件,文件中定義了觸發器的任務清單,該目錄下 也可以有其他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來 vars/子目錄 變量存放的目錄,至少應該包含一個main.yml的文件,文件中定義了相關的變量及其值,該目錄下也可以有其 他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來 meta/ 用于存放此角色元數據,至少應該包含一個main.yml的文件,文件中定義當前角色的特殊設定及其依賴關系, 該目錄下也可以有其他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來 default/ 默認變量存放的目錄,至少應該包含一個main.yml的文件,文件中定義了此角色使用的默認變量,該目錄下也 可以有其他.yml文件,但是需要在main.yml文件中用include指令將其他.yml文件包含進來 ####### 除了tasks目錄,上述目錄結構并非每個都必須,而是根據實際需要進行創建 #######
3、在playbook中調用角色方法一:
如何利用定義的角色,在某些主機上完成某些任務:此時就需要調用相關的角色了
如:(相關示例詳見實戰部分) - hosts: webserver remote_user: root roles: - mysql - httpd 可以只調用一個角色,也可以調用多個角色,當定義了角色后,用ansible-playbook PLAYBBOOK文件 執行即可 此時ansible會到角色集合的目錄(默認/etc/ansible/roles/ 目錄)去找 roles:調用的角色,也就是在角色集合 目錄下找同名的子目錄,將子目錄下的所有代碼運行一遍
4、在playbook中調用角色方法二:(在角色調用時傳遞變量)
如:(相關示例詳見實戰部分)
- hosts: webserver remote_user: root roles: - {role: mysql,var1: value1,var2: value2,...} - {role: httpd,var3: value3,var4: value4,...} 表示調用兩個角色,(role鍵用于指定調用的角色名稱,后續的key/value用于傳遞變量給角色,每個鍵后面對應的值之間有空格) 一個角色是mysql,向該角色傳遞變量var1,其值為value1,... 調用另一個角色httpd,向該角色傳遞變量var3,其值為value3,...
5、在playbook中調用角色時,實現條件判斷:
如:(相關示例詳見實戰部分)
- hosts: webserver remote_user: root roles: - {role: mysql,var1: value1,when:ansible_distribution_major_version=='7'} - {role: httpd,when:ansible_distribution_major_version=='6'} 表示當ansible_distribution_major_version的值為7時,調用mysql角色,傳遞變量var1,變量值為value1 表示當ansible_distribution_major_version的值為6時,調用httpd角色
第十二章 ansible實戰一:利用ansible配置主備模型的keepalived+nginx
1、實驗環境
2、實驗前準備工作
<1> 配置好各個節點之間的網絡環境
<2> 各個節點之間時間同步
<3> 配置各個節點之間,可基于主機名解析,且解析結果與實際主機名一致
<4> 確保iptables和selinux不會影響實驗正常進行
<5> 在ansible管理節點上部署ansible
<6> 配置ansible主機可基于ssh秘鑰登錄被管理主機的root用戶
<7> 為ansible配置被管理主機
3、在ansible主機上利用ansible的roles功能,在兩臺被管理主機上安裝和配置nginx
[root@node68 ~]# ****** 創建角色的目錄結構 ****** [root@node68 ~]# mkdir /etc/ansible/roles/nginx/{files,templates,tasks,handlers,vars,default,meta} -pv mkdir: 已創建目錄 "/etc/ansible/roles/nginx" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/files" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/templates" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/tasks" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/handlers" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/vars" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/default" mkdir: 已創建目錄 "/etc/ansible/roles/nginx/meta" [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 編輯tasks文件 ****** [root@node68 ~]# cat /etc/ansible/roles/nginx/tasks/main.yml - name: install a wget tool yum: name=wget state=present tags: - anzhuang wget - name: download nginx rpm package shell: chdir=/root wget ftp://10.1.0.1/pub/Sources/7.x86_64/nginx/nginx-1.10.0-1.el7.ngx.x86_64.rpm - name: install nginx shell: chdir=/root rpm -i nginx-1.10.0-1.el7.ngx.x86_64.rpm tags: - anzhuang nginx - name: provide a config file template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: - restart nginx - mail to root tags: - config and restart - name: move the default index page shell: mv /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.bak tags: - move default page and provide a new page - name: provied a index page template: src=index.html.j2 dest=/usr/share/nginx/html/index.html tags: - move default page and provide a new page [root@node68 ~]# [root@node68 ~]# ****** 因為tasks中定義了通知機制,故要編輯handler文件 ****** [root@node68 ~]# cat /etc/ansible/roles/nginx/handlers/main.yml - name: restart nginx shell: service nginx restart - name: mail to root shell: echo "nginx config file has been changed" | mail -s "nginx config file changed" root@localhost [root@node68 ~]# [root@node68 ~]# ****** 因為tasks中定義了template模塊相關任務,故要編輯生成template模板文件 ****** [root@node68 ~]# ls /etc/ansible/roles/nginx/templates/ index.html.j2 nginx.conf.j2 [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** nginx的模板配置文件 ****** [root@node68 ~]# cat /etc/ansible/roles/nginx/templates/nginx.conf.j2 user nginx; worker_processes {{ ansible_processor_vcpus }}; ###### worker進程的個數為ansible_processor_vcpus變量的值,表示與被管理主機上的cpu個數相等 ###### error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; server { listen 80; server_name {{ ansible_fqdn }}; ###### server_name為ansible_fqdn變量的值 ###### #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } #error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 提供的默認主頁的文件模板 ****** [root@node68 ~]# cat /etc/ansible/roles/nginx/templates/index.html.j2 <h1>This is {{ ansible_fqdn }} index page IP is {{ ansible_all_ipv4_addresses }}</h1> [root@node68 ~]#
4、編輯playbook文件,調用角色,執行劇本,讓被管理主機通過roles定義的方式,完成nginx安裝和配置
5、驗證被管理主機上nginx是否運行正常
6、編輯生成keepalived的roles角色,和相關配置文件
[root@node68 ~]# ***** 創建角色工作目錄 ****** [root@node68 ~]# mkdir -pv /etc/ansible/roles/keepalived/{files,templates,tasks,handlers,vars} mkdir: 已創建目錄 "/etc/ansible/roles/keepalived" mkdir: 已創建目錄 "/etc/ansible/roles/keepalived/files" mkdir: 已創建目錄 "/etc/ansible/roles/keepalived/templates" mkdir: 已創建目錄 "/etc/ansible/roles/keepalived/tasks" mkdir: 已創建目錄 "/etc/ansible/roles/keepalived/handlers" mkdir: 已創建目錄 "/etc/ansible/roles/keepalived/vars" [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 創建tasks任務列表 ****** [root@node68 ~]# cat /etc/ansible/roles/keepalived/tasks/main.yml - name: install keepalived package yum: name=keepalived state=present - name: move default config file shell: mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak tags: - move old config file - name: provide a config file for master template: src=keepalived.conf.master.j2 dest=/etc/keepalived/keepalived.conf when: is_master == "yes" notify: - mail to root tags: - provide a config file - name: provide a config file for backup template: src=keepalived.conf.backup.j2 dest=/etc/keepalived/keepalived.conf when: is_master == "no" notify: - mail to root tags: - provide a config file - name: restart keepalived shell: systemctl restart keepalived.service tags: - restart keepalived [root@node68 ~]# [root@node68 ~]# ****** 由于在tasks中定義了 notify,故定義相應的handlers ****** [root@node68 ~]# cat /etc/ansible/roles/keepalived/handlers/main.yml - name: mail to root shell: echo "keepalived on {{ ansible_all_ipv4_addresses }} config file has been changed" | mail -s "keepalived changed" root@localhost [root@node68 ~]# [root@node68 ~]# ****** 由于在task中定義了template模塊,故提供模板文件 ******* [root@node68 ~]# ls /etc/ansible/roles/keepalived/templates/ keepalived.conf.backup.j2 keepalived.conf.master.j2 [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 為keepalived的master節點提供的模板配置文件 ****** [root@node68 ~]# cat /etc/ansible/roles/keepalived/templates/keepalived.conf.master.j2 ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalivedadmin@nwc.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id {{ ansible_hostname }} vrrp_mcast_group4 224.0.32.18 } vrrp_script chk_nginx { script "killall -0 nginx" interval 2 weight -5 } vrrp_instance VI_1 { state MASTER interface eno16777736 #####此為心跳信息傳遞的接口,可以與VIP的接口不一樣##### virtual_router_id 32 priority 100 advert_int 2 authentication { auth_type PASS auth_pass 123456 } track_script { chk_nginx } virtual_ipaddress { 192.168.1.1/24 dev eno33554976 } track_interface { eno16777736 eno33554976 } } [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 為keepalived的backup節點提供的模板配置文件 ****** [root@node68 ~]# cat /etc/ansible/roles/keepalived/templates/keepalived.conf.backup.j2 ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalivedadmin@nwc.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id {{ ansible_hostname }} vrrp_mcast_group4 224.0.32.18 } vrrp_script chk_nginx { script "killall -0 nginx" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eno16777736 #####此為心跳信息傳遞的接口,可以與VIP的接口不一樣##### virtual_router_id 32 priority 98 advert_int 2 authentication { auth_type PASS auth_pass 123456 } track_script { chk_nginx } virtual_ipaddress { 192.168.1.1/24 dev eno33554976 } track_interface { eno16777736 eno33554976 } } [root@node68 ~]# [root@node68 ~]# ***** 由于在task任務列表文件中定義了變量,判斷當前節點是否是主節點的操作 ****** [root@node68 ~]# ***** 故針對每個節點定義其是否為主節點的變量 is_master ****** [root@node68 ~]# [root@node68 ~]# cat /etc/ansible/hosts # This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # - Blank lines are ignored # - Groups of hosts are delimited by [header] elements # - You can enter hostnames or ip addresses # - A hostname/ip can be a member of multiple groups [nginx] 10.1.32.72 is_master=yes 10.1.32.73 is_master=no [root@node68 ~]#
7、編輯playbook劇本文件,運行劇本
8、驗證keepalived對nginx的高可用是否成功
第十三章 ansible實戰二:實戰一的基礎上在nginx后端提供httpd+php+php-mysql
1、實驗環境
在實戰一的基礎上,為nginx提供后端提供httpd+php+php-mysql,本實驗中,將httpd,php,php-mysql均部署在 原有的nginx兩個節點上,將httpd的監聽端口改為8080,nginx繼續監聽80端口,修改nginx的配置文件,讓nginx 接受到的請求均反代到httpd服務上進行處理 用的實驗環境是實驗一的環境,故相關準備工作參照實驗一
2、利用ansible的roles,編輯roles相關配置
[root@node68 ~]# ****** 創建lap角色目錄 ****** [root@node68 ~]# mkdir -pv /etc/ansible/roles/lap/{files,templates,tasks,handlers,vars} mkdir: 已創建目錄 "/etc/ansible/roles/lap" mkdir: 已創建目錄 "/etc/ansible/roles/lap/files" mkdir: 已創建目錄 "/etc/ansible/roles/lap/templates" mkdir: 已創建目錄 "/etc/ansible/roles/lap/tasks" mkdir: 已創建目錄 "/etc/ansible/roles/lap/handlers" mkdir: 已創建目錄 "/etc/ansible/roles/lap/vars" [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 編輯生成tasks任務列表文件 ****** [root@node68 ~]# cat /etc/ansible/roles/lap/tasks/main.yml - name: install httpd yum: name=httpd state=present - name: install php yum: name=php state=present - name: install php-mysql yum: name=php-mysql state=present - name: make sure nginx proxy the request to httpd template: src=nginx.new.conf.j2 dest=/etc/nginx/nginx.conf notify: - reload nginx tags: - nginx proxy - name: move old httpd config file shell: mv /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak tags: - move old config - name: provide a httpd config file template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf notify: - restart http - name: provide index page template: src=index.html.j2 dest=/var/www/html/index.html - name: restart httpd service shell: systemctl restart httpd [root@node68 ~]# [root@node68 ~]# ***** 創建handlers觸發器文件 ***** [root@node68 ~]# cat /etc/ansible/roles/lap/handlers/main.yml - name: reload nginx shell: systemctl restart nginx - name: restart http shell: systemctl restart httpd [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 根據tasks中定義的模板文件,提供對應的template模板文件 ***** [root@node68 ~]# ls /etc/ansible/roles/lap/templates/ httpd.conf.j2 index.html.j2 nginx.new.conf.j2 [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 提供給遠程主機的httpd的默認主頁面的文件 ****** [root@node68 ~]# cat /etc/ansible/roles/lap/templates/index.html.j2 <h1> This is {{ ansible_nodename }} index page </h1> [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ******* 修改的nginx配置文件的模板文件 ****** [root@node68 ~]# cat /etc/ansible/roles/lap/templates/nginx.new.conf.j2 user nginx; worker_processes {{ ansible_processor_vcpus }}; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; ##### 定義后端主機 ##### upstream web { server 10.1.32.72:8080 max_fails=2; server 10.1.32.73:8080 max_fails=2; } server { listen 80; server_name {{ ansible_fqdn }}; ##### 定義將所有請求反代到后端主機的8080端口 ##### location / { root /usr/share/nginx/html; index index.html index.htm; proxy_pass http://web; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } } [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 提供httpd的配置文件的模板文件 ****** [root@node68 ~]# cat /etc/ansible/roles/lap/templates/httpd.conf.j2 ServerRoot "/etc/httpd" Listen 8080 ##### 修改監聽端口為8080 ##### Include conf.modules.d/*.conf User apache Group apache ServerAdmin root@localhost ServerName {{ ansible_nodename }} ##### ServerName的值修改為遠程主機的主機名 ###### <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "/var/www/html" <Directory "/var/www"> AllowOverride None # Allow open access: Require all granted </Directory> <Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> <IfModule dir_module> DirectoryIndex index.html </IfModule> <Files ".ht*"> Require all denied </Files> ErrorLog "logs/error_log" LogLevel warn <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> # You need to enable mod_logio.c to use %I and %O LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> CustomLog "logs/access_log" combined </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" </IfModule> <Directory "/var/www/cgi-bin"> AllowOverride None Options None Require all granted </Directory> <IfModule mime_module> AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml </IfModule> AddDefaultCharset UTF-8 <IfModule mime_magic_module> MIMEMagicFile conf/magic </IfModule> EnableSendfile on IncludeOptional conf.d/*.conf
3、編輯playbook文件,引用角色,測試運行,檢測有無錯誤信息
4、運行劇本,驗證反代是否成功
第十四章 ansible實戰三:在此前實驗基礎上配置mysql服務
1、實驗環境
在實驗一和實驗二的基礎上,部署一個后端mysql服務器,并啟動 配置mysql服務器擁有testdb庫,并允許testuser對其擁有所有權限 本實驗繼續利用實驗一的環境,在node73,也就是10.1.32.73這臺主機上安裝mariadb服務 相關準備工作的流程,詳見實驗一的準備工作部分
2、編寫ansible的roles角色的相關內容
[root@node68 ~]# ***** 為ansible管理端添加db主機組 ***** [root@node68 ~]# cat /etc/ansible/hosts # This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # - Blank lines are ignored # - Groups of hosts are delimited by [header] elements # - You can enter hostnames or ip addresses # - A hostname/ip can be a member of multiple groups [nginx] 10.1.32.72 is_master=yes 10.1.32.73 is_master=no [db] 10.1.32.73 [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 創建mariadb角色的相關目錄結構 ***** [root@node68 ~]# mkdir -pv /etc/ansible/roles/mariadb/{files,templates,tasks,handlers,vars} mkdir: 已創建目錄 "/etc/ansible/roles/mariadb" mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/files" mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/templates" mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/tasks" mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/handlers" mkdir: 已創建目錄 "/etc/ansible/roles/mariadb/vars" [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ***** 提供mariadb角色的tasks任務文件 ***** [root@node68 ~]# cat /etc/ansible/roles/mariadb/tasks/main.yml - name: install mariadb package yum: name=mariadb-server state=present - name: move old config file shell: mv /etc/my.cnf /etc/my.cnf.bak - name: provide a config file copy: src=my.cnf dest=/etc/my.cnf notify: - restart mariadb - name: create a testdb shell: mysql -uroot -e "CREATE DATABASE testdb;GRANT ALL ON testdb.* TO 'testuser'@'10.1.%.%' IDENTIFIED BY '111111';FLUSH PRIVILEGES;" [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# ****** 由于tasks定義了notify,故提供handlers觸發器的文件 ****** [root@node68 ~]# cat /etc/ansible/roles/mariadb/handlers/main.yml - name: restart mariadb shell: systemctl restart mariadb [root@node68 ~]# [root@node68 ~]# [root@node68 ~]# #### 提供mariadb的樣例配置文件 ##### [root@node68 ~]# cat /etc/ansible/roles/mariadb/files/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 #### 修改的配置文件 ###### skip_name_resolve = ON innodb_file_per_table = ON [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid !includedir /etc/my.cnf.d [root@node68 ~]#
3、編輯生成playbook文件,引用角色,測試執行劇本,查看是否有報錯
4、執行劇本,驗證配置是否正確
原創文章,作者:M20-1倪文超,如若轉載,請注明出處:http://www.www58058.com/57409