(一)架構(gòu)
Ansible Core
Modules
Core Modules(核心模塊)
Customed Modules(自定義模塊)
Host Inventory(主機(jī)清單,定義需要被管理的主機(jī))
Files
CMDB
配置管理數(shù)據(jù)庫??
PlayBooks(YAML格式的"劇本"即要執(zhí)行的具體任務(wù)描述文件)
Hosts
roles
Connection Plugins
并發(fā)連接插件
(二)Ansible概念與特性
Configuration、Command and Control
Ansible is a radically simple model-driven configuration management,
multi-node deployment, and remote task execution system. Ansible works
over SSH and does not require any software or daemons to be installed
on remote nodes. Extension modules can be written in any language and
are transferred to managed machines automatically.
運(yùn)維工具的分類:
agent:基于專用的agent程序完成管理功能葛作,puppet, func, zabbix, ...
agentless:基于ssh服務(wù)完成管理,無須在客戶端安裝額外軟件,ansible, fabric, ...
ansible特性
①學(xué)習(xí)曲線比較平滑
②模塊化:調(diào)用特定的模塊系宫,完成特定的任務(wù);
③基于Python語言研發(fā)荷憋,由Paramiko, PyYAML和Jinja2三個(gè)核心庫實(shí)現(xiàn);
④部署簡單:agentless;
⑤支持自定義模塊闷祥,使用任意編程語言夷蚊;
⑥強(qiáng)大的playbook機(jī)制构挤;
⑦冪等性, 即其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。這里主要指的是playbook具有該特性.
(三)ansible的安裝與使用
3.1.1安裝及程序環(huán)境
yum -y install ansible
#epel源,目前最新版本是2.2
程序
ansible # 主程序
ansible-playbook # 執(zhí)行playbook的程序
ansible-doc # 查看文檔
3.1.2各配置文件
主配置文件
/etc/ansible/ansible.cfg
主機(jī)清單:
/etc/ansible/hosts
角色目錄:
/etc/ansible/roles
插件目錄:
/usr/share/ansible_plugins/
3.2基本使用入門
3.2.1 ansible命令
ansible <host-pattern> [options]
host-pattern: 主機(jī)清單(host inventory)文件里的組名/通配符名或者某遠(yuǎn)程主機(jī)ip或者all
(表示所有的主機(jī)清單組)等
options:
-m MOD_NAME
#指明模塊 ansible-doc -l
可以獲取到模塊名
-a MOD_ARGS
#指明模塊參數(shù)
3.2.2 配置Host Inventory
[group_id]
HOST_PATTERN1
HOST_PATTERN2 ```

**3.3 ansible常用的模塊說明**
**模塊:**處理各種任務(wù)的庫
獲取模塊列表:**`ansible-doc -l`**
獲取指定模塊的使用幫助:**`ansible-doc -s MOD_NAME`**


|模塊名|作用與參數(shù)|
|:----:|:------|
|**ping**|探測目標(biāo)主機(jī)是否存活,無參數(shù),如下圖|

|模塊名|作用與參數(shù)|
|:----:|:------|
|**command**|**默認(rèn)的模塊**在遠(yuǎn)程主機(jī)執(zhí)行命令,注意參數(shù)不支持管道等特殊字符.示例:ansible websrvs -m command -a "ifconfig"|
|**shell**|在遠(yuǎn)程主機(jī)上調(diào)用shell解釋器運(yùn)行命令惕鼓,支持shell的各種功能筋现,例如管道等.**注意:command和shell模塊的核心參數(shù)直接為命令本身;而其它模塊的參數(shù)通常為“key=value”格式**.示例:|
|**copy**| 拷貝文件到遠(yuǎn)程主機(jī)用法|
(1) 復(fù)制文件-a "src= dest= "
(2) 給定內(nèi)容生成件content:直接編寫內(nèi)容 -a "content= dest= "
(3) dest:目標(biāo)文件地址
(4) mode, owner, group, ...
|模塊名|作用與參數(shù)|
|:----:|:------|
|**file**|設(shè)置文件屬性,可以創(chuàng)建目錄 創(chuàng)建鏈接文件 刪除文件等用法|
(1) 創(chuàng)建目錄: -a "path= state=directory"
(2) 創(chuàng)建鏈接文件: -a "path= src= state=link"
(3) 刪除文件: -a "path= state=absent"
(4) owner: -a "path= owner= .."
(5) mode: -a "path= mode=064 ..."
|模塊名|作用與參數(shù)|
|:----:|:------|
|**fetch**|從遠(yuǎn)程主機(jī)拉取文件,比較少用因?yàn)橛衧cp|
|**cron**|管理定時(shí)任務(wù)|
minute= # 指定分鐘
hour= # 指定小時(shí)
day= # 指定日期
month= # 指定月份
weekday= # 指定星期幾
job= # 定時(shí)任務(wù)的命令
name= # 對定時(shí)任務(wù)的描述
user= # 指定修改哪個(gè)用戶的crontab文件
state={present|absent} # 控制定時(shí)任務(wù),absent會將定時(shí)任務(wù)清除.
|模塊名|作用與參數(shù)|
|:----:|:------|
|**hostname**|管理主機(jī)名 示例: `ansible all -m hostname -a "name=IBM"`|
|**yum**|管理軟件包 **注意:YUM倉庫須事先配置好**示例: `ansible all -m yum -a "name=httpd state=present enabled=true"`|
|**service**|管理服務(wù),示例:`ansible all -m service -a "name=httpd state=started"`|
參數(shù)
name=
state={started|stopped|restarted}
enabled={true|false}
runlevel= #在哪些級別下可以開機(jī)自啟動
|模塊名|作用與參數(shù)|
|:----:|:------|
|**group**|添加或刪除組gid # Optional `GID' to set for the group.
name= # Name of the group to manage.
state # Whether the group should be present or not on the remote host.
system # If `yes', indicates that the group created is a system group.
|模塊名|作用與參數(shù)|
|:----:|:------|
|**user**|管理用戶帳號. 示例:|
|***setup***|**以json的格式收集遠(yuǎn)程主機(jī)的各個(gè)由ansible對其設(shè)定的變量參數(shù)即ansible_facts 這項(xiàng)非常重要**示例: `ansible all -m setup` |
** 3.4YAML語言(ansible的playbook文件就是用的這種格式)**
**YAML**(英語發(fā)音:
[/](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99)[?](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99#.E7.AC.A6.E8.99.9F)[j](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99#.E7.AC.A6.E8.99.9F)[?](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99#.E7.AC.A6.E8.99.9F)[m](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99#.E7.AC.A6.E8.99.9F)[?l](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99#.E7.AC.A6.E8.99.9F)[/](https://zh.wikipedia.org/wiki/Wikipedia:%E8%8B%B1%E8%AA%9E%E5%9C%8B%E9%9A%9B%E9%9F%B3%E6%A8%99)箱歧,尾音類似*camel*駱駝)是一個(gè)可讀性高矾飞,用來表達(dá)資料序列的格式。YAML參考了其他多種語言呀邢,包括:[C語言](https://zh.wikipedia.org/wiki/C%E8%AA%9E%E8%A8%80)洒沦、[Python](https://zh.wikipedia.org/wiki/Python)、[Perl](https://zh.wikipedia.org/wiki/Perl)价淌,并從[XML](https://zh.wikipedia.org/wiki/XML)申眼、電子郵件的數(shù)據(jù)格式(RFC [2822](http://www.rfc-editor.org/rfc/rfc2822.txt))中獲得靈感瞒津。Clark Evans在2001年首次發(fā)表了這種語言[[1]](https://zh.wikipedia.org/wiki/YAML#cite_note-1)
,另外Ingy d?t Net與Oren Ben-Kiki也是這語言的共同設(shè)計(jì)者[[2]](https://zh.wikipedia.org/wiki/YAML#cite_note-2)
括尸。目前已經(jīng)有數(shù)種編程語言或腳本語言支援(或者說解析)這種語言巷蚪。
*YAML*是"YAML Ain't a Markup Language"(YAML不是一種[標(biāo)記語言](https://zh.wikipedia.org/wiki/%E6%A0%87%E8%AE%B0%E8%AF%AD%E8%A8%80))的[遞回縮寫](https://zh.wikipedia.org/wiki/%E9%81%9E%E8%BF%B4%E7%B8%AE%E5%AF%AB)。在開發(fā)的這種語言時(shí)濒翻,*YAML* 的意思其實(shí)是:"Yet Another Markup Language"(仍是一種[標(biāo)記語言](https://zh.wikipedia.org/wiki/%E6%A0%87%E8%AE%B0%E8%AF%AD%E8%A8%80))[[3]](https://zh.wikipedia.org/wiki/YAML#cite_note-YAML_spec_2001_08_01-3)
屁柏,但為了強(qiáng)調(diào)這種語言以數(shù)據(jù)做為中心,而不是以標(biāo)記語言為重點(diǎn)肴焊,而用反向縮略語重新命名前联。
**常用數(shù)據(jù)結(jié)構(gòu)**
- 清單([陣列](https://zh.wikipedia.org/wiki/%E9%99%A3%E5%88%97))[[編輯](https://zh.wikipedia.org/w/index.php?title=YAML&action=edit§ion=6)]
習(xí)慣上清單比較常用區(qū)塊格式(block format)表示,也就是用短杠+空白字元作為起始娶眷。
--- # 最喜愛的電影
- Casablanca
- North by Northwest
- Notorious
--- # 購物清單
[milk, pumpkin pie, eggs, juice]
- 字典
{name:jerry, age:21}
{name: John Smith, age: 33}
**PlayBook的基本格式**
```python
核心元素:
hosts: 運(yùn)行指定任務(wù)的目標(biāo)主機(jī)似嗤;
remote_user:在遠(yuǎn)程主機(jī)以哪個(gè)用戶身份執(zhí)行;
tasks: 任務(wù)届宠,由模塊定義的操作的列表烁落;
Templates: 模板,即使用了模板語法的文本文件豌注;
Variables: 變量
handlers: 由特定條件觸發(fā)的Tasks伤塌;
Roles: 角色,由多個(gè)自包含的任務(wù) 變量 templates handlers等組成的操作的集合.
playbook的基礎(chǔ)組件:
hosts: 運(yùn)行指定任務(wù)的目標(biāo)主機(jī)
remote_user: 在遠(yuǎn)程主機(jī)以哪個(gè)用戶身份執(zhí)行;
sudo_user:非管理員需要擁有sudo權(quán)限轧铁;
tasks:任務(wù)列表
模塊每聪,模塊參數(shù),格式有如下兩種:
(1) action: module arguments
(2) module: arguments
示例1:
- hosts: all
remote_user: root
tasks:
- name: install a group
group: name=mygrp system=true
- name: install a user
user: name=user1 group=mygrp system=true
示例2:
- hosts: websrvs
remote_user:
tasks:
- name: install httpd package
yum: name=httpd
- name: start httpd service
service: name=httpd state=started
執(zhí)行playbook文件
運(yùn)行playbook,使用ansible-playbook命令
(1) 檢測語法
ansible-playbook --syntax-check /path/to/playbook.yaml
(2) 測試運(yùn)行
ansible-playbook -C /path/to/playbook.yaml
--list-hosts # 列出主機(jī)
--list-tasks # 列出任務(wù)
--list-tags # 列出標(biāo)簽
(3) 運(yùn)行
ansible-playbook /path/to/playbook.yaml
-t TAGS, --tags=TAGS
--skip-tags=SKIP_TAGS
--start-at-task=START_AT
handlers的用法
handlers:由特定條件觸發(fā)的Tasks齿风;
調(diào)用及定義方式:
tasks:
- name: TASK_NAME
module: arguments
notify: HANDLER_NAME
handlers:
- name: HANDLER_NAME
module: arguments
示例:
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=latest
- name: install conf file
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd service
- name: start httpd service
service: name=httpd state=started
handlers:
- name: restart httpd service
service: name=httpd state=restarted
tags的用法
tags: 給指定的任務(wù)定義(打)一個(gè)調(diào)用標(biāo)識药薯,以便可以選擇性地執(zhí)行或跳過執(zhí)行這些任務(wù),多個(gè)標(biāo)簽想要同時(shí)調(diào)用的話用","分隔開即可救斑。在playbook文件中的寫法如下:
- name: NAME
module: arguments
tags: TAG_ID
與tags相關(guān)的執(zhí)行方法:**ansible-playbook [-t, TAGS, --tags=TAGS] | [--skip-tags=SKIP_TAGS] | [--list-tags] PLAYBOOKFILE.yaml
**
Variables,變量童本,即向playbook傳遞相關(guān)變量使得playbook功能更強(qiáng)大(跟真正的腳本語言一樣了)
類型:
內(nèi)建變量:
(1) facts # 還記得ansible 10.1.1.78 -m setup setup模塊嗎?
自定義變量的幾種形式:
(1) 命令行傳遞脸候;
ansible-playbook -e VAR=VALUE
(2) 在hosts Inventory(/etc/ansible/hosts文件)中為每個(gè)主機(jī)定義專用變量值穷娱;
(a) 向不同的主機(jī)傳遞不同的變量 ;
IP/HOSTNAME variable_name=value
(b) 向組內(nèi)的所有主機(jī)傳遞相同的變量 运沦;
[groupname:vars] # 這個(gè)vars是固定寫法
variable_name=value
(3) 在playbook中定義 # 優(yōu)先級低于(1)泵额,所以同名變量(1)可以覆蓋(3)
vars: # 這個(gè)不能少
- var_name: value # 示例 - pkgname: httpd
- var_name: value
(4) Inventory還可以使用參數(shù):
用于定義ansible遠(yuǎn)程連接目標(biāo)主機(jī)時(shí)使用的屬性,而非傳遞給playbook的變量携添;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
...
(5) 在角色調(diào)用時(shí)傳遞
roles:
- { role: ROLE_NAME, var: value, ...}
變量調(diào)用梯刚,如下圖中的playbook文件中定義:
{{ var_name }}
Templates:模板,ansible中的模板功能由jinja2模塊支持,模板化一個(gè)文件到遠(yuǎn)程主機(jī)
文本文件薪寓,內(nèi)部嵌套有模板語言腳本(使用模板語言編寫)
Jinja2 is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.
語法:與Python一致
字面量:
字符串:使用單引號或雙引號亡资;
數(shù)字:整數(shù)、浮點(diǎn)數(shù)向叉;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false
算術(shù)運(yùn)算:
+, -, *, /, //, %, **
比較操作:
==, !=, >, <, >=, <=
邏輯運(yùn)算:and, or, not
執(zhí)行模板文件中的腳本锥腻,并生成結(jié)果數(shù)據(jù)流,需要使用template模塊且此模塊僅支持在playbook中使用
backup # Create a backup file including the timestamp information so you can get the original file back if you somehow clobbered it incorrectly.
dest= # Location to render the template to on the remote machine.
follow # This flag indicates that filesystem links, if they exist, should be followed.
group # name of the group that should own the file/directory, as would be fed to `chown'
mode # mode the file or directory should be, such as 0644 as would be fed to `chmod'. As of version 1.8, the mode may be specified as a symbolic mode (for example, `u+rwx' or `u=rw,g=r,o=r').
owner # name of the user that should own the file/directory, as would be fed to `chown'
selevel # level part of the SELinux file context. This is the MLS/MCS attribute, sometimes known as the `range'. `_default' feature works as for `seuser'.
serole # role part of SELinux file context, `_default' feature works as for `seuser'.
setype # type part of SELinux file context, `_default' feature works as for `seuser'.
seuser # user part of SELinux file context. Will default to system policy, if applicable. If set to `_default', it will use the `user' portion of the policy if available
src= # Path of a Jinja2 formatted template on the local server. This can be a relative or absolute path.
validate # The validation command to run before copying into place. The path to the file to validate is passed in via '%s' which must be present as in the visudo example below. validation to run before copying into place. T
~
注意:此模板不能在命令行使用母谎,而只能用于playbook瘦黑;
一個(gè)完整的playbook示例文件:
- hosts: ngxsrvs
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=latest
- name: install conf file
template: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: ngxconf
notify: reload nginx service
- name: start nginx service
service: name=nginx state=started enabled=true
handlers:
- name: reload nginx service
shell: /usr/sbin/nginx -s reload
playbook中的條件測試語句之when(可以使得playbook功能更靈活)
when:在tasks中使用,Jinja2的語法格式
- hosts: all
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=latest
- name: start nginx service on CentOS6
shell: service nginx start
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
#這里的ansible_distribution奇唤、ansible_distribution_major_version都是內(nèi)置變量幸斥,可用下圖方式獲得
- name: start nginx service
shell: systemctl start nginx.service
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
playbook中的循環(huán)測試語句之with_items
循環(huán):迭代,需要重復(fù)執(zhí)行的任務(wù)對迭代項(xiàng)的引用咬扇,固定變量名為"item”甲葬,使用with_item屬性給定要迭代的元素
元素:列表
字符串
字典
基于字符串列表給出元素的playbook示例:
- hosts: websrvs
remote_user: root
tasks:
- name: install packages
yum: name={{ item }} state=latest # 注意這里循環(huán)的用法 item是固定的名稱
with_items:
- httpd # 以- 開頭的每一行內(nèi)容都會被認(rèn)為是一個(gè)item,下面的基于字典也如此
- php
- php-mysql
- php-mbstring
- php-gd
基于字典列表給元素的playbook示例
- hosts: all
remote_user: root
tasks:
- name: create groups
group: name={{ item }} state=present
with_items:
- groupx1
- groupx2
- groupx3
- name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- {name: 'userx1', group: 'groupx1'}
- {name: 'userx2', group: 'groupx2'}
- {name: 'userx3', group: 'groupx3'}
角色: roles懈贺,以特定的層級目錄結(jié)構(gòu)進(jìn)行組織的tasks经窖、variables、handlers梭灿、templates画侣、files等。/etc/ansible/roles/目錄為默認(rèn)的角色目錄
role_name/
files/: 存儲由copy或script等模塊調(diào)用的文件
tasks/: 此目錄中至少應(yīng)該有一個(gè)名為main.yml的文件堡妒,用于定義各task配乱;其它的文件需要由main.yml進(jìn)行“包含”調(diào)用
handlers/: 此目錄中至少應(yīng)該有一個(gè)名為main.yml的文件,用于定義各handler皮迟;其它的文件需要由main.yml進(jìn)行“包含”調(diào)用
vars/: 此目錄中至少應(yīng)該有一個(gè)名為main.yml的文件搬泥,用于定義各variable;其它的文件需要由main.yml進(jìn)行“包含”調(diào)用
templates/: 存儲由template模塊調(diào)用的模板文本
meta/: 此目錄中至少應(yīng)該有一個(gè)名為main.yml的文件万栅,定義當(dāng)前角色的特殊設(shè)定及其依賴關(guān)系佑钾;其它的文件需要由main.yml進(jìn)行“包含”調(diào)用
default/: 此目錄中至少應(yīng)該有一個(gè)名為main.yml的文件,用于設(shè)定默認(rèn)變量
下面截圖部分為使用角色的一個(gè)小實(shí)例:
最后
在playbook中調(diào)用角色的方法烦粒,編輯一個(gè)調(diào)用role的yaml文件:ansible-playbook nginx.yml
- hosts: webservers
remote_user: root
roles:
- nginx # 這里即可調(diào)用上面截圖部分創(chuàng)建的nginx角色了
- ROLE2 # 另一種方法休溶,傳遞變量給role
- { role: nginx, nginxport: 8080, ...}
- { role: ROLE4, when: CONDITION }
實(shí)戰(zhàn)作業(yè):
(1) 主/備模型的keepalived+nginx;
(2) httpd+php+php-mysql;
(3) mysql-server或mariadb-server;
擁有testdb庫扰她,并允許testuser對其擁有所有權(quán)限兽掰;