1. 程式人生 > >Docker:一場令人追悔莫及的豪賭

Docker:一場令人追悔莫及的豪賭


每當我對Docker提出批判時,都會收到很多憤懣的回覆。我曾於6個月前撰寫一篇文章,即《 為什麼有人會選擇Docker而非大型二進位制檔案?》,並終於在Hacker News上眾多憤慨的批評聲中看到了一些明智的評論。因而,今天的這篇文章主要是進一步闡述Docker的設計缺陷並回應未來可能將會面臨的批判。

相比HFT Guy的經歷而言,我想我已經足夠幸運了。HFT Guy曾滿腔怒火地表示,由於在金融公司的產品生產階段使用了Docker而導致失敗,想來其必然為此付出了不小代價。原文引用如下:

我收到了一份十分無禮的郵件,發件人明顯是業餘社群中的一員。這位仁兄在郵件中憤怒地表示:“白痴才會在Ubuntu上執行Docker。”該郵件中還隨附了一份軟體程式包列表以及在Ubuntu上執行Docker所需的高階系統調整方案。另外,這封郵件還特地表示:“任何人都可以通過谷歌在5秒內找到列表中的相關內容。”
人們傾向於在網上發洩其憤怒——儘管我不知為何,但事實的確如此。並且,當開發人員發現有人抨擊其所深愛的技術時,往往會奮起反擊,進而引發一場口水戰。然而,這種不良情緒矇蔽了他們了雙眼,以至於其無法辨識相關方案有關現實使用方面的長遠意義。

Docker承諾其能夠提供可移植性、安全性以及資源管理與編排能力。因此,理智的人們自然希望瞭解:“Docker是否真的是獲取可移植性、安全性以及資源管理與編排能力的最佳方式?”

在此之前,我想先回應我所收到的部分回覆。儘管大部分回覆中所持有的觀點根本不值得討論,但有一個論點引起了我的注意——我將在文末對其詳加闡述。

有評論如下:

由於使用Docker所涉及的資源較少,並且與是否需要對相關資源進行處理以及使用方現有的處理能力無關。
是的。但參考物件又是什麼呢?是讓開發人員編寫指令碼以實現標準化構建、部署、編排以及資源使用嗎?上述評論似乎想要表達的是“我並不是說開發人員應該選擇這類操作,因為結果已經客觀存在; 我的意思是希望其能夠實現標準化。”

開發人員與管理人員偏愛Docker的原因無外乎其所提供的功能自定義空間有限、相對不那麼混亂、更長久且更加標準化——或者起碼存在實現這類效果的機會。然而事實上,Docker迄今為止帶來的只是一團令人難以置信的亂麻(更多詳細資訊請參考:《
生產階段的Docker:一段失敗的歷史
》)。儘管如此,仍然有很多人願意相信目前Docker所存在的問題不久即可得以解決,並且屆時Docker就能夠為容器化場景提供穩定且一致的標準。這無疑是一場關於Docker的豪賭!幾乎所有參與這場“賭博”的公司都為此付出了慘重的代價,但仍然有公司繼續為此投注,以期有朝一日能夠由此獲取豐厚的回報。

在過去的兩年時間裡,我曾合作過的每家公司不是在使用Docker,就是在擬定有關使用Docker的計劃。實際上,這些公司都為獲取標準化解決方案付出了高昂的代價。

更可怕的是,我還沒有聽到任何一位技術管理者明確對這種“賭博”現狀作出陳述。大多數支援Docker的群體仍在不斷強調其帶來的可移植性、安全性或者編排與配置能力。沒錯,Docker確實能夠為我們提供可移植性、安全性或者編排與配置能力,但其代價也相當可觀。在大多數情況下,編寫特定指令碼反而難度更低。

在我個人認為最出色的Docker論述文章當中,作者強調了使用Docker所帶來的利弊權衡:

