聊聊 Kubernetes 在企業(yè)落地過(guò)程中遇到的問(wèn)題
原文鏈接:
https://increment.com/containers/containerization-at-scale/
Increment 采訪了 Datadog、Braze 和 BetterUp 的工程負(fù)責(zé)人,討論了容器工具、測(cè)試和監(jiān)控,以及他們?nèi)绾翁幚砣萜鬟w移的問(wèn)題。
DataDog 高級(jí)工程師勞倫:主要容器技術(shù)有 Kubernetes、containerd 和 Cilium。我們?cè)诙鄠€(gè)云供應(yīng)商上運(yùn)行了數(shù)十個(gè)不同規(guī)模的 Kubernetes 集群:我們最大的集群每個(gè)都有 4000 多個(gè)節(jié)點(diǎn),而且我們依賴內(nèi)部開(kāi)發(fā)的工具來(lái)管理和編排多個(gè)集群的部署。
Braze 工程總監(jiān)克里斯:我們?cè)?AWS 和 Azure 中使用 Kubernetes,運(yùn)行 Ruby on Rails、Java、Go 和 Python 中的 dockerized 應(yīng)用程序。Kubernetes 會(huì)將度量報(bào)告給 Datadog,將日志報(bào)告給 Papertrail,而應(yīng)用程序的錯(cuò)誤會(huì)轉(zhuǎn)到 Sentry。通過(guò)使用 Terraform 定義 Kubernetes 在不同云中部署的基礎(chǔ)設(shè)施,我們使用 Sops 進(jìn)行 Secret 配置。
BetterUp 工程經(jīng)理布萊恩: 我們使用 Heroku,它采用了稱為 dynos 的輕量級(jí)容器,用于我們的網(wǎng)絡(luò)服務(wù)器、后臺(tái)作業(yè)以及機(jī)器學(xué)習(xí)微服務(wù)的一個(gè)子集。其他機(jī)器學(xué)習(xí)微服務(wù)使用 Kubeflow。利用 Docker,我們可以將開(kāi)發(fā)和測(cè)試環(huán)境與生產(chǎn)環(huán)境保持一致。我們使用 SolarWinds Papertrail 和 Sumo Logic。對(duì)于客戶端和應(yīng)用程序的錯(cuò)誤報(bào)告,我們使用 Sentry。最后,在性能監(jiān)控方面,我們使用了 Scout 和 Calibre。
DataDog 高級(jí)工程師勞倫:從 2018 年初開(kāi)始,Datadog 遷移到 Kubernetes,大約 6 個(gè)月之后,DataDog 的第一個(gè)版本就完全在 Kubernetes 上運(yùn)行和生產(chǎn)了。其中包括無(wú)狀態(tài)網(wǎng)絡(luò)應(yīng)用和有狀態(tài)數(shù)據(jù)服務(wù),如 Cassandra 和 Kafka。我們從用 Chef 管理的虛擬機(jī)中運(yùn)行的應(yīng)用程序遷移過(guò)來(lái),因此這一過(guò)渡要求對(duì)開(kāi)發(fā)流程進(jìn)行很多更改。舉例來(lái)說(shuō),我們必須將每個(gè)應(yīng)用程序容器化,并提供一種可以部署到 Kubernetes 集群的解決方案,該方案最初依賴于 Spinnaker 和 Helm 圖表。遷移是一個(gè)挑戰(zhàn)。這個(gè)截止日期很有挑戰(zhàn)性,我們將從一個(gè)沒(méi)有容器、也沒(méi)有工具來(lái)部署容器的環(huán)境開(kāi)始。但是這樣做也很有意義,因?yàn)樗鼮槲覀兲峁┝私y(tǒng)一的打包和部署解決方案,使我們能夠部署到新的云供應(yīng)商和地區(qū)。
Braze 工程總監(jiān)克里斯:大約兩年前,我們開(kāi)始在多云環(huán)境中使用容器。經(jīng)過(guò)近一年的初步探索,最初,容器會(huì)增加一些復(fù)雜性,尤其是在配置方面,但是,當(dāng)我們構(gòu)建工具時(shí),某些方面會(huì)變得更加簡(jiǎn)單。舉例來(lái)說(shuō),Chef 要求更嚴(yán)格的權(quán)限才能對(duì)配置進(jìn)行修改。把 Chef 數(shù)據(jù)包的配置改成 Sops,我們給開(kāi)發(fā)者帶來(lái)了更簡(jiǎn)單的自助式更改。
BetterUp 工程經(jīng)理布萊恩:2015 年以前,我們使用基于虛擬機(jī)的開(kāi)發(fā)環(huán)境,后來(lái)由于本地編譯的原生依賴性帶來(lái)的挑戰(zhàn),常常導(dǎo)致升級(jí)失敗,從而改用容器。轉(zhuǎn)換為容器之后,我們就可以做到無(wú)縫地遷移,而不會(huì)對(duì)開(kāi)發(fā)工作流程造成負(fù)面影響。這也使我們的開(kāi)發(fā)環(huán)境更加現(xiàn)代化,更接近于生產(chǎn)環(huán)境,并且降低了資源的密度。
DataDog 高級(jí)工程師勞倫:我們大多數(shù)應(yīng)用程序都是用 Go、Python 和 Java 編寫的,因此在容器中運(yùn)行它們并不困難。問(wèn)題當(dāng)然是在細(xì)節(jié)上,我們面臨著一些挑戰(zhàn),包括在容器中管理 JVM 占用的內(nèi)存。大部分應(yīng)用程序都認(rèn)為它們只在虛擬機(jī)上運(yùn)行,這就給它們自己提出了挑戰(zhàn):尤其是 IO 操作(磁盤和網(wǎng)絡(luò)訪問(wèn)),因?yàn)?Kubernetes 在共享 CPU 時(shí)間和內(nèi)存方面效率很高。Kubernetes 提供了更少的控制來(lái)限制和隔離資源消耗,IO 方面則更為復(fù)雜。在將應(yīng)用程序遷移到 Kubernetes 之后,我們注意到需要兩倍的主機(jī)數(shù)量。在剖析了應(yīng)用程序并分析了開(kāi)銷之后,我們就對(duì) pod 配置進(jìn)行了優(yōu)化,從而大大減少了需要的額外主機(jī)數(shù)。
Braze 工程總監(jiān)克里斯:實(shí)際上,我們已將所有遺留應(yīng)用程序遷移到容器。將應(yīng)用程序 Docker 化是相對(duì)直接的,在大多數(shù)情況下,可以更輕松地打包依賴項(xiàng)和部署。在此之前,DevOps 管理 EC2 實(shí)例,將應(yīng)用程序復(fù)制到 Chef 并通過(guò) Chef 運(yùn)行它。應(yīng)用工程師把應(yīng)用程序轉(zhuǎn)換成容器后,就可以更直接地控制應(yīng)用程序在什么環(huán)境中運(yùn)行,可以使用什么工具和庫(kù),以及如何分配資源。
困難在于將部署管道的職責(zé)從 DevOps 轉(zhuǎn)移到應(yīng)用工程團(tuán)隊(duì),以及了解如何在 Kubernetes 而非 EC2 實(shí)例上調(diào)試應(yīng)用程序。但是,所有這些都有顯著的長(zhǎng)期好處,消除了反復(fù)修改的需求,并使代碼與運(yùn)行環(huán)境更緊密地結(jié)合在一起。
BetterUp 工程經(jīng)理布萊恩:利用容器進(jìn)行機(jī)器學(xué)習(xí)微服務(wù)的實(shí)驗(yàn)。在主要應(yīng)用中,我們提取了一小部分,并通過(guò)更適合的技術(shù)棧快速啟動(dòng)新服務(wù)。這樣就可以快速迭代和實(shí)驗(yàn)。舉例來(lái)說(shuō),我們可以用 Python 中的神經(jīng)網(wǎng)絡(luò)無(wú)縫替換 R 中的貝葉斯方法訓(xùn)練的模型。
當(dāng)我們將服務(wù)從單體上剝離時(shí),我們面臨的一個(gè)挑戰(zhàn)是,這些服務(wù)不再能直接訪問(wèn)實(shí)時(shí)應(yīng)用數(shù)據(jù)。我們必須決定微服務(wù)將保留對(duì)那些數(shù)據(jù)的訪問(wèn),并且知道越是接近實(shí)時(shí)的服務(wù),就越需要訪問(wèn)上下文數(shù)據(jù)。
DataDog 高級(jí)工程師勞倫:我們依賴 DataDog 來(lái)監(jiān)控。每一個(gè)應(yīng)用都負(fù)責(zé)對(duì)其監(jiān)控進(jìn)行配置,但是有一些關(guān)鍵的指標(biāo)隨處可見(jiàn):容器的 CPU 和內(nèi)存使用情況,容器狀態(tài)和重啟次數(shù),以及底層節(jié)點(diǎn)的健康狀況。起初,我們使用 Spinnaker 來(lái)部署容器化應(yīng)用程序,這在早期提供了一個(gè)強(qiáng)大的基礎(chǔ),但是隨著集群數(shù)量的增長(zhǎng)和工作流程的復(fù)雜性,我們對(duì)此有所改進(jìn)。當(dāng)前,我們正在開(kāi)發(fā)利用 Helm 和云原生應(yīng)用包并由 Temporal 支持的多集群部署的內(nèi)部解決方案。
Braze 工程總監(jiān)克里斯:我們主要看內(nèi)存和 CPU,標(biāo)準(zhǔn)的 Kubernetes 監(jiān)控,以及特定的應(yīng)用指標(biāo),比如內(nèi)部隊(duì)列大小和錯(cuò)誤率。應(yīng)用程序用 Helm 部署,當(dāng)配置(GitHub repo 中的 YAML)發(fā)生變化時(shí),使用內(nèi)部工具通過(guò) Jenkins 將部署配置提供給 Helm CLI。
BetterUp 工程經(jīng)理布萊恩:當(dāng)構(gòu)建在主分支中通過(guò)時(shí),我們使用 Heroku 不斷地部署應(yīng)用程序。通過(guò)使用 Heroku,我們還添加了日志服務(wù)——Pingdom 和 New Relic,結(jié)合了 PagerDuty 的警報(bào),這使得我們可以調(diào)查生產(chǎn)系統(tǒng)中的問(wèn)題,并在發(fā)現(xiàn)問(wèn)題時(shí)通知我們的團(tuán)隊(duì)。同時(shí),我們也使用合成和真實(shí)用戶監(jiān)測(cè)來(lái)發(fā)現(xiàn)嚴(yán)重的錯(cuò)誤和性能問(wèn)題。我們這個(gè)團(tuán)隊(duì)使用 KPI 來(lái)跟蹤基礎(chǔ)設(shè)施的趨勢(shì)。服務(wù)器的正常運(yùn)行時(shí)間是關(guān)鍵的健康指標(biāo),在 2020 年這一指標(biāo)為 99.999%。
DataDog 高級(jí)工程師勞倫:我們沒(méi)有對(duì)容器進(jìn)行系統(tǒng)性測(cè)試。取而代之的是,我們?cè)?CI 中測(cè)試應(yīng)用程序,并在 staging 和 canary(金絲雀)中驗(yàn)證新容器版本。如果我們懷疑容器化對(duì)它有影響,我們還會(huì)臨時(shí)測(cè)試容器,尤其是那些無(wú)法用代碼庫(kù)更改來(lái)解釋的性能下降。
Braze 工程總監(jiān)克里斯:通過(guò) Docker Compose 運(yùn)行,我們的許多應(yīng)用程序都在本地開(kāi)發(fā)和測(cè)試。在運(yùn)行容器化應(yīng)用部署的開(kāi)發(fā)和 staging 環(huán)境中,我們每天也會(huì)數(shù)次運(yùn)行端到端測(cè)試。我們使用 Buildkit,CI 還在 Docker 中運(yùn)行測(cè)試,當(dāng)應(yīng)用程序代碼改變時(shí),測(cè)試會(huì)自動(dòng)運(yùn)行。
BetterUp 工程經(jīng)理布萊恩:測(cè)試容器已進(jìn)行了配置,以與生產(chǎn)環(huán)境匹配。沒(méi)有直接測(cè)試容器本身,但是我們的連續(xù)測(cè)試過(guò)程可以確保應(yīng)用程序在各個(gè)分支中的行為一致。
DataDog 高級(jí)工程師勞倫:由于我們大規(guī)模使用 Kubernetes,并且面對(duì)著生態(tài)系統(tǒng)剛剛開(kāi)始應(yīng)對(duì)的挑戰(zhàn),所以我們更傾向于在早期測(cè)試新技術(shù),并在測(cè)試成功之后再加以采用。比如,當(dāng) containerd 具有容器運(yùn)行時(shí)接口時(shí),我們將其標(biāo)準(zhǔn)化,并且當(dāng) kube-proxy 在測(cè)試版中可用時(shí),我們就將其用于 IPVS 模式,這是處于擴(kuò)展性的考慮。我們最近對(duì) pod 網(wǎng)絡(luò)、服務(wù)負(fù)載平衡和網(wǎng)絡(luò)策略的 Cilium 進(jìn)行了標(biāo)準(zhǔn)化。
Braze 工程總監(jiān)克里斯:我們工程師非常關(guān)心整個(gè)行業(yè)的變化。為了嘗試新的方法,他們嘗嘗鼓足勇氣做出改變,包括在我們的內(nèi)部“黑客日”進(jìn)行概念驗(yàn)證演示,以探索和衡量其他人的興趣。他們關(guān)注 AWS 的公告,Kubernetes 的公告,以及關(guān)于新選項(xiàng)的技術(shù)新聞來(lái)源。遇到問(wèn)題的時(shí)候,他們會(huì)尋找解決辦法,想象出一個(gè)“更好的”樣子。舉例來(lái)說(shuō),我們已經(jīng)做了很多研究,通過(guò)使用 spot 實(shí)例自動(dòng)提供實(shí)例來(lái)節(jié)省成本。
BetterUp 工程經(jīng)理布萊恩:我們依賴工程師來(lái)發(fā)現(xiàn)改進(jìn)我們使用容器方法的機(jī)會(huì),并且我們權(quán)衡了潛在價(jià)值和需求。舉例來(lái)說(shuō),最近我們的前端和全棧工程師在使用 Docker for Mac 時(shí)遇到了文件系統(tǒng)性能的問(wèn)題。我們的一位工程師研究了改進(jìn) Docker 的 IO 的技術(shù),并對(duì) Mutagen、NFS,以及本地系統(tǒng)和 Docker 之間共享文件進(jìn)行了實(shí)驗(yàn)。最后,我們將 Mutagen 引入了整個(gè)團(tuán)隊(duì),極大地改善了開(kāi)發(fā)人員的體驗(yàn)。前端容器的構(gòu)建時(shí)間不再會(huì)影響開(kāi)發(fā)者的生產(chǎn)力。
DataDog 高級(jí)工程師勞倫:從控制平面上的可擴(kuò)展性問(wèn)題到低層的運(yùn)行時(shí)問(wèn)題和網(wǎng)絡(luò)問(wèn)題,我們都遇到過(guò)許多令人吃驚的挑戰(zhàn)。總體而言,在采用容器方面最大的成功在于,它允許我們使用通用抽象在多個(gè)云供應(yīng)商之間進(jìn)行擴(kuò)展和部署。
Braze 工程總監(jiān)克里斯:構(gòu)建用于 localdev 的容器需要其他額外的調(diào)試工具,這在生產(chǎn)環(huán)境中是不可取的。與本地調(diào)試相比,在生產(chǎn)環(huán)境中進(jìn)行調(diào)試更困難,尤其是在托管容器的服務(wù)器上,它有一個(gè)細(xì)粒度的訪問(wèn)控制列表。將面向服務(wù)的架構(gòu)精確地復(fù)制到容器中會(huì)讓筆記本的 CPU 和內(nèi)存負(fù)擔(dān)過(guò)重,這會(huì)導(dǎo)致仍然缺少一些可靠的捷徑,例如不運(yùn)行“真正的” Kubernetes 集群或者相同的配置。與本地構(gòu)建不同,CI 構(gòu)建容器可以輕松地包含本地不存在的內(nèi)容,這可能會(huì)導(dǎo)致難以調(diào)試或識(shí)別。
BetterUp 工程經(jīng)理布萊恩:容器使我們能夠在一個(gè)云供應(yīng)商上訓(xùn)練新的機(jī)器學(xué)習(xí)模型,并且當(dāng)我們準(zhǔn)備將它們與我們的主要應(yīng)用集成時(shí),可以輕松地遷移到另一個(gè)云供應(yīng)商上。令人驚訝的是,我們幾乎沒(méi)有遇到任何與容器本身相關(guān)的問(wèn)題。一般情況下,任何問(wèn)題都存在于比容器級(jí)別更高的抽象層次;例如,我們?cè)诓渴饝?yīng)用程序時(shí)發(fā)現(xiàn)了一些錯(cuò)誤,但這些錯(cuò)誤并不特定于容器的使用。
- END -
推薦閱讀 Kubernetes實(shí)戰(zhàn)指南:從零到架構(gòu)師的進(jìn)階之路 Kubernetes 中網(wǎng)站無(wú)法訪問(wèn),深入排查實(shí)戰(zhàn) Nginx 常用配置清單 Prometheus + Thanos 多集群架構(gòu)監(jiān)控 Jenkins 流水線自動(dòng)化部署 Go 項(xiàng)目 最強(qiáng)整理!常用正則表達(dá)式速查手冊(cè) 運(yùn)維的工作邊界,這次真的搞明白了! Linux 這些工具堪稱神器! Prometheus + Granafa 構(gòu)建高大上的MySQL監(jiān)控平臺(tái) 搭建一套完整的企業(yè)級(jí) K8s 集群(v1.20,kubeadm方式) 12年資深運(yùn)維老司機(jī)的成長(zhǎng)感悟
點(diǎn)亮,服務(wù)器三年不宕機(jī)


