作為背鍋俠運維工作的基本流程
系統(tǒng)安裝(物理機(jī)践付、虛擬機(jī))-->程序包安裝、配置缺厉、服務(wù)啟動 --> 對主機(jī)批量操作 --> 程序版本更新 -->監(jiān)控
OS Provisioning:
物理機(jī):PXE永高、Cobbler
虛擬機(jī):Image、Templates
Configuration:
puppet工具(ruby開發(fā))
Saltstack(python開發(fā))
chef
Command and Concrol:
fabric
預(yù)發(fā)布環(huán)境驗證:
新版本的代碼先發(fā)布到內(nèi)網(wǎng)測試服務(wù)器(跟線上環(huán)境配置完全相同提针,只是未介入到調(diào)度器)命爬;
程序發(fā)布:
不能影響用戶體驗;
系統(tǒng)不能停機(jī)辐脖;
不能導(dǎo)致系統(tǒng)故障或造成系統(tǒng)完全不可用饲宛;
灰度發(fā)布:
一種發(fā)布模式;在調(diào)度器上下線一批主機(jī) --> 關(guān)閉服務(wù) --> 部署新版本的應(yīng)用程序 --> 啟動服務(wù) --> 在調(diào)度器上啟用這一批主機(jī)嗜价;
自動化灰度發(fā)布機(jī)制:可通過腳本或公司自己的發(fā)布平臺發(fā)布艇抠;
運維工具的分類 :
agent:代理工具:puppet,func
agentless:無代理工具:ansible久锥,fabric家淤;agentless類工具必須依賴ssh服務(wù);
ansible的模塊化:
模塊化:調(diào)用特定的模塊來完成特定的任務(wù)瑟由;
基于python語言實現(xiàn)絮重,由paramaiko、pyYAML和jinja2三個關(guān)鍵模塊
部署簡單:agentless類工具
主從模式:
支持自定義模塊:
支持playbook:
ansible密鑰登陸
ansible是通過ssh實現(xiàn)配置管理歹苦、應(yīng)用部署青伤、任務(wù)執(zhí)行等功能,因此殴瘦,需要事先配置ansible端能基于密鑰認(rèn)證的方式聯(lián)系各個被管理節(jié)點狠角;
ansible管理端做密鑰:ssh-keygen -t rsa -P ‘’
將密鑰拷貝到各個被控節(jié)點:ssh-copy-id root@192.168.4.41
ssh遠(yuǎn)程連接測試:ssh root@192.168.4.41 ##應(yīng)該不需要密碼就可以直接遠(yuǎn)程進(jìn)被控端
ansible安裝
## wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
## yum -y install ansible
配置文件:/etc/ansible/ansible.cfg
主機(jī)清單:/etc/ansible/hosts
ansible的簡單使用
1、修改/etc/ansible/hosts文件痴施,添加ansible被控主機(jī)或被控組擎厢;
##必須先在hosts文件添加主機(jī)ip,不然遠(yuǎn)程控制被控端時會報錯: [WARNING]: No hosts matched, nothing to do
2辣吃、執(zhí)行一個簡單的ansible命令:
在ansible控制端執(zhí)行:
ansible 192.168.4.41 -m command -a 'ifconfig'會顯示被控端的網(wǎng)卡信息
ansible常用模塊
可以使用‘a(chǎn)nsible-doc -s 模塊名 ’來查看模塊的詳細(xì)用法
ansible用法:ansible [-f forks] [-m module_name] [-a args]
user模塊:
示例:ansible test -m user -a 'name=wuyongfeng state=present system=yes'
在test組包含的被控端上創(chuàng)建用戶动遭,name為wuyongfeng;
state=present表示創(chuàng)建用戶神得,state=absent時表示刪除用戶厘惦;
system=yes表示創(chuàng)建系統(tǒng)用戶;
group模塊:
示例:ansible test -m group -a 'name =testgroup gid=111 state=present system=yes'
在test組包含的被控端上創(chuàng)建組testgroup;```
組id為111宵蕉;
state=present表示創(chuàng)建組酝静,state=absent時表示刪除組;
syste=yes表示創(chuàng)建系統(tǒng)組羡玛,system=no表示創(chuàng)建的不是系統(tǒng)組别智;
cron模塊:
示例:ansible test -m cron -a 'name="wuyongfeng crontab list" minute="*/20" job="/sbin/ntpdate 192.168.4.40 &>/dev/null"'
在test組包含的被控端添加任務(wù)計劃,每20分鐘向192.168.4.40同步時間稼稿,并把輸出丟如/dev/null薄榛;
name:計劃任務(wù)的描述信息;
minute:分鐘让歼;
job:要進(jìn)行的操作敞恋;
day:日(1-31,*谋右,*/2,……)硬猫;
hour:小時(0-23,*改执,*/2啸蜜,……);
month:月(1-12天梧,*盔性,*/2,……)呢岗;
weekday:周(0-7冕香,*,……)后豫;
user:以哪個用戶的身份執(zhí)行悉尾;
若要刪除之前在被控端部署的計劃任務(wù),只需指定name和state=absent即可挫酿;
例如:
ansible test -m cron -a 'name="wuyongfeng crontab list" state=absent'
copy模塊:
示例:ansible test -m copy -a 'src=/data/wyf.txt dest=/tmp/wyf.txt mode=600'
復(fù)制ansible控制端的wyf.txt文件到test組所指定的被控端的主機(jī)的/tmp目錄下
src:源路徑
dest:目標(biāo)路徑
mode:文件權(quán)限
file模塊:
專門用來設(shè)定文件屬性构眯;
ansible test -m file -a 'path=/tmp/www state=directory'
在test組定義的被控端的/tmp/下創(chuàng)建www目錄,state指定文件屬性為目錄
group:定義文件/目錄的屬組
mode:定義文件/目錄的權(quán)限
owner:定義文件/目錄的屬主
path:必選項早龟,定義文件/目錄的路徑
recurse:遞歸的設(shè)置文件的屬性惫霸,只對目錄有效
dest:被鏈接到的路徑,只應(yīng)用于state=link的情況
state:
=directory:如果目錄不存在葱弟,創(chuàng)建目錄
=file:即使文件不存在壹店,也不會被創(chuàng)建
=link:創(chuàng)建軟鏈接
=hard:創(chuàng)建硬鏈接
=touch:如果文件不存在,則會創(chuàng)建一個新的文件芝加,如果文件或目錄已存在硅卢,則更新其最后修改時間
=absent:刪除目錄、文件或者取消鏈接文件
ping模塊:
用于確認(rèn)和對象機(jī)器之間是否能夠ping通,正常情況會返回pong将塑;
示例:ansible test -m ping
ping test組定義的被控端脉顿;如果是可以通的則返回pong;
yum模塊:
示例:ansible test -m yum -a 'name=httpd state=present'
在test組的被控端yum安裝httpd点寥;
config_file:yum的配置文件
disable_gpg_check:關(guān)閉gpg_check
disablerepo:不啟用某個源
enablerepo:啟用某個源
name:要進(jìn)行操作的軟件包的名字艾疟,也可以傳遞一個url或者一個本地的rpm包的路徑
state:狀態(tài)(present安裝,absent卸載敢辩,latest最新的)
service模塊:
示例:ansible test -m service -a 'name=httpd state=started enabled=yes'
test組的所有被控端汉柒,啟動httpd服務(wù),開機(jī)啟動(enabled)
enabled:[yes/no] 啟動os后啟動對應(yīng)service的選項;是否開機(jī)啟動
name:需要進(jìn)行操作的service名字
state:[stared/stoped/restarted/reloaded] 服務(wù)最終操作后的狀態(tài)责鳍。
shell模塊:
示例:ansible test -m shell -a 'sh /date/1.sh chdir=/date/www creates=/date/www/1.txt'
執(zhí)行test組所有被控端,先切換到/date/www目錄兽间,如果/date/www/1.txt不存在历葛,則執(zhí)行/data/1.sh,
chdir:command一樣的嘀略,運行shell之前cd到某個目錄恤溶;
creates:跟command一樣的,如果某個文件存在則不運行shell帜羊;
removes:跟command一樣的咒程,如果某個文件不存在則不運行shell;
script模塊:
可以實現(xiàn)被控端上可以執(zhí)行ansible控制端的腳本讼育。
示例:ansible test -m script -a '/4.40/www/2.sh'
在test組所有被控端執(zhí)行ansible控制端中/4.40./www/目錄下的2.sh
setup模塊:
用于收集遠(yuǎn)程主機(jī)的一些基本信息帐姻。
示例:ansible test -m setup
收集test組所有主機(jī)的基本信息
Ansible Playbooks
playbook的核心元素:
Tasks:任務(wù)
Variables:變量
Templates:模板
Handlers:處理器
Roles:角色
ansible --yaml語法
一:介紹:
YAML是一個可讀性高的用來表達(dá)資料序列的格式。YAML參考了其他多種語言,包括:XML奶段、C語言饥瓷、 Python、Perl等痹籍。
YAML不是XML呢铆,不過,在開發(fā)的這種語言時蹲缠,YAML的意思其實是:“Yet Another Makup Language”(仍是一種標(biāo)記語言)
特點:
1棺克、可讀性好
2、和腳本的交互性好
3线定、使用實現(xiàn)怨言的數(shù)據(jù)類型
4娜谊、有一個一致的信息模型
5、易于實現(xiàn)渔肩。
6因俐、可以基于流來處理。
7、表達(dá)能力強(qiáng)抹剩,擴(kuò)展性好撑帖。
二:yaml語法
yaml的語法和其他高階語言類似,并且可以簡單表達(dá)清單澳眷,散列表胡嘿,標(biāo)量等數(shù)據(jù)結(jié)構(gòu),其結(jié)構(gòu)通過空格來展示钳踊,序列里的項目用“-”來表示衷敌,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:14
gender:female
列表: 也叫做序列
列表中的所有元素都用“-”打頭拓瞪,例如:
- apple
- orange
- mango
字典:
字典通過key與value進(jìn)行標(biāo)識缴罗,例如:
name:example developer
job:developer
skill:elite
也可以將key:value放置與{}中表示,例如:
{name:example developer祭埂,job:developer面氓,skill:elite}
Ansible基礎(chǔ)元素
1.變量
1.1 變量命名
變量名僅能由字母,數(shù)字和下劃線組成蛆橡,且只能以字母開頭
1.2 facts
facts是由正在通信的遠(yuǎn)程目標(biāo)主機(jī)返回的信息舌界,這些信息能保存在ansible變量中,要獲取指定的遠(yuǎn)程主機(jī)所支持的素有的facts泰演,可使用如下命令進(jìn)行
#ansible hostname -m setup
1.3 register
注冊器:把任務(wù)的輸出定義為變量呻拌,然后用于其他任務(wù),示例如下:
tasks:
- shell:/usr/bin/foo
register:foo_result
ignore_errors:True
1.4 通過命令行傳遞變量
在運行playbooks的時候也可以傳遞一些變量供playboo使用:示例如下:
ansible-playbook test.yml --extra-vars"hosts=www user=mageedu"
1.5 通過roles傳遞變量
當(dāng)給一個主機(jī)應(yīng)用角色的時候可以傳遞變量睦焕,然后在角色內(nèi)使用這些變量藐握,示例如下:
- hosts:webservers
roles:
- common
- { roles:foo_app_instance,dir:'/web/htdocs/a.com',port 8000 }
2.Inventory
ansible的主要功用在于批量主機(jī)操作垃喊,為了便捷地使用其中的部分主機(jī)趾娃,可以在inventory file中將其分組命名,默認(rèn)的inventory file為/etc/ansible/hosts
Inventory file可以有多個缔御,且也可以通過Dynamic Inventory動態(tài)生成抬闷;
2.1 Inventory文件格式
Inventory文件INI文件風(fēng)格,中括號中的字符為組名耕突,可以將同一個主機(jī)分配到多個不同的組笤成,此外妓灌,當(dāng)被控制的主機(jī)使用了非默認(rèn)的ssh 22端口時甜孤,還可以在主機(jī)ip或主機(jī)名之后使用冒號加端口號標(biāo)明惯殊;示例:
[webservers] ##被控組組名
192.168.1.100 ##使用ip添加被控端主機(jī)
www.erlang.com:222 ##如果被控端沒有使用默認(rèn)的ssh端口逼裆,可用冒號加端口號注明
如果主機(jī)名稱遵循相似的命名格式,還可以使用列表的方式標(biāo)識主機(jī)橡庞,示例:
[webservers]
www[1:50].example.com ##表示www1.example.com-www50.example.com的主機(jī)
2.2 主機(jī)變量
可以在Inventory中定義主機(jī)時為其添加主機(jī)變量以便于在playbook中使用挪丢,例如:
[webservers]
www1.erlang.com http_port-80 maxRequestsPerChild-808
www2.erlang.com http_port-8080 maxRequestsPerChild-909
2.3 組變量
組變量是指賦予給指定組內(nèi)所有主機(jī)上的在playbook中可用的變量捐迫,例如:
[webservers]
www1.erlang.com
www2.erlang.com
[webservers:vars] :vars是固定寫法,指定下邊兩行都可以分別對應(yīng)給webservers組的兩臺主機(jī)
ntp_server-ntp.erlang.com
nfs_server-nfs.erlang.com
2.4 組嵌套
Inventory中籽腕,組還可以包含其他的組嗡呼,并且也可以向組中的主機(jī)指定變量,不過皇耗,這些變量只能在ansible-playbook中使用南窗,而ansible不支持,例如:
[apache]
httpd1.erlang.com
httpd2.erlang.com
[nginx]
nginx1.erlang.com
nginx2.erlang.com
[webservers:children] webservers組內(nèi)包含apache和nginx兩個組郎楼,:children表示引用了其他組用來做webservers組的子組
apache
nginx
[webservers:vars]
ntp_server-ntp_erlang.com
2.5 Inventory參數(shù)
ansible基于ssh連接Inventory中指定的遠(yuǎn)程主機(jī)時万伤,還可以通過參數(shù)指定其交互方式,這些參數(shù)如下所示:
> ansible_ssh_host
> ansible_ssh_port
> ansible_ssh_user
> ansible_ssh_pass
> ansible_sudo_pass
> ansible_connection
> ansible_ssh_pricate_key_file
> ansible_shell_type
> ansible_python_interpreter
> ansible\_\*\_interpreter
Ansible playbooks
playbooks是一個或多個“play”組成的列表呜袁,play的主要功能在于將事先歸并為一組的主機(jī)裝扮成事先通過ansible中的tasks定義好的角色敌买,從根本上來講,所謂task無非是調(diào)用ansible的一個module阶界,將多個play組織在一個playbook中放妈,即可以讓他們連同起來按事先編排的機(jī)制同唱一臺大戲,下面是一個簡單示例:
- hosts:webservers ##定義inventory荐操,主機(jī)組
vars:
http_port:80
max_clients:256
remote_user:root ##定義連接到遠(yuǎn)程主機(jī)時,以哪個用戶的身份執(zhí)行
tasks:
- name:install apache is at the latest version ##描述珍策,可隨意寫
yum:name=httpd state=latest ##使用yum模塊托启,指定選項,安裝最新版本的httpd
- name: ensure apache is running ##描述信息
service:name=httpd state=started ##使用service模塊攘宙,指定httpd狀態(tài)
handlers: ##處理器
- name:restart apache
service:name=httpd state=restarted
playbook組成結(jié)構(gòu):
Inventory
Modules
Ad Hoc Commands
Playbooks
Tasks:任務(wù)屯耸,即調(diào)用模塊完成的某操作
Variables:變量
Templates:模板
Handlers:處理器,在某條件滿足時蹭劈,會由某事件觸發(fā)執(zhí)行的操作
Roles:角色
hosts和remote_user:
playbook中的每一個play的目的都是為了讓某個或某些主機(jī)以某個指定的用戶身份執(zhí)行任務(wù)疗绣,hosts即用于指定要執(zhí)行指定任務(wù)的主機(jī),其可以是一個或多個由冒號分隔主機(jī)組铺韧,remote_user則用于指定遠(yuǎn)程主機(jī)上的執(zhí)行任務(wù)的用戶多矮,如以上示例中的
- hosts:webservers
remote_user:root
不過,remote_user也可以用于各個tasks中(可能每個tasks指定的用戶不一樣)哈打,也可以指定其通過sudo的方式在遠(yuǎn)程主機(jī)上執(zhí)行操作塔逃,其可用于play全局或某任務(wù),此外料仗,甚至可以在sudo時使用sudo_user指定sudo時切換的用戶湾盗;
- hosts:webservers
remote_user:mageedu
tasks:
- name:test connection
ping:
remote_user:mageedu
sudo:yes ##以remote_user指定的用戶切入進(jìn)去,然后以這個用戶的身份sudo到root用戶去
任務(wù)列表和action:
play的主體部分是task立轧、list格粪、task list中的各任務(wù)按次序逐個在hosts中指定的所有主機(jī)上執(zhí)行躏吊,即在所有主機(jī)上完成第一個任務(wù)后再執(zhí)行第二個任務(wù),在運行自上而下某playbook時帐萎,如果中途發(fā)生錯誤比伏,所有已執(zhí)行任務(wù)都可能回滾,因此吓肋,在更正playbook后重新執(zhí)行一次即可凳怨;
task的目的是使用指定的參數(shù)執(zhí)行模塊,而在模塊參數(shù)中可以使用變量是鬼,模塊執(zhí)行是冪等的肤舞,這意味這多次執(zhí)行是安全的,因為其結(jié)果均一致均蜜;
每個task都應(yīng)該有個name李剖,用于playbook的執(zhí)行結(jié)果輸出,建議其內(nèi)容盡可能清晰地描述任務(wù)執(zhí)行步驟囤耳,如果為提供name篙顺,則執(zhí)行action的結(jié)果將用于輸出;
定義task的可以使用"action:module option"或"module:option"的格式充择,推薦使用后者以實現(xiàn)向后兼容德玫;
tasks:
- name:make sure apache is running
service:name=httpd state=running
在眾多模塊中,只有command和shell模塊僅需要給定一個列表而無需使用key:value格式椎麦,例如:
tasks:
- name:disable selinux
command:/sbin/setenforce 0
如果命令或腳本的退出碼不為零宰僧,可以使用如下方式替代:
tasks:
- name:run this command and ignore the result
shell:/usr/bin/SOME COMMAND||/bin/true
在執(zhí)行/usr/bin/下的某條命令時,如果報錯了观挎,但是這不影響我們本身意愿或者執(zhí)行結(jié)果時琴儿,可以使用/bin/true將退出碼強(qiáng)制改為true
或者使用ignore_errors來忽略錯誤信息:
tasks:
- name:run this command and ignore the result
shell:/usr/bin/SOME COMMAND
ignore_errors:True
Handlers:處理器
用于當(dāng)關(guān)注的資源發(fā)生變化時采取一定的操作:
“notify”這個action可用于在每個play的最后被觸發(fā),這樣可以避免多次有改變發(fā)生時每次都執(zhí)行指定的操作嘁捷,取而代之造成, 僅在所有的變化發(fā)生完成后一次性的執(zhí)行指定操作,在notify中列出的操作成為Handlers雄嚣,也即notify中調(diào)用handlers中定義的操作晒屎;
示例:
- hosts: test #\\主機(jī)組,在/etc/ansible/hosts定義
remote_user: root # \\遠(yuǎn)端執(zhí)行任務(wù)的用戶
tasks: #\\任務(wù)
- name: install httpd #\\任務(wù)描述
command: yum -y install httpd #\\調(diào)用ansible的command模塊安裝httpd
- name: install configuration file for httpd #\\任務(wù)描述
copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf #\\調(diào)用ansible的copy模塊復(fù)制ansible管理端的文件到被控端
notify: #\\定義一個notify缓升,當(dāng)執(zhí)行copy這個模塊的命令時執(zhí)行notify
- restart httpd #\\ notify引用的handlers的名字為restart httpd(必須跟handlers的名字一樣)
handlers: #\\ 定義一個handlers
- name: restart httpd #\\名字為restart httpd
service: name=httpd state=restarted #\\調(diào)用ansible的service模塊夷磕,重啟httpd服務(wù)
playbook的一個簡單實例:
- hosts: test #\\主機(jī)組,在/etc/ansible/hosts定義
remote_user: root # \\遠(yuǎn)端執(zhí)行任務(wù)的用戶
tasks: #\\任務(wù)
- name: install httpd #\\任務(wù)描述
command: yum -y install httpd #\\調(diào)用ansible的command模塊安裝httpd
###### 在playbook中使用變量:
- hosts: test #\\主機(jī)組仔沿,在/etc/ansible/hosts定義
remote_user: root # \\遠(yuǎn)端執(zhí)行任務(wù)的用戶
vars: ##定義變量package和service
- package: httpd
- service: httpd
tasks: #\\任務(wù)
- name: rpm -e httpd
command: rpm -e httpd
- name: install {{ package }} #\\任務(wù)描述 調(diào)用變量用{{ }}引用
command: yum -y install httpd #\\調(diào)用ansible的command模塊安裝httpd
- name: install configuration file for httpd
copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
Ansible使用條件測試
如果需要根據(jù)變量坐桩、facts或此前任務(wù)的執(zhí)行結(jié)果來做為某task執(zhí)行還是不執(zhí)行的前提時需要用到條件測試;
1.when語句
在task后添加when子句即可使用條件測試封锉,when語句支持jinja2表達(dá)式語法绵跷,例如:
tasks:
- name: "shutdown debian system"
command: /sbin/shutdown -h now
when: ansible_os_family == "Debian"
當(dāng)系統(tǒng)為debian系統(tǒng)時膘螟,則關(guān)機(jī)
- hosts: test
remote_user: root
tasks:
- name: yum httpd
command: yum -y install httpd
when: ansible_fqdn == "wwww"
當(dāng)test組的某臺主機(jī)的主機(jī)名為wwww時,才給符合條件的主機(jī)安裝httpd
Ansible playbook使用迭代(循環(huán))
當(dāng)有需要重復(fù)性執(zhí)行的任務(wù)時碾局,可以使用迭代機(jī)制荆残,其使用格式為將需要迭代的內(nèi)容定義為item變量引用,并通過with_item語句來指明迭代的元素列表即可净当,例如:
- hosts: test
remote_user: root
tasks:
- name: touch file
file: name={{ item }} state=directory ##循環(huán)創(chuàng)建ietm内斯,而item對應(yīng)的值為with_items中指定的
with_items: ##列出item索要對應(yīng)的值
- file1
- file2
事實上,with_items中可以使用元素還可為hashes像啼,例如:
- hosts: test
remote_user: root
tasks:
- name: touch file
user: name={{ item.name}} state=present groups={{ item.groups }} ##在各個主機(jī)創(chuàng)建用戶俘闯,以及指定用戶的基本組
with_items:
- { name: 'testuser1', groups: 'nginx' }
- { name: 'testuser2', groups: 'apache' }
Ansible中使用Templates
http://blog.csdn.net/modoo_junko/article/details/45460693