最好將Docker視為一種高階優化方案。沒錯,它很酷且功能相當強大,但其同時也會增加系統複雜性,且只有專業的系統管理員才能夠理解如何在生產中安全使用Docker並將其部署在關鍵性任務系統之內。
就目前來看,您需要掌握更多系統專業知識才能使用Docker。事實上,幾乎所有Docker相關文章都只展示過分簡單的用例,而忽略了在多主機生產系統上使用Docker所帶來的複雜性挑戰。這無疑給人們留下了Docker的實際生產應用非常簡單易行這一極為錯誤的印象。
在計算機程式設計領域,流傳著這樣一句至理名言:“不成熟的優化是萬惡之源”。然而,今年以來我們的大部分客戶都堅持“我們必須從起步階段就全部實現Docker化。”因此不同於傳統最初最佳實踐要求的建立一套工作系統、將其投入生產、最後考量Docker能否帶來比較優勢的作法,客戶們開始盲目推動Docker的標準化開發與部署。

可能很多朋友都遇到過以下場景:

我:“我們不需要在專案早期使用Docker。”

對方:“這款應用需要Nginx、PostGres以及Redis和一大堆環境變數。如果不用Docker,要怎麼進行設定?”

我:“我可以寫個Bash指令碼、用make命令,或者使用其它型別的安裝程式。反正方案多種多樣,這麼多年來我們一直都有辦法。”

對方:“這簡直是瘋了。Bash指令碼有可能中斷,你就得花時間除錯;而且跟容器相比,它不一定能在其它機器上正常執行。使用Docker,我們可以編寫build指令碼,而且保證它能夠在任何一臺機器上正常執行。”

很明顯,這就是典型的銷售代表場景——他們只會強調Docker最吸引人的特性。作為一款開發工具,Docker看起來確實擁有更出色的一致性水平,而且不像其它方案那麼混亂。但在實際使用過程中,特別是在生產環境當中,Docker帶來的往往只有痛苦。

您的開發團隊可能擁有一位使用Windows機器的開發者、一位Mac使用者、一位已經安裝Ubuntu的開發者,外加一位使用紅帽Linux的開發者。對於身為團隊負責人的您來說,對他們使用的機器進行全面控制幾乎是個不可能完成的任務。而乍看之下,Docker似乎能夠確保在各類平臺上提供相同的開發環境。(但這裡我要提一句,千萬別在Windows環境中使用Docker——任何告訴你Docker能夠簡化Windows機器開發流程的傢伙都是在給你挖坑。)

但在實際生產過程當中,您將能夠完全控制生產環境中執行的機器。如果您希望在CentOS上實現標準化,完全沒有問題。您可以掌控數千臺CentOS伺服器,並利用舊有技術(例如Puppet)確保這些伺服器擁有同樣的執行環境。這意味著Docker並沒有傳說中那麼重要。相比之下,在利用Docker進行開發時,開發人員往往會認為實際生產環境也將由Docker構建而成——但事實並非如此。

我當然可以列舉更多與Docker問題相關的實際案例,但這些例子真的非常無聊。目前已經有大量博文在討論Docker設計缺陷,相信您對這些已經有所耳聞——除非您身為Docker鐵粉,而且對一切反對意見都視而不見。對於這部分朋友,他們會直接忽略此類文章,或者在勉強讀完之後表示“Docker生態系統正在迅速發展成熟,相信到明年其就會非常穩定且適合用於實際生產。”這樣的話在過去五年中每年都會出現。沒錯,也許這樣的論斷最終會變成現實,但回到開頭——這是一場危險的豪賭。

儘管Docker存在上述問題,但其似乎仍然獲得了成功——與我們使我幾乎每家企業都渴望投向Docker的懷抱。為什麼?據我所知,標準化是其中最為核心的理由。

再次強調,在發表於Hacker News上的文章的評論中,網友“friend-monoid”這樣評價Docker:

我們擁有大量以不同語言編寫而成的HTTP服務。以[超級]二進位制方式對其進行整體管理是件苦差事——編寫者必須提供一種用於埠設定及地址監聽的方案,而我必須追蹤每一種埠設定方式。有了net名稱空間與更智慧的iptables路由,Docker能夠幫助我完成這項任務。
網友notyourday則給出了深得我心的迴應:

