一. Ansible
Configuration、Command and Control
SSH-based configuration management, deployment, and task execution system
運維工具的分類:
agent:基于專用的agent程序完成管理功能,puppet, func, zabbix,salkstack
agentless:基于ssh服務完成管理,ansible, fabric, …
1. 架構:
Ansible Core
Modules:
Core Modules
Customed Modules #自定義模塊,可二次開發導入使用
Host Iventory #受控主機列表
Files
CMDB :client managment database
PlayBooks
Hosts
roles
Connection Plugins: #連接插件
2. 特性:
模塊化:調用特定的模塊,完成特定的任務;
基于Python語言研發,由Paramiko, PyYAML和Jinja2三個核心庫實現;
部署簡單:agentless;
支持自定義模塊,使用任意編程語言;
強大的playbook機制;
冪等性; 即一個命令,即使執行一次或多次, 其結果也一樣
3. 安裝及程序環境:
注意: ansible 依賴python環境,因此介意使用yum 來安裝
程序:
ansible
ansible-playbook
ansible-doc #幫助文檔
(CentOS 6 中,只需安裝ansible 一個包即可)
配置文件:
/etc/ansible/ansible.cfg
主機清單:
/etc/ansible/hosts
插件目錄:
/usr/share/ansible_plugins/
4. ssh連接支持
建議私鑰連接:
創建監控端公鑰
ssh-keygen -t rsa -P ''
復制公鑰到制定被控主機:
ssh-copy-id ip /root/.ssh/id_rsa.pub
============================================================
二. 基本使用入門
1.ansible命令:
Usage: ansible <host-pattern> [options]
常用選項:
-m MOD_NAME(模塊) -a "MOD_ARGS" (傳遞參數,需要加引號)
ansible 使用幫助:
ansible -h
2. 配置Host Inventory: #主機清單; 若不用主機清單,則需要直接使用IP地址
/etc/ansible/hosts
#直接添加主機
#添加主機范圍:
## www[001:006].example.com
#即用001–006號主機
#創建群組
[group_id]
HOST_PATTERN1
HOST_PATTERN2
eg:
[websrvs]
10.1.252.4
10.1.232.2
補充:
ansible all …. 代表全部主機
3. 模塊使用:
獲取模塊列表:ansible-doc -l
獲取指定模塊的使用幫助:ansible-doc -s MOD_NAME
注意: -a 選項后的參數,涉及空格的項,注意要用引號引起:
eg:
ansible all -m cron -a "minu='*/5 ' job='/usr/sbin/ntpdate 10.1.0.1' "
常用模塊:
1) ping:探測目標主機是否存活;
eg:
ansible all -m ping
2) command:在遠程主機執行命令;:(注意,此命令無法識別管道命令)
eg:
ansible all -m command -a "useradd centos"
3) shell:在遠程主機上調用shell解釋器運行命令,支持shell的各種功能,例如管道等 ;
注意:command和shell模塊的核心參數直接為命令本身;而其它模塊的參數通常
為“key=value”格式;
4). copy: C o p i e s f i l e s t o r e m o t e l o c a t i o n s .
用法:
(1) 復制文件
-a "src= dest= "
#從本地主機復制到遠程主機
[root@localhost test]# ansible webs -m copy -a "src=/test/1111 dest=/test/"
(2) 給定內容生成文件
-a "content= dest= "
#在遠程主機上生成制定內容的文件
其它參數:mode, owner, group, …
eg:
ansible webs -m copy -a "content=1ddfd111 dest=/test/2222"
5) . file:S e t s a t t r i b u t e s o f f i l e s
用法:
(1) 創建目錄:
-a "path= state=directory"
(2) 創建鏈接文件:
-a "path= src= state=link"
(3) 刪除文件:
-a "path= state=absent“
4) 另還有額外配置項: owner ,group 等,可以指定文件屬性
eg:
ansible all -m file -a "path=/test/2222 owner=centos"
6) fetch:F e t c h e s a f i l e f r o m r e m o t e n o d e s
#從遠程主機上復制文件到本地
格式示例:
ansible all -m fetch -a "dest=/###/@@@ src=/test/"
7) .cron:M a n a g e c r o n . d a n d c r o n t a b e n t r i e s .
#周期性任務管理
-a "":
minute=
hour=
day=
month=
weekday=
job=
name=
user=
state={present|absent}
eg:
ansible all -m cron -a "minu='*/5 ' job='/usr/sbin/ntpdate 10.1.0.1' "
8). hostname:M a n a g e h o s t n a m e
-a "name=host_name"
eg:
[root@localhost test]# ansible 10.1.252.59 -m hostname -a
"name=node1111"
10.1.252.59 | SUCCESS => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "node1111",
"ansible_hostname": "node1111",
"ansible_nodename": "node1111"
},
"changed": true,
"name": "node1111"
}
9). yum:M a n a g e s p a c k a g e s w i t h t h e I ( y u m ) p a c k a g e
m a n a g e r
備注: 另有其他選項,請自行查看幫助
注意: client 上的yum源需要先配置好
-a " ":
(1) name=soft_name state={present|latest} #安裝
(2) name=soft_name state=absent #卸載
eg:
ansible webs -m yum -a "name=httpd state=latest"
#安裝httpd 程序
10) service:M a n a g e s e r v i c e s .
-a ""
name= #程序名
state=
started
stopped
restarted
enabled= true | false
#開機啟動
runlevel=# # 設置啟動級別
eg:
ansible webs -m service -a "name=httpd state=restarted enabled"
11 ) group: A d d o r r e m o v e g r o u p s
-a ""
name=
state=present | absent
system=yes|no # 設置為系統組
gid=##
12) user:M a n a g e u s e r a c c o u n t s
-a ""
name=
group= #同名組(基本組)
groups= #將用戶加入多個組(附加組)
comment= #用戶注釋信息
uid=
system= yes|no (true|false) #設置為系統用戶
shell=
expires= #指定用于過期時間
home= #指定用戶家目錄
13) setup:G a t h e r s f a c t s a b o u t r e m o t e h o s t s
#用于獲取client的各種屬性信息
eg:
[root@localhost ~]# ansible webs -m setup
10.1.252.218 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.122.1",
"10.1.48.2",
"10.1.252.218"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe41:1e55"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "07/02/2015",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-327.el7.x86_64",
"LANG": "en_US.UTF-8",
"quiet": true,
"rhgb": true,
"ro": true,
"root": "UUID=795056d7-a4e5-43eb-b4df-4681d61acbfe"
},
"ansible_date_time": {
"date": "2016-11-04",
"day": "04",
"epoch": "1478262632",
"hour": "20",
"iso8601": "2016-11-04T12:30:32Z",
"iso8601_basic": "20161104T203032309415",
"iso8601_basic_short": "20161104T203032",
"iso8601_micro": "2016-11-04T12:30:32.309575Z",
"minute": "30",
"month": "11",
"second": "32",
"time": "20:30:32",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Friday",
"weekday_number": "5",
"weeknumber": "44",
"year": "2016"
},
…………
===========================================================
三.playbook
#用于實現將client 配置同一寫入文件,并一鍵運行
1. YAML:(ansible client配置文件的格式,python中常使用的模板語言)
YAML is a data serialization format designed for human readability and
interaction with scripting languages.
數據結構:
鍵值對:
key:value
列表:(以"-"為開頭引導的)
– item1
– item2
– item3
字典:
{name:jerry, age:21}
2. PlayBook:
1) 文件格式:
file_name.yaml 或者 file_name.yml
2) 幫助:
ansible-playbook -h
3) 核心元素:
Tasks:任務,由模塊定義的操作的列表;
Variables:變量
Templates:模板,即使用了模板語法的文本文件;
Handlers:由特定條件notify觸發的Tasks;
Roles:角色;
notify: 觸發條件, 放于tasks 中,用于當指定任務發生時促發handlers
4) playbook的基礎組件:
Hosts:運行指定任務的目標主機;
remote_user:在遠程主機以哪個用戶身份執行;
sudo_user:非管理員需要擁有sudo權限;
tasks:任務列表
模塊,模塊參數:
格式:
(1) action: module arguments
(2) module: arguments
5) 常用格式:
注意:yaml內容格式有嚴格固定,縮進只能用一個空格
格式示例:
– hosts: #"-"需頂格,后接一個空格
remote_user: ## #首部為兩個空格,remote與hosts對齊
tasks: #tasks 與remote對齊
– name: task_name1 #任務1 #"-"需要與name與tasks對齊
mod_name : name= ## …
– name: task_name2 #任務2
mod_name: name=###
語法以及格式測試:
ansible-playbook –syntax-check /path/to/playbook.yaml
———————————————————————
示例1:
vim group.yml:
– hosts: all #對all 主機執行的task
remote_user: root
tasks:
– name: install a group #任務1
group: name=mygrp system=true
#調用group 模塊
– name: install a user #任務2
user: name=user1 group=mygrp system=true
#調用user模塊
– hosts: websrvs #對 websrvs 組主機需要執行的task
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd
– name: start httpd service
service: name=httpd state=started
– ———————————————————————————–
6) 運行playbook,使用ansible-playbook命令
(1) 檢測語法(僅做語法檢測,不測試運行)
ansible-playbook –syntax-check /path/to/playbook.yaml
(2) 測試運行
ansible-playbook /path/to/playbook.yaml
-C ,–check 測試運行
–check
–list-hosts
–list-tasks
–list-tags
注意:–check時候,有些報錯不一定是真實錯誤,部分操作需要真實執行后才
能進行的任務,在測試執行時候也會報錯
eg:
ansible-playbook -C | –check /test.yaml
(3) 運行
ansible-playbook /path/to/playbook.yaml
-t TAGS, –tags=TAGS #指定需要運行的標簽對應的任務
–skip-tags=SKIP_TAGS #跳過對應標簽的的任務
–start-at-task=START_AT
7) handlers:由特定條件觸發的Tasks;
調用及定義方式:
tasks:
– name: TASK_NAME
module: arguments
notify: HANDLER_NAME #觸發條件
?。V挥性趯膖asks中添加了notify ,才能觸發后續對應的handlers
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
# 當執行了name: install conf file 此名稱的任務時,會觸發handlers的任務
8) tags:給指定的任務定義一個調用標識;
– name: NAME
module: arguments
tags: TAG_ID
eg:
– name: install httpd package
yum: name=httpd state=latest
tags: install
– name: restart httpd service
service: name=httpd state=restarted
tags: restart
執行時:
ansible-playbook -t install,restart web.yaml
9) Variables:
變量調用:
{{ var_name }}
類型:
內建:
(1) facts
自定義:
(1) 命令行傳遞;
-e VAR=VALUE
#直接在yaml文件中定義變量,并在執行時,在命令行直接傳遞變量
eg:
vim test.yaml:
– hosts: all
remote_name: root
tasks:
– name: install a package
yum: name= {{ pkgname }} state=present
執行并傳遞變量值:
ansible-playbook -e pkgname=httpd test.yaml
(2) 在hosts Inventory中為每個主機定義專用變量值;
# 在/etc/ansible/hosts中,直接給對應主機賦予變量
(a) 向不同的主機傳遞不同的變量 ;
IP/HOSTNAME variable_name=value
eg:
[websrvs]
10.1.252,.1 pkgname=httpd
10.1.252.2 pkgname=nginx
(b) 向組內的所有主機傳遞相同的變量 ;
[groupname:vars]
variable_name=value
eg:
[srvs]
10.1.1.1
10.1.1.2
[srvs:vars]
pkgname=httpd
(3) 在playbook中定義
vars:
– var_name: value
– var_name: value
注意: 如果此時命令行也用-e 給出指定變量的值,則-e 的優先級高,變量
引用-e 的值
eg:
vim test.yaml:
– hosts: all
remote_name: root
vars:
– pkgname: httpd
– pkgname2: vsftpd
tasks:
– name: install a package
yum: name= {{ pkgname }} state=present
– name: uninstall a package
yum: name= {{ pkgname2 }} state=absent
(4) Inventory還可以使用參數:
(直接在/ets/ansible/hosts中傳遞)
用于定義ansible遠程連接目標主機時使用的屬性,而非傳遞給
playbook的變量 ;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
eg:
[websrvs]
10.1.0.1 ansible_ssh_port=2222
10.1.0.2 ansible_ssh_user=centos ……
(5) 在角色調用時傳遞
roles:
– { role: ROLE_NAME, var: value, …}
eg:
某個執行調用roles 的.yaml文件,對某個指定的角色傳遞指定變量
– hosts: all
remote_user: root
roules:
– { role: nginx, nginx_port: 8080 }
10) Templates:模板 (使用jinja2語言編寫) (僅能在playbook中使用)
文本文件,內部嵌套有模板語言腳本(使用模板語言編寫)
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.
(1)作 用: 執行模板文件中的腳本,并生成結果數據流,需要使用template模塊;
即,作用類似于copy, 但是可以將文件中包含的變量等,轉化為對應值,
查看可以使用的 內建的鍵 可以使用ansilbe host_name -m setup 來查看含有的鍵
eg:
修改nginx.conf 中的
work_processes {{ ansible_processor_vcpus }}
只有使用template模塊傳遞nginx.conf 文件時候,才會將 ansible_processor_vcpus
解析為對應主機上硬件的值
詳細使用,見下方示例處
(2)template:
-a ”“
src=
dest=
mode=
onwer=
group=
注意:此模板不能在命令行使用,而只能用于playbook;
(3)語法:
文件后綴: .j2
字面量:
字符串:使用單引號或雙引號;
數字:整數、浮點數;
列表:[item1, item2, …]
元組:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布爾型:true/false
算術運算:
+, -, *, /, //, %, **
比較操作:
==, !=, >, <, >=, <=
邏輯運算:and, or, not
————————————————————————————-
(4)示例:
vim nginx.yaml:
– 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"
————————————————————————–
(5)條件測試:
when語句:在tasks中使用,Jinja2的語法格式;
可以直接使用內置變量(即 -m setup 中顯示的)
– 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"
– name: start nginx service
shell: "systemctl start nginx.service"
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7"
(6)循環:迭代,需要重復執行的任務;
對迭代項的引用,固定變量名為"item”,使用with_items屬性給定要迭代的元素;
元素:列表
字符串
字典
基于字符串列表給出元素示例:
– hosts: websrvs
remote_user: root
tasks:
– name: install packages
yum: name={{ item }} state=latest
with_items:
– httpd
– php
– php-mysql
– php-mbstring
– php-gd
基于字典列表給元素示例:
– 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'}
==========================================================
11) 角色:roles
以特定的層級目錄結構進行組織的tasks、variables、handlers、templates、files等;
即將原本一個yaml文件中定義的各項內容,拆分到至指定的位置,調用時再組合起來,
此方式對調用更為靈活
#各文件一般位于/etc/ansible/roles 目錄, ansible-playbook會自行前往該目錄查找
若需要重新定義,則在ansible的配置文件修改即可
( role_name 即為指定角色的名字,如nginx ,與nginx 相關的配置均放于此文件夾中)
role_name/
files/:存儲由copy或script等模塊調用的文件;
tasks/:此目錄中至少應該有一個名為main.yml的文件,用于定義各task;
其它的文件需要由main.yml進行“包含”調用;
handlers/:此目錄中至少應該有一個名為main.yml的文件,用于定義各
handler;其它的文件需要由main.yml進行“包含”調用;
vars/:此目錄中至少應該有一個名為main.yml的文件,用于定義各
variable;其它的文件需要由main.yml進行“包含”調用;
templates/:存儲由template模塊調用的模板文本;
meta/:此目錄中至少應該有一個名為main.yml的文件,定義當前角色的特
殊設定及其依賴關系;其它的文件需要由main.yml進行“包含”調用;
default/:此目錄中至少應該有一個名為main.yml的文件,用于設定默認變
量;
在playbook中調用角色的方法:
– hosts: HOSTS
remote_user: USERNAME
roles:
– ROLE1
– ROLE2
– { role: ROLE3, VARIABLE: VALUE, …}
– { role: ROLE4, when: CONDITION }
示例:
1. mkdir -pv /etc/ansible/roles/ngixn/{files,template,vars,handlers,meta,default,tasks}
2. vim …./nginx/tasks/main.yaml:
– name: install nginx
yum: name=nginx state=present
– name: install conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
#指定文件放于對應模塊的文件夾后,就不需要使用絕對路徑
tags: ngxconf
notify: reload conf
– name: start nginx service
service: name=nginx state=started enabled=true
3. vim …./nginx/handlers/main.yaml
#補充定義tasks中notify: reload conf 指定的handlers
– name: reload nginx service
service: name=nginx state=restarted
4. cp /etc/nginx/nginx.conf /etc/ansible/roles/nginx/template/nginx.conf.j2
同時,修改nginx.conf.j2 中的:
Listen 80 —–> Listen {{ nginx_port }}
work_processes auto ; ——> work_processes {{ ansible_processor_vcpus }};
5. vim …./nginx/vars/main.yaml
– nginx_port: '8080'
6. #role調用:
vim /etc/ansible/nginx.yaml
– hosts: webs
remote_user: root
roles:
– nginx #此名稱需要與/etc/ansible/roles下定義的文件夾名稱一致
7. 執行:
ansible-playbook xxxx.yaml 即可
==========================================================
博客作業:以上所有內容;
實戰作業:
(1) 主/備模型的keepalived+nginx;
(2) httpd+php+php-mysql;
(3) mysql-server或mariadb-server;
擁有testdb庫,并允許testuser對其擁有所有權限;
原創文章,作者:ldt195175108,如若轉載,請注明出處:http://www.www58058.com/60033