容器并不能解決一切問題
容器化在開發(fā)和運(yùn)維領(lǐng)域掀起了一場(chǎng)風(fēng)暴。在過去,部署是高度依賴于特定技術(shù)的,通常需要對(duì)每個(gè)項(xiàng)目進(jìn)行大量不可重復(fù)的工程工作。你是否部署到 VPS?你是否在分法虛擬機(jī)鏡像?靜態(tài)可執(zhí)行文件?需要特定解釋器的腳本? 根據(jù)你對(duì)這些問題的回答,你可能已經(jīng)使用了 Capistrano、Puppet、shell 腳本、Ansible、deb 或 rpm 包、cloud-init 腳本、專有云技術(shù)、upstart、systemd、init 等很多技術(shù)。在部署階段,系統(tǒng)管理和開發(fā)之間的界限就變得模糊了,DevOps 的原則就誕生了。隨著 DevOps 開始成熟,業(yè)界發(fā)展出了應(yīng)用開發(fā)的最佳實(shí)踐,比如 12 因素應(yīng)用程序方法論,但許多實(shí)現(xiàn)細(xì)節(jié)仍然是依賴于特定技術(shù)的。

然后 Docker 出現(xiàn)了,并通過如下簡(jiǎn)單的規(guī)則使應(yīng)用程序的部署產(chǎn)品化:如果你的應(yīng)用程序可以打包成一個(gè)容器,那么它就可以部署在任何地方。容器并不是什么新鮮事——畢竟,谷歌已經(jīng)使用它們很多年了。Unix 黑客也曾出于類似目的使用 Solaris Zones 和 FreeBSD jail。然而,在 Docker 出現(xiàn)之前,還沒有一個(gè)很好的方式可以輕松地將應(yīng)用程序打包到一個(gè)可移植的容器中。Docker 徹底改變了我們部署應(yīng)用程序的方式。
Docker 解決了許多重要的部署問題,所以接下來要問的問題是 Docker 是否為開發(fā)提供了任何優(yōu)勢(shì)。擁有一個(gè)看起來(至少大體看起來)像生產(chǎn)環(huán)境的開發(fā)環(huán)境有很多好處。如果你在生產(chǎn)環(huán)境中部署 Docker 容器,那么在開發(fā)過程中在容器中運(yùn)行代碼也是合理的。此外,Docker 還解決了版本依賴關(guān)系的問題。例如,如果你有一個(gè)應(yīng)用程序需要 MySQL 5.3,而另一個(gè)應(yīng)用程序需要 MySQL 5.7,那么你就不需要在本地運(yùn)行兩個(gè)版本,也不需要在各自的虛擬機(jī)中運(yùn)行每個(gè)版本。你可以為每個(gè)版本使用一個(gè)容器,它們可以在幾秒鐘內(nèi)啟動(dòng)和停止。

2013 年底,Docker Compose(當(dāng)時(shí)稱為 fig)進(jìn)入了這個(gè)領(lǐng)域。Docker Compose 有一個(gè)簡(jiǎn)單的前提:與使用一次性腳本啟動(dòng)和停止應(yīng)用程序及其在開發(fā)中的依賴不同,你把它們描述為 YAML 文件中的 Docker 容器,并讓 Docker Compose 管理它們的生命周期。它提供了一些額外的細(xì)節(jié),如為 12 因素應(yīng)用程序提供日志采集、環(huán)境變量以及基本容器網(wǎng)絡(luò)。簡(jiǎn)而言之,Docker Compose 對(duì)那些想要使用容器化的方法開發(fā) 12 因素應(yīng)用程序的開發(fā)人員來說是一種完美工具。
乍一看,Docker Compose 似乎是本地開發(fā)的理想解決方案——在許多情況下,它確實(shí)是。然而,就像它的名字一樣,它只關(guān)注那些一切都在 Docker 內(nèi)部運(yùn)行的開發(fā)工作流。在某些情況下,這樣做很好。例如,如果你在 Node.JS 中編寫一個(gè)依賴于 Postgres 的 API,那么你可以在 nodejs 容器中運(yùn)行代碼(可能在它前面有一個(gè)文件監(jiān)視器),在 Postgres 容器中運(yùn)行 Postgres。然而,并不是所有的開發(fā)工作流都可以被容器化。無論是為了性能、易于與主機(jī)操作系統(tǒng)特性集成,還是其他許多原因,有時(shí)最好將開發(fā)環(huán)境的某些部分作為本地進(jìn)程運(yùn)行,而將其他部分作為容器運(yùn)行。你仍然需要拼湊一個(gè)解決方案,以將非 Docker 部分與一些 Docker 容器進(jìn)行集成。
此外,考慮到 Docker 依賴于 Linux 內(nèi)核特定的特性來實(shí)現(xiàn)容器,macOS、Windows、FreeBSD 和其他操作系統(tǒng)的用戶仍然需要虛擬化層。我們想要通過使用容器來擺脫的一系列復(fù)雜的網(wǎng)絡(luò)、文件同步和虛擬機(jī)管理等問題仍然存在。當(dāng)然,它們通常是可以工作的——直到出現(xiàn)問題,這時(shí)我們就只剩下谷歌、Stack Overflow 和 GitHub 來幫助我們找到解決方案。