當然,如果你採用其它方法並且遵循同樣的編寫方式與規則,也能達到同樣的效果。事實上,後者的效果可能更好,因為其會提供更智慧的名稱空間與iptables,甚至允許你完全不用分心於應用程式的運作狀態。
網友anilakar迴應notyourday道:

在我看來,這正是Docker技能具備可轉移性的核心所在。也就是說,如此一來,剛剛招聘的新人也能夠很快上手新工作。很多企業仍然在使用能夠切實滿足基業務需求的構建/部署系統,但卻無法提供能夠在企業之外繼續發揮作用的實用經驗。
據我所知,這基本總結出了Docker的真正優勢所在。沒錯,Docker的優勢根本不在於能夠讓應用的部署、安全保障或者編排變得更加輕鬆——這完全 就是無稽之談。事實上,Docker成為標準的惟一理由,就是人們能夠將自己在一家企業中積累到的經驗應用於另一家企業。Docker不像自定義Bash指令碼那麼混亂且獨特。然而,這是否值得我們押上一切?

但說句不中聽的,我覺得上述爭論其實是混淆容器技術與Docker。而且相當一部分Docker支援派是在故意混淆這個問題。容器技術本身確實是個先進的概念,但由單一公司掌控的Docker卻不可避免地存在著一定問題。繼續來看HTF Guy給出的觀點:

Docker不具備商業模式,也無法實現貨幣化。公平地講,Docker公司正在以絕望的方式將其推向全部平臺(Mac/Windows),並將所有功能特性硬湊在一起(Swarm),從而:1)確保任何競爭對手都不具備任何顯著的獨特性;2)確保每個人都使用Docker及Docker工具;3)將客戶完全鎖定在其生態系統當中;4)在此過程中釋出大量新聞、文章與報道,增加炒作熱度;5)證明其估值的合理性。
Docker幾乎完全不可能面向多種產品及市場進行水平與垂直擴充套件。(這裡我們姑且不論這種擴充套件是否屬於適當或者說可持續的商業決策,這又是另一個議題了。)
與此同時,Amazon、微軟、谷歌、Pivotal以及紅帽等競爭對手則在以各種方式進行競爭,而且通過容器賺到了遠超Docker的回報。事實上,CoreOS也在開發作業系統並憑藉其Rocket容器化技術參與競爭。
因此,即使您認同容器技術當中蘊藏的巨大能量,並高度讚揚由其帶來的設定一致性能力,也並不同改變Docker本身根基不穩的事實。

好吧,這裡我們暫時把Docker和容器看成是同一種東西。在這樣的立場之下,我們再來回顧我之前發表的文章,看看其中哪些批評意見仍然符合現實。

我在前文當中錯誤地使用“大型二進位制檔案”這樣的表達,並導致了很多誤解。幾小時之後,我釋出了以下免責宣告:

在這篇文章中,我使用“大型二進位制檔案”來表達一個包含所有依賴性的二進位制檔案。我的本意並不是指整個32位與64位轉換。如果單純立足Java與JVM領域,我會使用“uberjar”一詞。但之所以沒有使用,是因為我希望在表述中涵蓋值得肯定的GO語言及其生態系統。
如果再來一次我絕對會使用“超級二進位制”這個詞,雖然它代表著我個人的工作主要集中在JVM領域,但其表意相對更為準確。這已經是我能想到的最好的表達,因此在這篇文章中,我轉而使用“超級二進位制”的說法。

我希望開發者們能夠意識到,他們最喜愛的計算機程式設計方式可能並不適用於雲端分散式計算體系。這裡我要反覆強調這一點,而且相信很多開發者已經感覺到,雲端計算體系需要越來越多地適應他們編寫的PHP程式碼、Ruby程式碼或者是Python程式碼,而他們卻從來不會在程式碼層面適應這個新的世界。

