運維工做:系統安裝(物理機、虛擬機)--> 程序包安裝、配置、服務啓動 --> 批量操做 --> 程序發佈 --> 監控php
穩定可用 ------- 標準化 --------- 自動化python
系統安裝:nginx
一、物理機:PXE、Cobblerweb
二、虛擬機:Image Templatesshell
程序配置Configration:編程
一、puppet (ruby語言研發)vim
二、saltstack (python語言研發)ruby
三、chefbash
四、cfengine數據結構
五、ansible
批量操做Command and Control:
一、fabric(python語言研發)
二、func
三、ansible
程序發佈:
一、人工智能(手動發佈)
二、腳本
三、發佈程序(運維程序)
程序發佈的標準要求:
一、不能影響用戶體驗;
二、系統不能停機;
三、不能致使系統故障或形成系統徹底不可用;
發佈路徑:
/webapps/tuangou
/webapps/tuangou-1.1
/webapps/tuangou-1.2
灰度模型:
主機
用戶
在調度器上下線一批主機(標記爲維護模式) ----- 關閉服務 ------ 部署新版本 ------- 啓動服務 ------- 在調度器上啓用這一批主機;
運維工具的分類:
一、agent:puppet,func
二、agentless(ssh):ansible、fabric
ansible:能夠實現系統安裝(研發中)、程序配置、批量操做、發佈程序(需自定義)
模塊化,調用特定的模塊,完成特定的任務;
基於Python語言實現,由Paramiko、PyYAML和Jinja2三個關鍵模塊;
部署簡單,agentless;
主從模式;
支持自定義模塊;
支持Playbook;
冪等性;執行一次跟屢次結果一致;
安裝ansible:epel,ansible
配置文件:/etc/ansible/ansible.cfg
主機清單:/etc/ansible/hosts
主程序:
ansible
ansible-playbook
ansible-doc
ansible的簡單使用格式:
ansible HOST-PATTERN -f forks -m MOD_NAME -a MOD_ARGS
使用前提:
一、各節點先寫入/etc/ansible/hosts裏
二、各節點基於ssh密鑰認證通訊
控制端(即ansible主機)
# ssh-keygen -t rsa -P ''
# ssh-copy-id -i ~/.ssh/id_rsa.pub root@各節點
經常使用模塊:
獲取模塊列表:ansible-doc -l
獲取指定模塊的幫助:ansible-doc -s MOD_NAME
一、command模塊:在遠程主機運行命令;
二、shell模塊:在遠程主機在shell進程下運行命令,支持shell特性,例如管道、重定向等;
三、copy模塊:複製ansible主機的文件到各遠程節點;
用法:
(1)src= dest=
(2)content= dest=
owner,group,mode
四、cron模塊:管理各遠程節點的cron任務;
用法:
name= job= state=present(建立)|absent(刪除)
minute,hour,day,month,weekday,user
五、fetch模塊:從各遠程節點拉取文件到ansible本機;
六、file模塊:設定遠程各節點的文件屬性;
用法:
(1)建立連接文件:path= src= state=link
(2)修改屬性:path= owner= group= mode=
(3)建立目錄:path= state=directory
七、hostname模塊:管理遠程各節點主機名
八、pip模塊:安裝遠程各節點的python所需的庫
九、yum模塊:管理各節點的yum程序;
name=:程序包名,能夠帶版本號;
state=:安裝(present|lastest),卸載(absent);
十、service模塊:管理遠程各節點的服務
name=:
state=:started啓動,stopped中止,restarted重啓
enabled=0|1:開機是否啓動
runlevel=
十一、ping模塊:ping遠程各節點;
十二、user模塊:管理遠程各節點的用戶
name=
system=yes|no
uid=
shell=
state=present|absent
home=:家目錄
group=:基本組
groups=:額外組
remove:刪除用戶,同時刪除家目錄
1三、uri模塊:訪問遠程各節點的http|https服務
1四、setup模塊:收集遠程各節點的facts信息;
1五、group模塊:添加或刪除組
name=
state=present|absent
gid=
system=:是否系統組
1六、script模塊:把一個本地script傳遞到遠程各節點執行
-a 「/path/to/script_file」
1七、template模塊:基於模板方式生成一個文件複製到遠程主機
src=
dest=
YAML語法:YAML的語法和其餘高階語言相似,而且能夠簡單表達清單、散列表、標量等數據結構。其結構(Structure)經過空格來展現,序列(Sequence)裏的項用"-"來表明,Map裏的鍵值對用":"分隔。下面是一個示例。
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female
YAML文件擴展名一般爲.yaml,如example.yaml。
playbook的核心元素:
hosts:
tasks: 任務
variables: 變量
templates: 模板(包含了模版語法的文本文件)
handlers: 處理器(由特定條件觸發的任務)
roles: 角色
案例:
heartbeat.yaml
- hosts: hbhosts
remote_user: root
tasks:
- name: ensure heartbeat latest version
yum: name=heartbeat state=present
- name: authkeys configure file
copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
- name: authkeys mode 600
file: path=/etc/ha.d/authkeys mode=600
notify:
- restart heartbeat
- name: ha.cf configure file
copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
notify:
- restart heartbeat
handlers:
- name: restart heartbeat
service: name=heartbeat state=restarted
playbook的基礎組件:
hosts:運行指定任務的目標主機;
remote_user:在遠程主機上執行任務的用戶;
sudo_user:在須要用到sudo時指定的用戶;
tasks:任務列表,自上而下
(1)action:module arguments
(2)module:arguments
注意:shell和command模塊後面直接跟命令,而非key=value類的參數列表
handlers:任務,在特定條件下觸發,接收到其餘任務的通知時被觸發;
(1)某任務的狀態在運行後爲changed時,可經過「notify」通知給相應的handlers;
(2)任務能夠經過「tags」打標籤,然後在ansible-playbook命令上使用-t指定進行調用;
運行playbook的方式:
(1)測試
ansible-playbook --check:只檢測可能發生的改變,但不真正執行操做;
ansible-playbook --list-hosts:列出運行任務的主機;
(2)運行
variables: 變量;調用 {{ variable }}
一、facts:setup模塊提供的;可直接調用
二、ansible-playbook命令的自定義變量:經過雙括號進行調用:{{ 變量名 }};
三、經過roles傳遞變量;
四、Host Incentory:
(1)向不一樣的主機傳遞不一樣的變量;在/etc/ansible/hosts文件下,IP/HOSTNAME variable=value var2=value2
(b)向組中的主機傳遞相同的變量;在/etc/ansible/hosts文件下,[groupname:vars] var=value
在playbook中定義變量的方法:
vars:
- var1: value1
- var2: value2
inventory參數:用於定義ansible遠程鏈接目標主機時使用的參數,而非傳遞給playbook的變量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
模板:templates;文本文件,嵌套有腳本(使用模板編程語言編寫)
jinjar2:
一、字面量:
(1)字符串:使用單引號或雙引號;
(2)數值:整數,浮點數;
(3)列表:[item1,item2];
(4)元組:(item1,item2);
(5)字典:{key1:value1,key2:value2,...};
(6)布爾型:true|false
二、算術運行:
+,-,*,/,//,%,**
三、比較操做:
==,!=,>,>=,<,<=
四、邏輯運算:
and,or,not
案例:nginx.yaml:在websrvs組安裝nginx,並根據模板nginx.j2,啓動nginx服務;
# vim nginx.yaml
其中nginx.j2 傳遞了2個變量
worker_processes {{ ansible_processor_vcpus-1 }}; #由setup模塊提供的變量;
listen {{ http_port }} default_server;
http_port變量是由/etc/ansible/hosts文件傳遞;以下
條件測試:
when語句:在tasks中使用,jinja2的語法格式;
在tasks後添加when子句便可使用條件測試;when語句支持jinja2表達式語法。例如:
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "Debian"
循環:迭代,須要重複執行的任務;
對迭代項的引用,固定變量名爲「item」;然後在tasks中,使用with_items給定要迭代的元素列表;a、字符串,二、字典
a、例如:
- name: install some package
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
b、例如
- name: add some group
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: add some users
user:name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: "user1" group: "group1" }
- { name: "user2" group: "group2" }
- { name: "user3" group: "group3" }
角色roles:roles就是經過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並能夠便捷地include它們的一種機制。角色通常用於基於主機構建服務的場景中,但也能夠是用於構建守護進程等場景中。
roles模塊的路徑能夠在配置文件/etc/ansible/ansible.cfg裏roles_path定義.
1
2
|
vim
/etc/ansible/ansible
.cfg
roles_path =
/etc/ansible/roles
:
/usr/share/ansible/roles
|
role內各目錄中可用的文件:
tasks目錄:至少應該包含一個名爲main.yml的文件,其定義了此角色的任務列表;其餘的文件須要在此文件中經過include進行包含;
files目錄:存放由copy或script等模塊調用的文件;
templates目錄:template模塊查找所須要模板文件的目錄;
handlers目錄:至少應該包含一個名爲main.yml的文件,用於定義此角色用到的各handler;在handler中使用include包含的其它的handler文件也應該位於此目錄中;
vars目錄:至少應該包含一個名爲main.yml的文件,用於定義此角色用到的變量;
meta目錄:至少應該包含一個名爲main.yml的文件,用於定義此角色的特殊設定及其依賴關係;ansible 1.3及其之後的版本才支持;
default目錄:爲當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;
建立role的步驟
(1) 建立以roles命名的目錄;
(2) 在roles目錄中分別建立以各角色名稱命名的目錄,如webservers等;
(3) 在每一個角色命名的目錄中分別建立files、handlers、meta、tasks、templates和vars目錄;用不到的目錄能夠建立爲空目錄,也能夠不建立;
(4) 在playbook文件中,調用各角色;
示例:建立nginx角色
#設置任務文件,注意,配置模板文件的src使用相對路徑便可,目錄的相對路徑是:/usr/share/ansible/roles/nginx/templates/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
vim
/usr/share/ansible/roles/nginx/tasks/main
.yml
- name:
install
nginx package
yum: name=nginx state=latest
- name: copy nginx conf
file
tempalte: src=web.conf.j2 dest=
/etc/nginx/conf
.d
/web
.conf
notify: reload nginx
tags: cpfile
- name: create docroot
dir
file
: path={{ ngx_doc_root }} state=directory
tags: cpfile
- name: start nginx service
service: name=nginx enabled=
true
state=started
#設置變量,在vars目錄下定義變量,變量不須要橫杆引導
vim
/usr/share/ansible/roles/nginx/vars/main
.yml
ngx_port: 8888
ngx_server_name: www.sunny.com
ngx_doc_root:
/webdata
#設置觸發後執行的操做
vim
/usr/share/ansible/roles/nginx/handlers/main
.yml
- name: reload nginx
service: name=nginx state=reloaded
#設置模板文件
vim
/usr/share/ansible/roles/nginx/templates/web
.conf.j2
server {
listen {{ ngx_port }};
server_name {{ ngx_server_name }};
location / {
root {{ ngx_doc_root }};
}
}
|
#調用模塊
1
2
3
4
5
|
vim
/root/ansible/nginxrole
.yml
- hosts: dbsrvs
remote_user: root
roles:
- nginx
|
測試模塊
1
|
ansible-playbook -C
/root/ansible/nginxrole
.yml
|
注意,因爲測試沒有實際安裝nginx模塊,所以測試時,啓動服務會失敗
執行模塊
1
|
ansible-playbook
/root/ansible/nginxrole
.yml
|
執行tag cpfile對應的代碼,若是文件web.conf.j2 發生變化,包括定義變量的文件發送變化,就會從新服務該文件到對應機器,同時,notify生效,重啓nginx服務
1
|
ansible-playbook -t cpfile
/root/ansible/nginxrole
.yml
|
在執行命令中執行變量,注意,命令裏的變量優先級比配置再模塊vars下的優先級高
1
|
ansible-playbook -t cpfile -e
"ngx_port=8899"
/root/ansible/nginxrole
.yml
|
在playbook調用角色方法1:
- hosts: websrvs
remote_user: root
roles:
- nginx
- memcached
在playbook調用角色方法2:傳遞變量給角色
- hosts: websrvs
remote_user: root
roles:
- { role: nginx, username: nginx } 鍵role用於指定角色名稱,後續的K/V用於傳遞變量給角色
還能夠基於條件測試實現角色調用3;
roles:
- { role: nginx, when: ansible_distribution_major_version == '7' }
參考文檔:www.ansible.com.cn