快進(jìn)到 2021 年,大多數(shù)生產(chǎn)級(jí)應(yīng)用也依賴于云基礎(chǔ)設(shè)施,這些基礎(chǔ)設(shè)施不能作為本地 Docker 容器運(yùn)行,因此我們面臨一系列新的問題,每個(gè)問題都需要權(quán)衡:
我們是否將云服務(wù)存根?這種方法成本低、性能好,但除了非常簡(jiǎn)單的服務(wù)外,維護(hù)本地存根所需工程量很高。
每個(gè)開發(fā)人員是否都有自己的每個(gè)云資源實(shí)例?這通常代價(jià)高昂,公司必須支付很高的成本來保留很少使用的基礎(chǔ)設(shè)施。無服務(wù)器產(chǎn)品通常比預(yù)留產(chǎn)品有更好的成本模型,但仍然必須考慮成本。
開發(fā)人員是否共享共同的開發(fā)基礎(chǔ)設(shè)施?在此選項(xiàng)中,基礎(chǔ)設(shè)施成本降低了,但通常需要額外的工程量,以便多個(gè)應(yīng)用程序可以共享相同的數(shù)據(jù)庫(kù)和其他有狀態(tài)服務(wù)而不會(huì)發(fā)生沖突。換句話說,每個(gè)應(yīng)用程序都必須支持多租戶。
以上選項(xiàng)在不同的場(chǎng)景中都是可行的,但這里要說的是采用 Docker 或者 Docker Compose 并不能解決問題——甚至不能指出哪個(gè)選項(xiàng)是最好的!現(xiàn)代開發(fā)環(huán)境編排器必須具有云感知能力并支持不同的運(yùn)行時(shí)架構(gòu)。目前,基礎(chǔ)設(shè)施即代碼工具最接近解決這個(gè)問題,但由于它們專注于生產(chǎn)部署,因此無法與本地開發(fā)環(huán)境順利集成。
除了云服務(wù),微服務(wù)還具有它們自身的復(fù)雜性,這些復(fù)雜性是“僅僅使用 Docker”無法解決的。任何采用了微服務(wù)策略的大型組織都會(huì)迅速發(fā)展到任何開發(fā)人員都可以在其筆記本電腦上運(yùn)行該組織所有服務(wù)的地步。像 Telepresence 這樣的工具有助于將本地容器連接到遠(yuǎn)程 Kubernetes 集群中運(yùn)行的容器,但我們?nèi)匀蝗狈δ軌蚩绫镜睾瓦h(yuǎn)程環(huán)境透明地處理服務(wù)發(fā)現(xiàn)、代理和身份驗(yàn)證等問題的高級(jí)工具。而且,現(xiàn)有的工具大多是以 kubernetes 為中心的,這給很多開發(fā)人員增加了使用難度。
我們的行業(yè)在過去十年中取得了令人難以置信的進(jìn)步,這在一定程度上要?dú)w功于 Docker、Docker Compose 和 Kubernetes 等技術(shù)。然而,我們?nèi)栽谘芯咳绾卧谖覀兯幍亩鄻踊h(huán)境中進(jìn)行開發(fā)。下一代開發(fā)工具必須能夠處理本地進(jìn)程、Docker 容器、云服務(wù),甚至其他團(tuán)隊(duì)的微服務(wù)的構(gòu)建和運(yùn)行。針對(duì)所有這些問題,我們還沒有答案,但我們正在構(gòu)建 exo,以幫助像我們這樣的開發(fā)者克服本地開發(fā)的復(fù)雜性。
原文鏈接:https://blog.deref.io/containers-dont-solve-everything/
往期推薦
點(diǎn)個(gè)在看少個(gè) bug???