如果您正在著手啟動新專案,並預計其規模將會逐漸增大——您可能需要因此考慮其可擴充套件性,或者單純重視高可用性——那麼您可以使用專為雲環境設計的現代語言。目前,很多新語言都能提供前所未有的新鮮特性,我個人使用過且給我留下深刻印象的有Go和Clojure。我個人對Rust、Scala以及Kotlin經驗不多,所以沒法討論太多。當然,它們應該也非常出色(在以往的文章中,很多讀者朋友認為我是故意忽略了一些語言。我絕不是故意侮辱這些語言,但限於個人接觸範圍,我只會提及自己實際使用過的方案)。我讀過一些與Scala Akka框架的文章,並發現其中包含不少非常精彩的思路。因此雖然沒有實際使用過,但我認為其確實設計水平極高且充滿現代感。

在我早前的文章中,網友btown寫道:

任何認為一切現代Web應用程式都是使用Golang或JVM開發完成的人,都生活在一種奇怪的自我認知迴圈當中。
再次強調,很多語言都非常出色; 但我不可能瞭解所有語言,因此只能對其中一些我親自接觸過的語言作出評價。另外,我也會批評自己曾經使用過的舊有語言——包括PHP、Ruby以及最近人氣爆棚的Python。它們源於一種舊有正規化工,因此不適用於雲端的微服務與分散式架構。我曾在《 Docker正保護我們需要儘量擺脫的程式設計正規化》一文中對此進行過探討。現在看來,似乎大家並沒有認真考慮這個問題。我想起2000年前後,面向物件程式設計掀起的狂熱浪潮達到頂峰。那時候,幾乎沒人敢站出來反對這種模式。科技行業一直認為自身是完全開放的,但實際上其中仍充斥著各類驅動因素。在接下來的幾年中,各參與者紛紛退卻,留下一地雞毛與吃瓜群眾們的嘲笑聲。結合本文的主旨,2000年XML與面向物件程式設計出現了過度炒作,而如今的Docker亦處於同樣的狀態之下。

Clojure語言我用得比較多,而其似乎非常適合用於編寫應用程式並建立繫結依賴關係的uberjar。我也很清楚如何建立起像Jenkins這樣的系統,因此我的Clojure build完全能夠實現自動化執行。我聽說很多企業選擇了令人難以置信的極端路線,其在構建無外部依賴關係的應用程式時,會將資料庫等全部繫結在uberjar當中。請參考《 利用Clojure與AWS在7個月中實現600倍增長》一文中的內容:

這推動了決策二的出爐。由於資料集體積較小,因此我們能夠將整個內容資料庫新增至我們的某一版本當中。沒錯,您沒看錯。我們利用Solr的一個嵌入式例項構建我們的軟體,並採取標準化、清潔化非關係資料庫作為酒店庫存管理方案,並將其共同塞進應用程式部署方案當中。
我們利用這種非傳統處理方式得到了巨大收益。首先,我們消除了重要的故障點——即程式碼與資料間的不匹配問題。任何版本的軟體都將能夠正常工作——即使多年後我們將其轉移至其它系統當中,且在此期間對內容資料庫作出各類改動,都不會影響這一結果。在這種情況下,針對不同環境的部署與配置管理工作變得極為輕鬆。
其次,我們在面向使用者層中實現了橫向無共享可擴充套件性。其擴充套件能力相當相當可觀。
如果不需要引入新技術(例如Docker)就能實現這種大規模擴充套件,那麼當然沒必要多此一舉。以最簡單的方式解決問題才是我們應當堅持的原則。如果從Ruby/Python/Perl轉向新的語言及生態系統,而且能夠以更少的技術與移動部件實現規模化,那麼大家應當甚至說必須採取這樣的處理方式。再次強調,我們的原則是儘可能以最簡單的方式實現目標,而且在大多數情況下這意味著您應儘可能降低所使用技術的數量。受到Rich Hickey的啟發,我將“簡單”與“簡易”區分開來。使用一門您已經瞭解的語言非常“簡易”,學習一門新語言很困難——但後者卻更“簡單”,或者說能夠減少系統中的技術總量。這裡的“簡單”意味著您的系統最終能夠以更簡單的方式運作——其程式碼規模更小、配置更單純或者使用的技術數量更少。

