《微服務(wù)運(yùn)維實(shí)戰(zhàn)(第1卷)》詳細(xì)講解微服務(wù)和容器在軟件持續(xù)集成和部署中的應(yīng)用。將微服務(wù)打包成不可變的容器,通過(guò)配置管理工具實(shí)現(xiàn)自動(dòng)化測(cè)試和持續(xù)部署,同時(shí)保證零停機(jī)且隨時(shí)能回滾。采用集中日志對(duì)集群進(jìn)行記錄和監(jiān)控,輕松實(shí)現(xiàn)服務(wù)器擴(kuò)展。作者通過(guò)講解相關(guān)工具(Docker、Kubernetes、Ansible、Consul等)的用法,分享自己的工作經(jīng)驗(yàn),幫助讀者構(gòu)建高效、可靠、可快速恢復(fù)的軟件系統(tǒng)。
我的職業(yè)生涯是從程序員開(kāi)始的。那段日子,我所知道的只是編寫代碼。我以為出色的軟件設(shè)計(jì)師就是精通編碼的人,而精通的途徑是對(duì)所選的一種編程語(yǔ)言做到了如指掌。后來(lái),我的想法變了,我開(kāi)始對(duì)不同的編程語(yǔ)言產(chǎn)生興趣。我從Pascal換到Basic,而后換到ASP。Java和.NETet讓我了解到面向?qū)ο缶幊痰暮锰。Python、Perl、Bash、HTML、JavasScript、Scala,每種編程語(yǔ)言都帶來(lái)一些新東西并教給我如何以不同的方式思考。我學(xué)會(huì)了為手頭的任務(wù)挑選正確的工具。每學(xué)會(huì)一種新語(yǔ)言,我就感覺(jué)距離成為專家又近了一點(diǎn)。我只想成為一名資深程序員,這個(gè)想法隨著時(shí)間的推移發(fā)生了改變。我認(rèn)識(shí)到,如果要把自己的工作做好,我得成為一名軟件藝匠。我學(xué)習(xí)的東西遠(yuǎn)不止輸入代碼。有段時(shí)間我癡迷于測(cè)試,現(xiàn)在我認(rèn)為測(cè)試是開(kāi)發(fā)不可或缺的一部分。除非有特殊原因,否則我編寫的每行代碼都是通過(guò)測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(test-driven development,TDD)來(lái)完成的。測(cè)試驅(qū)動(dòng)開(kāi)發(fā)已它成為我手上必不可少的工具。另外我還認(rèn)識(shí)到,在確定應(yīng)該做什么時(shí),我必須接近客戶與他們肩并肩地工作。所有這些事情都將我引向軟件架構(gòu)領(lǐng)域。
我在軟件行業(yè)工作的這些年,沒(méi)有哪個(gè)工具、框架或者實(shí)踐能像持續(xù)集成(continuous integration,CI)以及之后的持續(xù)交付(continuous delivery,CD)那樣讓我著迷。起初,我以為CI/CD意味著了解Jenkins并且能夠書寫腳本。隨著時(shí)間的推移,我認(rèn)識(shí)到CI/CD幾乎牽涉了軟件開(kāi)發(fā)的方方面面。而我是在付出一定代價(jià)后才有了這樣的認(rèn)識(shí)。
我不止一次嘗試為我開(kāi)發(fā)的應(yīng)用創(chuàng)建CI管道,但都失敗了,因?yàn)槲也捎玫姆椒ㄊ清e(cuò)誤的。不考慮架構(gòu)問(wèn)題,CI/CD是無(wú)法實(shí)現(xiàn)的。類似的道理亦適用于測(cè)試、配置、環(huán)境、容錯(cuò)等等方面。要成功實(shí)施CI/CD,我們需要做出很多改變,這些改變第1眼看上去似乎沒(méi)有直接的關(guān)聯(lián)。我們需要從一開(kāi)始就應(yīng)用一些模式和實(shí)踐。我們還得考慮架構(gòu)、測(cè)試、耦合、打包、容錯(cuò),以及其它他許多事情。通過(guò)實(shí)踐CI/CD,我們正影響和改善軟件開(kāi)發(fā)生命周期的方方面面。
要真正精通CI/CD,我們需要對(duì)運(yùn)維更為加熟悉。DevOps運(yùn)動(dòng)將開(kāi)發(fā)所能帶來(lái)的優(yōu)勢(shì)與傳統(tǒng)運(yùn)維相結(jié)合,這是一個(gè)顯著的改善。但我認(rèn)為這還不夠。如果想要獲得CI/CD所能帶來(lái)的全部好處,我們需要深入理解架構(gòu)、測(cè)試、開(kāi)發(fā)、運(yùn)維,甚至客戶洽談,并做出相應(yīng)的改變。用DevOps這個(gè)名字來(lái)概括CI/CD其實(shí)是不合適的,因?yàn)镈evOps不僅僅關(guān)系到開(kāi)發(fā)和運(yùn)維,其還關(guān)系到軟件開(kāi)發(fā)的所有方面,需要架構(gòu)師、測(cè)試人員,甚至管理者的共同參與。DevOps將傳統(tǒng)運(yùn)維與開(kāi)發(fā)相結(jié)合是一個(gè)巨大的進(jìn)步。就當(dāng)前的業(yè)務(wù)需求而言,手工運(yùn)維幾乎是行不通的,而自動(dòng)化需要開(kāi)發(fā)工作。我認(rèn)為應(yīng)該擴(kuò)展DevOps的定義。我本打算把它重新命名為DevOpsArchTestManageAndEverythingElse,但這個(gè)名字過(guò)于繁瑣而且?guī)缀醪豢赡茏x出來(lái),因此我用DevOps 2.0來(lái)代替。DevOps 2.0不但要實(shí)現(xiàn)運(yùn)維自動(dòng)化,而且要讓整個(gè)系統(tǒng)變得自動(dòng)化、快速、可擴(kuò)展、容錯(cuò)、零宕機(jī)、易于監(jiān)控。這無(wú)法通過(guò)某個(gè)單一的工具實(shí)現(xiàn),只能通過(guò)深入到技術(shù)層面和流規(guī)層面重構(gòu)整個(gè)系統(tǒng)來(lái)實(shí)現(xiàn)。
本書介紹快速構(gòu)建現(xiàn)代軟件系統(tǒng)的方法,我們將微服務(wù)打包成不可變的容器,通過(guò)配置管理工具實(shí)現(xiàn)自動(dòng)化測(cè)試和持續(xù)部署,同時(shí)保證零停機(jī)且隨時(shí)能回滾。設(shè)計(jì)能夠從硬件和軟件故障中恢復(fù)的自愈系統(tǒng),采用集中日志對(duì)集群進(jìn)行記錄和監(jiān)控,輕松實(shí)現(xiàn)服務(wù)器擴(kuò)展。
換言之,本書采用業(yè)界新的工具和方法開(kāi)展微服務(wù)開(kāi)發(fā)與部署。我們將用到Docker、Kubernetes、Ansible、Ubuntu、Docker Swarm、Docker Compose、Consul、etcd、Registrator、confd、Jenkins。
本書是寫給那些對(duì)持續(xù)部署和微服務(wù)感興趣的專業(yè)人士看的,涉及的內(nèi)容非常寬泛,目標(biāo)讀者包括想了解如何圍繞微服務(wù)設(shè)計(jì)系統(tǒng)的架構(gòu)師,想了解如何應(yīng)用現(xiàn)代配置管理實(shí)踐和持續(xù)部署容器化應(yīng)用的DevOps人員,希望將整個(gè)流程掌控在自己手中的開(kāi)發(fā)人員,以及想要更好地理解軟件交付流程的管理人員。我們會(huì)談及系統(tǒng)的擴(kuò)展和監(jiān)控,。我們甚至?xí)O(shè)計(jì)(并實(shí)現(xiàn))能夠從(硬件或軟件)故障中自愈的系統(tǒng)。
本書內(nèi)容涉及從設(shè)計(jì)、開(kāi)發(fā)、測(cè)試、部署到運(yùn)維的所有階段。我們介紹的流程是業(yè)界新的佳實(shí)踐。
第1章 DevOps的理想 1
1.1 持續(xù)集成、交付和部署 2
架構(gòu) 3
部署 4
編排 5
1.2 部署流水線的曙光 5
第2章 實(shí)現(xiàn)突破持續(xù)部署、微服務(wù)和容器 7
2.1 持續(xù)集成 7
推送到代碼庫(kù) 9
靜態(tài)分析 10
部署前測(cè)試 12
打包并部署到測(cè)試環(huán)境 13
部署后測(cè)試 13
2.2 持續(xù)交付和部署 15
微服務(wù) 18
容器 18
2.3 三個(gè)火槍手持續(xù)部署、微服務(wù)和容器的協(xié)作 20
第3章 系統(tǒng)架構(gòu) 23
3.1 單塊應(yīng)用 24
微服務(wù) 27
3.2 單塊應(yīng)用與微服務(wù)的比較
29
運(yùn)維和部署的復(fù)雜性 30
規(guī)模 31
部署、回滾和故障隔離 32
承諾期限 32
3.3 微服務(wù)的最佳實(shí)踐 41
容器 41
3.4 代理微服務(wù)或API網(wǎng)關(guān) 44
反向代理 44
極簡(jiǎn)主義方法 45
配置管理 45
跨職能團(tuán)隊(duì) 45
API版本化 46
最后的思考 46
第4章 使用Vagrant和Docker搭建開(kāi)發(fā)環(huán)境 49
4.1 結(jié)合微服務(wù)架構(gòu)和容器技術(shù)
50
Vagrant與Docker 52
4.2 開(kāi)發(fā)環(huán)境搭建 55
開(kāi)發(fā)環(huán)境使用 58
第5章 部署流水線的實(shí)現(xiàn)初始階段 63
5.1 啟動(dòng)持續(xù)部署虛擬機(jī) 63
5.2 部署流水線步驟 65
構(gòu)建Docker容器 67
第6章 Docker世界中的配置管理 79
6.1
CFEngine 79
Puppet 80
Chef 80
最后幾點(diǎn)思考 82
配置生產(chǎn)環(huán)境 83
設(shè)置Ansible Playbook 86
第7章 部署管道的實(shí)現(xiàn)中間階段
91
7.1 在生產(chǎn)服務(wù)器上部署容器
92
檢查清單 97
第8章 發(fā)現(xiàn)服務(wù)分布式服務(wù)的關(guān)鍵 99
8.1 服務(wù)注冊(cè)表 101
服務(wù)注冊(cè) 101
主動(dòng)注冊(cè) 102
注冊(cè)服務(wù) 103
服務(wù)發(fā)現(xiàn) 103
服務(wù)發(fā)現(xiàn)工具 104
手動(dòng)配置 106
Zookeeper 106
etcd 107
配置Registrator 130
Consul Health Checks、Web UI和數(shù)據(jù)中心 138
8.2 服務(wù)發(fā)現(xiàn)工具的比較 141
第9章 代理服務(wù) 143
9.1 反向代理服務(wù) 144
代理服務(wù)對(duì)我們的項(xiàng)目有何幫助 146
nginx 146
nginx 146
HAProxy 158
9.2 代理工具的比較 163
第10章 部署流水線的實(shí)現(xiàn)后期階段 167
10.1
啟動(dòng)容器 169
10.2
集成服務(wù) 170
10.3
運(yùn)行部署后測(cè)試 171
10.4
將測(cè)試容器推送到鏡像庫(kù) 172
10.5
檢查表 173
第11章 部署流水線的自動(dòng)化實(shí)現(xiàn)
175
11.1
部署流水線的步驟 175
Playbook和Role 178
部署前任務(wù) 179
部署任務(wù) 182
部署后任務(wù) 185
11.2
運(yùn)行自動(dòng)部署流水線 186
第12章 持續(xù)集成、交付和部署的工具
187
12.1
CI/CD工具對(duì)比 188
CI/CD工具的簡(jiǎn)史 189
運(yùn)行Jenkins作業(yè) 203
創(chuàng)建Jenkins Workflow作業(yè) 206
安裝Jenkins Multibranch Workflow和Jenkinsfile 215
最后的想法 217
第13章 藍(lán)綠部署 219
13.1
藍(lán)綠部署的流程 220
13.2
手動(dòng)執(zhí)行藍(lán)綠部署 223
部署藍(lán)色版本 224
集成藍(lán)色版本 226
部署綠色版本 228
集成綠色版本 230
移除藍(lán)色版本 231
發(fā)現(xiàn)應(yīng)部署哪個(gè)版本以及回滾 233
13.3
使用Jenkins workflow自動(dòng)化藍(lán)綠部署 239
藍(lán)綠部署角色 240
運(yùn)行藍(lán)綠部署 245
第14章 服務(wù)集群和擴(kuò)展 249
14.1
可擴(kuò)展性 250
軸線擴(kuò)展 252
集群 254
Docker集群工具大比拼Kubernetes、Docker Swarm和
Mesos對(duì)比 256
搭建 258
運(yùn)行容器 260
選擇 262
14.2
Docker Swarm漫步 263
14.3
搭建Docker Swarm 268
使用Docker Swarm部署 274
使用Docker Swarm無(wú)鏈接部署 275
使用Docker Swarm和Docker Networking部署 276
使用Docker Swarm擴(kuò)展服務(wù) 283
根據(jù)預(yù)留的CPU和內(nèi)存調(diào)度容器 284
14.4
使用Docker Swarm和Ansible自動(dòng)化部署 288
檢驗(yàn)Swarm部署playbook 290
第15章 自我修復(fù)系統(tǒng) 297
15.1
自我修復(fù)等級(jí)和類型 298
應(yīng)用程序級(jí)別的自我修復(fù) 299
系統(tǒng)級(jí)別的自我修復(fù) 300
硬件級(jí)別的自我修復(fù) 302
反應(yīng)式自我修復(fù) 303
預(yù)防式自我修復(fù) 303
15.2
自我修復(fù)架構(gòu) 305
15.3
Docker、Consul Watches和Jenkins組成的自我修復(fù)系統(tǒng) 311
搭建環(huán)境 311
15.4
自動(dòng)設(shè)置Consul健康檢查和watches來(lái)監(jiān)測(cè)硬件 322
15.5
預(yù)設(shè)擴(kuò)展和收縮的預(yù)防式自我修復(fù) 334
采用Docker重啟策略的預(yù)防式自我修復(fù) 339
將On-Premise與云節(jié)點(diǎn)結(jié)合 341
15.6
自我修復(fù)系統(tǒng)(到目前為止)總結(jié) 342
第16章 集中日志和監(jiān)控 343
16.1
集中日志的需求 344
16.2
向ElasticSearch發(fā)送日志條目 347
解析文件條目 354
發(fā)送日志條目到集中式LogStash 358
發(fā)送Docker日志條目到集中式LogStash實(shí)例 363
16.3
基于軟件數(shù)據(jù)的自修復(fù)系統(tǒng) 375
硬件狀態(tài)日志 381
基于硬件數(shù)據(jù)的自修復(fù)系統(tǒng) 388
最后的想法 388
第17章 結(jié)語(yǔ) 391
附錄A Docker Flow 393
A.1 背景 394
標(biāo)準(zhǔn)搭建環(huán)境 394
問(wèn)題 396
Docker Flow漫談 398
零停機(jī)事件部署新版本 404
索引 415