|
2015年初,我們計劃為開發(fā)團(tuán)隊搭建一套全新的部署平臺,在此之前我們使用的是Amazon EC2。盡管AWS-based steup我們一直用得很好,但使用自定義腳本和工具自動化部署的設(shè)置,對于運(yùn)維以外的團(tuán)隊來說不是很友好,特別是一些小團(tuán)隊——沒有足夠的資源來了解這些腳本和工具的細(xì)節(jié)。這其中的主要問題在于沒有“部署單元(unit-of-deployment)”,該問題直接導(dǎo)致了開發(fā)與運(yùn)維之間工作的斷層,而容器化趨勢看上去是一個不錯的方案。 如果你還沒有做好將Docker和Kubernetes落地到生產(chǎn)環(huán)境的準(zhǔn)備,不妨參考參考我們的經(jīng)驗。我們已經(jīng)在生產(chǎn)環(huán)境使用kubernetes一年多了。 從容器和容器編排工具開始 我們相信容器會是未來最主流的部署格式,這項技術(shù)讓應(yīng)用封裝變得簡單了許多。類似于Docker之類的工具提供了實際的容器,但我們還需要復(fù)制、故障排除等工具,以及可實現(xiàn)自動部署到多臺機(jī)器的API,好讓容器技術(shù)發(fā)揮出最大的作用。 在2015年初,Kubernetes、Docker Swarm等集成工具還不成熟,僅提供alpha版本。不過我們還是決定試一試,并選擇了Docker Swarm。 我們用Docker Swarm來處理網(wǎng)絡(luò),利用Ambassador模式和一組腳本來實現(xiàn)自動化部署。這種方式難度之大,超乎想象,我們也因此收獲了第一個教訓(xùn):容器集成、網(wǎng)絡(luò)、部署自動化是非常棘手的問題。 好在我們很快意識到了這一點(diǎn),并決定將籌碼壓在Kubernetes身上——一款由Google、Red Hat、Core OS及一些對大規(guī)模部署頗有見地的組織提供支持的集成工具。 通過Kubernetes實現(xiàn)負(fù)載均衡 使用Kubernetes,需要對pods、services、replication controller等概念了然于心。好消息是,包括Kubernetes官方文檔在內(nèi),網(wǎng)絡(luò)上有海量資源,可以幫助你快速上手。 成功建立并運(yùn)行Kubernetes集群后,即可通過kubectl(Kubernetes CLI)部署應(yīng)用了。然而當(dāng)我們想要自動化部署時,卻發(fā)現(xiàn)光有kubectl是不夠的。不過,在此之前我們需要解決另一個問題:如何從Internet訪問部署的應(yīng)用? 部署前的服務(wù)有一個IP地址,但這個地址僅在Kubernetes集群中可用。這意味著無法通過網(wǎng)絡(luò)訪問該服務(wù)!在Google Cloud Engine上運(yùn)行時,Kubernetes會自動配置一個負(fù)載均衡用以訪問應(yīng)用;如果不在Google Cloud Engine上運(yùn)行(比如我們),那就需要做一些額外的工作來獲得負(fù)載均衡了。 直接在主機(jī)端口上開放服務(wù)是一個可行的解決方案(很多人一開始的確是這么做的),但我們發(fā)現(xiàn),這樣的做法等于放棄了Kubernetes所提供的許多好處。如果我們依賴主機(jī)上的端口,部署多個應(yīng)用時會遇到端口沖突。另外這樣的做法會加大擴(kuò)展集群和更換主機(jī)的難度。 二級負(fù)載均衡器配置 我們發(fā)現(xiàn),解決以上問題的更好辦法,是在Kubernetes集群前配置負(fù)載均衡器,例如HAProxy或者NGINX。于是我們開始在AWS上的VPN中運(yùn)行Kubernetes集群,并使用AWS ELB將外部web流量路由到內(nèi)部HAProxy集群。HAProxy為每個Kubernetes服務(wù)配置了“后端”,以便將流量交換到各個pods。 這種“二級負(fù)載均衡器配置”主要也是為了適應(yīng)AWS ELB相當(dāng)有限的配置選項。其中一個限制是,它不能處理多個vhosts。這也是我們同時使用HAProxy的原因。只使用HAProxy(不用ELB)也能工作,只不過需要你在DNS級別解決動態(tài)AWS IP地址問題。
圖1:我們的“二級負(fù)載均衡器配置流程“ 在任何情況下,創(chuàng)建新的Kubernetes服務(wù),我們都需要一種機(jī)制動態(tài)重新配置負(fù)載均衡器(在我們的例子中是HAProxy)。 Kubernetes社區(qū)目前正在開發(fā)一個名為ingress的功能,用來直接從Kubernetes配置外部負(fù)載均衡器。可惜的是,目前開發(fā)工作還未完成。過去一年,我們采用的是API配合一個小的開源工具來配置負(fù)載均衡。 配置負(fù)載均衡 首先,我們需要一個地方存儲負(fù)載均衡器配置。負(fù)載均衡器配置可以存儲在任何地方,不過因為我們已經(jīng)有etcd可用,就把這些配置放在了etcd里。我們使用一個名為“confd”的工具觀察etcd中的配置變動,并用模板生成了一個新的HAProxy配置文件。當(dāng)一個新的服務(wù)添加到Kubernetes,我們向etcd中添加一個新的配置,一個新的HAProxy配置文件也就此產(chǎn)生。 不斷完善的Kubernetes Kubernetes中仍然存在眾多待解決的問題,很多開發(fā)者在社區(qū)上、設(shè)計文檔中討論解決這些問題的新功能,但開發(fā)適用于每一個人的解決方案是需要時間的。不過從長遠(yuǎn)來看,這也是一件好事,用shortcut的方式設(shè)計新功能很多時候會適得其反。 當(dāng)然,問題的存在并不意味著我們現(xiàn)在所使用的Kubernetes功能有限。配合API,Kubernetes幾乎可以完成你想要的一切。等Kubernetes增加新功能后,我們再用標(biāo)準(zhǔn)方案替代自己的解決方案不遲。 話說回來,在我們開發(fā)了用于負(fù)載均衡的解決方案后,另一項挑戰(zhàn)接踵而至:藍(lán)綠部署(Blue-green deployments)。 Kubernetes上的藍(lán)綠部署 藍(lán)綠部署是一種不中斷服務(wù)的部署。與滾動更新不同,藍(lán)綠部署在舊版本仍然正常工作的情況下,通過啟用一個運(yùn)行著新版本的副本集群來實現(xiàn)更新。當(dāng)新版本的副本集群完全啟動并運(yùn)行時,負(fù)載均衡器配置才會更改并將負(fù)載切換到新版本上。這種方式的好處是,永遠(yuǎn)保持至少一個版本的應(yīng)用正常運(yùn)行,減少了處理多個并發(fā)版本帶來的復(fù)雜性。藍(lán)綠部署在副本數(shù)量很少時也能很好的工作。
圖2:Kubernetes下的藍(lán)綠部署 圖2展示了“Deployer“如何編排部署?;贏pache License,并作為Amdatu umbrella project的一部分,我們開源了這個組件的實現(xiàn),供大家參考使用。另外,這個組件帶web UI,可以用來配置部署。 這種機(jī)制的一個要點(diǎn)是在重新配置負(fù)載均衡器之前,執(zhí)行在pods上的運(yùn)行狀態(tài)檢查。我們希望每部署的每一個組件都能提供狀態(tài)檢查。目前的做法通常是為每個組件添加一個通過HTTP訪問的狀態(tài)檢查。 實現(xiàn)部署自動化 有了Deployer,我們就可以把部署集成到構(gòu)建流程中了。我們的構(gòu)建服務(wù)器可以在構(gòu)建成功之后,將新的鏡像推送到registry(如Git Hub),而后構(gòu)建服務(wù)器可以調(diào)用新版本應(yīng)用并自動部署至測試環(huán)境中。同一個鏡像也可以通過觸發(fā)生產(chǎn)環(huán)境中的Deployer被推送上生產(chǎn)。
圖3:容器化自動部署流程 資源限制 使用Kubernetes時,搞清楚資源限制很重要。你可以在每個pod上配置資源請求和CPU/內(nèi)存限制,也可以控制資源保證和bursting limits。 這些設(shè)置對于高效運(yùn)行多個容器極為重要,防止容器因分配內(nèi)存不足而意外停止。 建議盡早設(shè)置和測試資源限制。沒有限制時,看起來運(yùn)行良好,不代表把重要負(fù)載放到容器中不會出現(xiàn)問題。 Kubernetes監(jiān)控 當(dāng)我們快要搭建好Kubernetes時,我們意識到監(jiān)控和日志在這個新的動態(tài)環(huán)境中非常重要。當(dāng)我們面對大規(guī)模服務(wù)和節(jié)點(diǎn)時,進(jìn)入服務(wù)器查看日志文件是不現(xiàn)實的,建一個中心化的日志和監(jiān)控系統(tǒng)需要盡快提上議程。 日志 有很多用于日志記錄的開源工具,我們使用的是Graylog和Apache Kafka(從容器收集摘錄日志的消息傳遞系統(tǒng))。容器將日志發(fā)送給Kafka,Kafka交給Graylog進(jìn)行索引。我們讓應(yīng)用組件將日志打給Kafka,方便將日志流式化,成為易于索引的格式。也有一些工具可以從容器外收集日志,然后發(fā)送給日志系統(tǒng)。 監(jiān)控 Kubernetes具備超強(qiáng)的故障恢復(fù)機(jī)制,Kubernetes會重啟意外停止的pod。我們曾遇到過因內(nèi)存泄露,導(dǎo)致容器在一天內(nèi)宕機(jī)多次的情況,然而令人驚訝的是,甚至我們自己都沒有察覺到。 Kubernetes在這一點(diǎn)上做得非常好,不過一旦問題出現(xiàn),即使被及時處理了,我們還是想要知道。因此我們使用了一個自定義的運(yùn)行狀況檢查儀表盤來監(jiān)控Kubernetes節(jié)點(diǎn)和pod,以及包括數(shù)據(jù)存儲在內(nèi)的一些服務(wù)??梢哉f在監(jiān)控方面,Kubernetes API再次證明了其價值所在。 檢測負(fù)載、吞吐量、應(yīng)用錯誤等狀態(tài)也是同樣重要的,有很多開源軟件可以滿足這一需求。我們的應(yīng)用組件將指標(biāo)發(fā)布到InfluxDB,并用Heapster去收集Kubernetes的指標(biāo)。我們還通過Grafana(一款開源儀表盤工具)使存儲在InfluxDB中的指標(biāo)可視化。有很多InfluxDB/Grafana堆棧的替代方案,無論你才用哪一種,對于運(yùn)行情況的跟蹤和監(jiān)控都是非常有價值的。 數(shù)據(jù)存儲和Kubernetes 很多Kubernetes新用戶都有一個問題:我該如何使用Kubernetes處理數(shù)據(jù)? 運(yùn)行數(shù)據(jù)存儲時(如MangoDB或MySQL),我們很可能會有持久化數(shù)據(jù)儲存的需求。不過容器一但重啟,所有數(shù)據(jù)都會丟失,這對于無狀態(tài)組件沒什么影響,但對持久化數(shù)據(jù)儲存顯然行不通。好在,Kubernetes具有Volume機(jī)制。 Volume可以通過多種方式備份,包括主機(jī)文件系統(tǒng)、EBS(AWS的Elastic Block Store)和nfs等。當(dāng)我們研究持久數(shù)據(jù)問題是,這是一個很好的方案,但不是我們運(yùn)行數(shù)據(jù)存儲的答案。 副本問題 在大多數(shù)部署中,數(shù)據(jù)存儲也是有副本的。Mongo通常在副本集中運(yùn)行,而MySQL可以在主/副模式下運(yùn)行。我們都知道數(shù)據(jù)儲存集群中的每個節(jié)點(diǎn)應(yīng)該備份在不同的volume中,寫入相同volume會導(dǎo)致數(shù)據(jù)損壞。另外,大多數(shù)數(shù)據(jù)存儲需要明確配置才能使集群啟動并運(yùn)行,自動發(fā)現(xiàn)和配置節(jié)點(diǎn)并不常見。 同時,運(yùn)行著數(shù)據(jù)存儲的機(jī)器通常會針對某項工作負(fù)載進(jìn)行調(diào)整,例如更高的IOPS。擴(kuò)展(添加/刪除節(jié)點(diǎn))對于數(shù)據(jù)存儲來說,也是一個昂貴的操作,這些都和Kubernetes部署的動態(tài)本質(zhì)不相符。 決定不在生產(chǎn)環(huán)境數(shù)據(jù)存儲上使用Kubernetes 以我們的情況,在Kubernetes內(nèi)運(yùn)行數(shù)據(jù)存儲沒有想象中那么完美,設(shè)置起來也比其他Kubernetes部署復(fù)雜得多。 于是我們決定不在生產(chǎn)環(huán)境數(shù)據(jù)存儲上使用Kubernetes,而是選擇在不同的機(jī)器上手動啟動這些集群,我們在Kubernetes內(nèi)部運(yùn)行的應(yīng)用正常連接到數(shù)據(jù)存儲集群。 所以說,沒必要運(yùn)行Kubernetes的一切,按自身情況與其他工具配合使用,會有意想不到的效果,比如我們的數(shù)據(jù)存儲和HAProxy服務(wù)器。 未來 看看我們現(xiàn)在的部署,可以負(fù)責(zé)任的說,Kubernetes的表現(xiàn)絕對是夢幻級的,而Kubernetes API更是自動化部署流程的利器。由于不需要處理VM,我們現(xiàn)在的部署相比之前更快、更可靠。更簡單的容器測試和交付,也讓我們在構(gòu)建和部署可靠性上得到了巨大提升。 這種新的部署方式迅速高效,讓我們得以跟上其他團(tuán)隊的節(jié)奏,這絕對是必要的。 成本計算 任何事情都有兩面性。運(yùn)行Kubernetes,需要一個etcd集群以及一個Master節(jié)點(diǎn),對于較小的部署來說,這一開銷還是比較大的,適合通過一些云服務(wù)達(dá)成。 對于大規(guī)模部署,Kubernetes可以幫助節(jié)省大量服務(wù)器成本,etcd集群和Master節(jié)點(diǎn)這點(diǎn)開銷就顯得微不足道了。Kubernetes讓很多容器在一個主機(jī)上運(yùn)行變得非常容易,最大程度上利用了現(xiàn)有資源,減少了服務(wù)器數(shù)量,成本自然下降了。不過這樣的集群也給運(yùn)維工作提出了更高的要求,必須要的時候,我們可以選擇一些云計算平臺提供的云服務(wù)來輕松達(dá)成。 Author Trans by 好雨科技 |
|
|
來自: 昵稱54185769 > 《待分類》