在此前文章的評論當中,不少讀者朋友認為我總是提到Jenkins的作法代表著我的心態已經過時——但有時候必須承認,無聊的東西不一定就不好:

無聊的好處(限制水平較高)在於,這些東西的功能相對更容易理解。而更重要的是,我們能夠更輕鬆地瞭解其故障模式。……但對於閃閃發光的新技術而言,其中的未知因素要多得多,這一點非常重要。
換句話來說,已經存在了十年的軟體更易於理解,而且未知因素更少。未知因素越少,運營開銷越低,這絕不是壞事。
我意識到,很多開發者都存在著極強的偏見。在閱讀這類文章時,他們傾向於揪住一個理由來駁斥整篇文章。因此如果我提到Jenkins、Ansible、Go、Clojure、Kotlin或者Akka等任何技術方案,他們都會專注於尋找這些技術中存在的缺陷,以此將文章本身貶得一文不值。而除了新增免責宣告之外,我不知道要怎樣才能跟這部分讀者朋友真正溝通——事實上,我覺得即使是添加了宣告,不想聽的讀者也仍然不會聽。

在之前的文章中,網友tytso寫道:

關於Go語言是大型二進位制檔案先驅的說法很明顯是錯誤的。數十年以來,人們一直在利用靜態二進位制檔案(有時候會配合內建資料資源)解決這個問題。MacOS就是其中的代表。
在這裡,我要對自己的表意不清問題表達歉意。我實際上想要表達的是將所有依賴關係、一切必要配置乃至全部必要的資源都塞進同一個二進位制檔案,從而簡化整體系統資源機制的作法。這種實踐方式在概念範圍上比簡單的靜態庫連結更為廣泛。現代持續整合系統可通過配置以確保各二進位制檔案皆被給予特定配置詶,而這些配置資訊可能以惟一方式對應二進位制檔案的特定例項。因此即使您需要同時運行同一應用程式的上千個例項,亦可構建起上千個在配置方面略有區別的例項變種。當然,您可以使用Jenkins這類相對陳舊的構建系統完成這項任務。這些系統易於理解,但在另一方面也確實比較無聊。但無聊不應該成為您選擇Docker的理由——其可能帶來可怕的複雜性挑戰。(當然,請別糾結於我在這裡將Jenkins作為例子的情況,大家也可以根據喜好選擇Travis、TeamCity或者Bamboo。我常常驚訝於很多開發者居然會因為一種方案的選擇而放棄對整篇文章的認同甚至是閱讀。)

有些讀者表示:

Docker能夠保護使用者免受雲服務供應商鎖定問題的影響。
當然不是。任何一款標準化部署DevOps工具都能幫助我們解決供應商鎖定問題。而且,這類工具選項可一點都不少見:

網友friend-monoid 寫道:

如果我的同事無需瞭解如何正確部署應用程式,那麼他們的工作內容將得到顯著簡化。如果我可以將他們的工作成果放進容器當中,而無需因語言或風格而受到影響,那麼我的工作內容也將得到顯著簡化。我不必再為處理崩潰、無限迴圈或者其它程式碼錯誤而分神。
網友notyourday的迴應則與我的態度不謀而合:

當然了,因為你只是把這套邏輯搬到了“編排”與“管理”層當中。你仍然需要編寫程式碼以正確執行。就算給豬畫口紅,豬也仍然是豬。
更何況,如果您身在一家小公司,而且開發人員總共只有幾個人,那麼將不可避免地處理彼此的程式碼結果。而如果您身在大型企業,那麼其中將具有獨立於開發團隊之外的DevOps團隊——他們多年來一直專注於處理此類問題,包括利用各類健康狀態檢查方案。健康檢查同樣涉及程式碼編寫,Docker的標準化範圍並不能涵蓋這部分工作。作為應用的開發者,您需要建立對應端點,從而將200條響應傳送給DevOps以進行定期測試。在這種情況下,Docker實際上起不到任何作用。大部分DevOps團隊都擁有專門用於測試應用程式是否活動的指令碼,如果目標應用沒有響應,那麼其將被終止並重新啟動。

