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