網友Lazare寫道:

舉例來說,我正利用指令碼語言(例如Ruby、PHP或者Node.js)構建基於舊式指令碼模式的現有程式碼庫。
.……我可以考慮如何將全部現有程式碼打包進Docker容器當中,並配合一些編排方案,而後進行釋出。
根據這篇文章,我發現作者認為用(超級)二進位制檔案的效果更好。但情況是這樣的:您可以對PHP應用程式進行Docker化,這並不困難。但我們要如何構建起(超級)二進位制檔案?如果你的答案是“用Golang重寫整套程式碼庫”,那這顯然毫無意義;我們首先沒有足夠的資源完成這項工作,其次就算這樣做了,我們也不打算採取這種毫無價效比可言的方法。最後,無論如何,我們都不喜歡Golang語言。
在這個例子當中,這家企業長久以來一直在使用PHP應用程式,現在的目標則是對該應用程式進行Docker化。為什麼會有這樣的結論?發生了哪些變化,導致該應用程式需要進行Docker化?這就像是一個人為設定的例子。在Docker化之前,您的應用程式運作情況如何?舊有方法的問題是什麼?您覺得Docker能夠解決這些問題嗎?

這款應用程式的最終目標是否能夠與其它(或者其自身的更新版本)應用程式實現編排與協調?Docker加編排通常意味著Docker加Kubernetes。(當然,您也可以選擇使用Mesos或者Nomad等來代替Kubernetes)。這是一套非常複雜的組合方案,企業在選擇這一道路前應該進行認真思考。請參閱《 K8s是否太過複雜?》如果您的應用規模不大,那麼對其進行整體重寫其實是個不錯的選擇; 而如果您的應用規模龐大,那麼您應該思考是否存在其它更為簡單的實現途徑——例如編寫一些Chef或Ansible指令碼。

我曾經遇到過一款規模龐大的整體式應用,其以PHP編寫而成,且使用到Symfony框架。這款應用出現了糟糕的效能問題。我們開始逐步對其進行拆分——將用於進行HTML模板渲染的Symfony保持原狀,而對真正決定效能的部分以其它語言進行重新編寫。我在《 小型應用的架構問題》一文中已經對此作出了陳述。當時,DevOps團隊正在利用Puppet及一些自定義指令碼處理部署工作。這對我們來說已經足夠了。無聊而穩定的技術,確實能夠起到很好的效果。

請記住,您的時間是有限的。無論您投入多少時間對自己的PHP程式碼進行Docker化,您的時間都被佔用了——這意味著您無法利用其完成其它現代化轉型。因此,請確保投入能夠帶來切實回報。

而讓人感到奇怪的是,人們在討論Docker時,往往並不會列舉那些真正需要進行編排的應用示例。我見過在Spark上長時間執行的資料分析指令碼,其利用Nomad進行編排。我意識到這是一套龐大的系統,其每天都會將數TB資料新增至Kafka當中,而後來到Apache Storm,最後是ElasticSearch。這套系統擁有一套複雜的執行狀態檢查與監控功能,但對於大部分工作而言,Storm本身就可以充分編排工具。Web應用程式需要在處理海量資料之前,首先處理大量業務流程。Twitter就面對著規模可觀的資料,其利用Aurora進行編排。您的規模能夠與Twitter相提並論嗎?如果您在普通網站上使用Docker與Kubernetes,請馬上停下——我們有眾多更簡單的網站執行方法。我已經擁有長達25年的建站經驗,相信我,絕大多數網站都不需要Docker。

網友mwcampbell寫道:

“我真的不太贊同投入大量精力保持舊有技術正常執行的作法。”
我強烈反對這部分內容。為了真正在技術與文明方面取得進展,我們需要確保自己不會浪費時間重新創造業已存在的解決方案——換言之,我們應保持舊有技術的運作。因此,如果Docker能夠讓2007年編寫完成的Rails應用正常執行,那實在是太讚了。事實上,我們仍然應該使用Rails、Django以及PHP等開發新的應用程式。即使不再時髦,我們仍有理由使用這些已經非常成熟的平臺與工具。
“時髦”這個詞不禁讓我想到技術領域廣泛存在的一種錯誤認知。我們能不能停止這種對時髦的盲目追捧?舉例來說,非要把技術與流行文化混為一談,就好像是認為搖滾音樂黃金年代出現的一切音樂作品如今都已經沒有存在的必要。相反,好的技術並不是流行音樂; 在1993年能夠順利執行的方案,沒準也仍然適合如今的需求場景。
這是一條明顯屬於反話的評論。很明顯,自認為清醒的現實主義者認為我們應該把一切東西都Docker化,但像我這樣的瘋子則認為我們應該繼續使用舊有DevOps工具並將其與新型語言加以結合。在其看來,我的選擇是受到了“時尚”的驅動,而他們對Docker的熱愛則是出於“真正在技術與文明方面取得進展”的偉大願望。

我的觀點是,只要陳舊而無聊的技術仍然能夠發揮自己的分內作用,且不會因繼續使用而帶來額外的成本,我們就應該繼續加以使用。但當技術的執行方式發生重大變化時,我們應當自問,某些技術是否已經不再適應新環境的需求。更具體地講,隨著雲端計算以及雲環境下微服務架構的興起,我們必須重新思考自身對技術方案的選擇。其中的指導原則應該是,“我們完成當前目標的最簡單方法是什麼?”如果舊有技術能夠完成目標,而且也屬於最簡單的方法,那麼其就應該是最優選擇。但如果新技術能夠幫助我們簡化系統,那麼我們就應該積極接納這種新方案。

網友chmike寫道:

容器不僅是依賴關係的解決方案,同時也能夠有效保護邊界。
網友neilwilson則迴應稱:

這只是chroot的花哨強化版。不要相信那麼多Docker宣傳。多年以來,明智的管理員一直在做類似的事情,只是我們不會花大價錢進行公關推廣。
這也代表了我個人的全部意見。

在前文中,我曾經提問“為什麼不使用不存在外部依賴關係的超級二進位制檔案?”大家可能會回答,“Docker就是這麼做的!它就是一個大型二進位制檔案,其中包含了應用程式執行所需要的一切!而且它還不依賴於任何語言!你可以使用其配合Ruby、PHP、Python、Java、Haskell乃至一切語言!”

說得沒錯,但我建議企業應該尋找機會減少其使用的技術方案的數量。也許大家可以利用現代語言與生態系統,從而以原生方式實現這種超級二進位制設計。

很多人認為Docker的反對者們之所以提出批評,是因為其沒有能力變更其所在企業中的技術方案。但我們的假設是,企業實際上是在自發使用異構混合技術,其中也包括一些不適合在雲中以分散式計算實現的舊有技術。因此,Docker其實是一種“隱身咒”,其實際作用就是隱藏企業無法調整自身語言與生態系統以適應雲端分散式計算架構的現實問題。

從長遠角度來看,這種拒不改進的態度會毀掉一家企業。我不造成一味追求科技領域的最新潮流,但我支援不斷重新評估最有利於企業自我技術成果。目前,計算的總體實現方式正在發生變化,而被動接受傳統應用終將成為企業的痛點,其會隨時間推移而拖慢企業的發展速度。而真正到傳統應用程式無法繼續執行時,重新編寫將給企業帶來更大的風險。如果企業能夠找到方法對現有應用程式進行拆分與現代化轉型,那是再好不過。事實上,微服務架構最重要的特色就是其允許舊有應用程式以增量化方式實現現代化。我在《 漸進式改善的珊瑚礁模式》一文中已經談到過這一點。

在前文中,我提到過一家分析企業,其每天需要向Kafka當中新增上TB資料,而後將其分發至Apache Storm,最後再到ElasticSearch。這家企業長期以來一直使用Python。當遇到效能問題時,他們希望使用Python併發系統(例如Tornado)在其系統中實現大規模併發。他們將這個專案交給一位非常出色的工程師(他此前在英特爾公司效力),並給了他3個月時間進行新系統構建。結果——完全失敗。他們無法獲得自己希望得到的效能提升,Tornado甚至無法帶來他們所期望的細粒度併發能力與併發水平。最後,他們終於接受了這樣一個現實——他們不可能在各個層面都始終堅持使用Python。如今,他們開始轉向Go與Elixir,並承認這才是能夠真正解決問題的辦法。(我相信這家企業肯定有點受傷——他們是真正的Python支持者,也是一群理想主義者。)

我對他們採取的重新評估方法表示造成,但我認為企業應該將這一環節納入運營體系並定期執行。

下面是來自網友pmoriarty的最強Docker支援論據:

你也可以對一切配置管理工具(Ansible/Chef/Salt/CFEngine/Puppet)提出幾乎完全相同的批評。它們都是一大堆亂七八糟的產物,起作用時你可以偷著樂,但不靈的時候也會帶來可怕的噩夢。
所有這些工具至少還需要幾十年才能徹底發展成熟。
是的,說得沒錯。

需要一套用於執行WordPress的recipe?Ansible能夠提供,Docker也可以。同樣的,Docker也能夠在執行Drupal、MySQL或者無數其它任務時提供這樣的幫助。至少在提供DevOps常規需求的預設設定方面,Docker的表現確實不錯。

如果Chef或者Ansible能夠發展得更成熟,那麼我們今天也就不需要圍繞Docker展開如此激烈的爭論了。據我所知,一家初創企業曾在2013年專注於為Chef構建框架(他們希望自己的框架能夠成為DevOps領域的Ruby on Rails)。他們遇到了一些問題,並在過程中發現其它更加有利可圖的發展方向。最終,他們分神了,也失敗了。儘管如此,他們未完成的工作可能終有一天會成功。這樣的框架將具有直接依賴作業系統功能的優勢,而無需像Docker那樣徹底掩蓋掉底層作業系統。

Chef與Ansible都曾經承諾為所有潛在的機器型別與一切常見的DevOps任務提供數千套指令碼。很明顯,二者一直都沒能完全實現承諾。2005年,每家企業都會有一名DevOps人員為公司內的所有DevOps任務編寫定製化指令碼——這似乎非常正常。但到2010年,明顯應該出現更為集中的常規任務指令碼庫,其具體程度應該高於Perl CPAN庫,且高度關注資源管理與編排層面的一致性問題(以實現可移植性)與安全性問題。也是從這時開始,Chef快速飛騰,Ansible隨後趕上,Docker也在幾年後奮起直追。很多開發者認為Docker最終帶來的正是Chef與Ansible長久以來承諾但卻未能實現的效果。但長久以來,Docker一直只適用於內部開發工作。直到2015年,在生產環境中使用Docker仍然無異於自殺。即使是在2016年,試圖利用Docker支援生產系統的企業仍然遭遇到痛苦的枷鎖。而這一切在過去一年中,仍然沒有出現顯著改觀。

在我看來,Docker有朝一日將被定性為一個巨大的錯誤。其中最強有力的論據在於,即使最終成為標準、始終最終發展成熟,Docker也只是為科技行業目前遭遇的種種難題貼上一張“創可貼”。由於缺少治本的能力,Docker的命運不可能迎來良好的結果。

我懷疑,從現在開始的五年之後,將會出現一種複雜度更低的方法實現雲端分散式計算的標準化——請大家與我一道見證這一猜想。當然,就目前來講,Docker仍然無處不在且人氣爆棚。

原文連結: Docker is the dangerous gamble which we will regret