Docker 開發環境的滑坡

Docker 開發環境的滑坡

作者 | Micah Adams

封圖| CSDN 下載於視覺中國

最近,我構建了一個本地開發環境,該環境使用 Docker 進行一些關鍵的集成測試。 在我要完成這項工作時,我意識到在開始這項工作之前,我沒有考慮到這麼做的一些意義深遠影響,如:

  • 它要求開發人員在其本地計算機上安裝 docker 和 docker-compose (命令行工具)。
  • 為了讓環境可以正常使用,需要大量的配置。
  • 我需要編寫 shell 腳本來“緩解”某些配置問題。
  • 我編寫的 shell 腳本最終也有些侷限ーー它在某些環境中工作得很好,但是如果你在 Windows 系統上工作,你就得靠自己了。
  • 我一天中的大部分時間都要用來排查一些數據庫連接問題,結果發現我容器的數據庫沒有配置正確。

在這方面投入了大量的時間,最終使我的團隊受益,並最終幫助我們解決了集成測試中遇到的一些難題。但是更讓我感興趣的是它所帶來的麻煩,

更不用說在最終合併之前我提交的 pull 請求時引發的熱烈討論了。

此外,這種環境最終只有一個目的——提供集成測試環境,而不是像我最初希望的那樣,提供一套完整的開發環境。最終的結果是,我們將這個環境從開發人員的機器上移開,並最終將其部署到雲提供商的一個容器化列表中,以創建一個集成測試資源。

我的努力基本上是失敗的,尤其是考慮到我最初的動機。

難道我誤入歧途了?我所有的努力工作只換來一個花哨的測試環境?

我決定更深入地研究基於容器的開發環境的問題,從那以後我所學到的東西極大地改變了我將來處理這個問題的方式。

Docker 開發環境的滑坡


Docker 開發環境的滑坡

容器的當前狀態

大量的調查向我們證明,使用 Docker 的人數在持續增加,特別是隨著基礎設施的增長和變得更加複雜之後。2018 年 6 月 來自 DataDog的一項調查顯示,大約25% 的公司使用 Docker 部署了某種形式的基礎設施。從 2017 年到 2018 年,部署的規模增加了75% 。根據這些消息來源, Docker “革命”正在全面展開,沒有減緩或停止的跡象。(我仍然很好奇 這75% 中的大多數公司在他們的部署中使用了什麼?抱歉,我跑題了。)

調查內容:https://portworx.com/wp-content/uploads/2019/05/2019-container-adoption-survey.pdf

來自 DataDog 的調查:https://www.datadoghq.com/docker-adoption/

2018 年的 DataDog 調查也提到了使用最廣泛的 Docker 鏡像是“ Nginx,Redis 和 Postgres”。這對我來說很有意義,因為運行應用程序依賴項的容器似乎是容器的第一步。Docker Compose 為多容器應用程序提供了一個相對簡單的工具; 它似乎也是一個很好的工具,允許開發人員為自己的環境運行特定的、底層的基礎設施。也就是說,你要為你的項目設置了一個 `docker-compose.yml` 文件即可。

這 25% 的公司在生產環境中運行 Docker,究竟有多少公司使用 Docker 作為開發工具呢?2019 年 Stack Overflow 調查報告顯示,38.4% 的受訪者使用容器進行開發工作,但目前約有一半的受訪者沒有使用任何容器技術。我想知道是否有一種方法可以進一步理解為什麼開發人員不像我最初想象的那樣經常使用 Docker。我決定再深入挖掘一下,粗略地研究一下開發人員對 Docker 的看法。

許多開發人員討厭自己的 Docker 環境,這是有充分理由的——引入容器似乎會減慢開發人員與他們所構建的環境之間的反饋週期。容器化開發環境似乎也為操作員創建了一個不必要的抽象,這個操作員需要能夠直接深入到代碼、執行期函式庫、甚至較低級別的操作系統

ーー所有這些都是在構建一個特性的過程中。

支持將 Docker 作為開發工具的人聲稱,這樣做有明顯的的好處。使用容器的開發環境也會導致整個開發團隊實現對等。

如果每個人都使用容器作為他們的數據庫、緩存或其他雜項基礎設施,那麼設置編寫代碼應該和運行 `docker-compose up` 一樣簡單,你就可以擁有一個完整的開發環境。假設你的團隊願意在本地運行容器,那麼你將永遠不會在開發環境和生產環境之間造成差異。

當運行 `brew upgrade`對其進行升級時,不會有啥意外——容器將始終與你的需求保持同步。

坦白地說,我同情這兩個群體。作為一個開發者,一隻腳堅定地站在房子的運營方面,我認為運行容器的好處是巨大的。然而,我並不認為這些好處完全適用於開發人員工作流。我相信在開發環境中使用 Docker 的經驗之間存在差異,因為 Docker 不是開發人員的工具。

然而,我不認為這意味著開發團隊不應該考慮利用一些 Docker 來滿足他們自己的需求。

但是我覺得將 Docker 作為另一個操作工具來處理可以幫助減輕在本地開發環境中運行 Docker 的痛苦。

Docker 開發環境的滑坡

Docker 開發環境的滑坡

容器是開發人員友好的抽象嗎?

一個容器,就 Docker 而言:

是一種標準的軟件單元,可以將代碼及其所有依賴關係打包,使應用程序能夠快速可靠地從一個計算環境運行到另一個計算環境上。

下面是一個稍微明晰一些的定義:

容器是應用層的一個抽象,它將代碼和依賴關係打包在一起。

聽起來不錯,對吧?

是的,特別是當你試圖部署代碼的時候,你會發現的確如此。換句話說,如果我主要關心的是讓我們的代碼在任何地方都能毫無意外地運行,那麼容器似乎是目前最好的抽象——我並不真的需要了解我們正在運行的代碼,相反,我需要對我們將如何運行它有一個可預測性。作為一個操作人員,這點非常棒。

但是,作為一個開發人員,這種抽象可能會帶來一些麻煩。容器並不真正關心自己在運行什麼。操作系統是有目的地抽象出來的,

運行容器所必需的任何依賴項也是如此。應用程序層本身和底層操作系統一樣短暫,訪問這些抽象層需要了解 Docker 希望以何種方式運行代碼。

儘管我已經談到了容器的預期用途,但我認為說容器只是團隊運營的東西的說法是錯誤的。我認為開發人員可以從容器化開發環境中受益。問題在於構建一個真正的開發人員友好的、基於容器的工作流並不容易。

Docker 開發環境的滑坡

基於 docker 的開發環境的常見缺陷


最後,我選擇在自己的開發工作中多次使用 Docker。這對我來說很有效,尤其是對於我每天所做的工作來說。在 Test Double,更重視 Dev Ops 和 SRE,我在這裡每天都和容器打交道。

當然,這可能不適合你的團隊。但是,如果你確實希望在開發環境中使用 Docker 進行,我會提醒你注意一些我親身經歷過的常見陷阱。

  • 假設容器化只有優點

在容器化的開發環境中,最大的陷阱可能是假設你在部署中獲得的好處與開發人員在本地體驗到的好處是一樣的。

類似地,假設一個團隊希望與 Docker 密切合作,這種假設可能不適用於你的團隊。如果你的開發人員與操作工作相對孤立,那麼他們可能不希望每天都在本地使用容器,這可能不是一個嚴謹的假設。但是,如果你處在一個開發人員正在進行一些操作工作的團隊中工作,那麼假設你提供了僅僅是容器化開發環境的其他替代方案,那麼這對你的團隊有好處。

Docker 開發環境的滑坡

在本地運行容器會消耗大量資源。僅在我的機器上,在一個典型的工作日,Docker 就要消耗大約 36GB 的存儲空間。我不會說對於我的特定品牌和型號的工作站來說系統使用量是非常大的,但是我可以很容易地看出,當我在工作流中包含更多的容器時,系統使用量會大大增加。在我的活動監視器中,Docker 也是佔用 CPU、內存和磁盤資源最多的。


更重要的是,儘管這可能不會給我的機器帶來沉重的負擔,但這並不意味著它與其他機器很好地匹配,而且最終決定將如此多的資源分配給 Docker 應該取決於開發人員自己的個人偏好。也就是說,你的筆記本電腦不是服務器,它可能不需要根據服務器標準構建的容器資源。

但是,即使超出了系統資源,開發人員環境也不能很好地與運行你的代碼的系統保持一致。在過去,這種差異是如此之大,以至於我們經常不得不進入一個與我們的生產服務器完全一樣的環境,而且我們中的一些人(不幸的是,包括我自己在內)如果出現嚴重錯誤的話,甚至不得不在這些系統上進行實時代碼更改!

開發人員需要專注於編寫可維護、可靠和經過良好測試的代碼。我認為,在有限的環境中工作可以有更好的代碼實踐和決策ーー你不得不依賴於編寫整潔的、可維護和可操作的代碼,而不是希望服務器以這種方式配置來處理性能瓶頸和低效的實現。

開發人員在工作時已經有很多需要構建和維護的上下文。如果你的本地 Docker 環境將這種上下文作為為判斷容器是否正在運行,那麼從長遠來看,只會讓你失望了。

類似地,要求開發人員使用 `docker run` 命令啟動容器會增加上下文切換的開銷。在本地環境中開發時,開發人員已經建立了某種模式,而使用容器不僅與這些模式背道而馳,還需要對 `docker` CLI 本身有更多的掌握,這就給開發人員實現目標製造了阻力。當我不得不使用 Docker 容器來調試某些東西時,我也不禁感到有點奇怪。它有點像我之前提到過的一個錯誤: 進入生產服務器。

這種啟發式方法與其他服務緊隨其後。如果你所在的團隊都在使用微服務,而其他團隊需要各種各樣的服務來構建自己的特性,那麼你應該謹慎地將這些鏡像作為容器提供。在這些情況下,團隊在自己的環境中支持服務本身實際上可能比用容器模糊服務更有益。

對於這些特定的內部服務,可能值得對為此服務提供的文檔進行審計,而不是對其進行容器化。維護不良的文檔與容器結合在一起會產生諸多認知失調,從而導致放棄 Docker 環境的挫敗感。我們所有人都應該更仔細地查看我們的文檔,並經常對其進行審計,而不是構建新的東西。

我上面提到的調查結果顯示,Nginx、 Redis 和 Postgres 在擁抱的團隊中非常受歡迎。很明顯,為什麼這些東西如此受歡迎。除非你的團隊從事編寫自己的 RDBMS 或 web 服務器 / 負載平衡器的業務,否則你將通過在堆棧中利用類似這樣的開放源碼應用程序而獲益匪淺。

直到徹底的容器化,你的運營團隊可能無法獲得與開發團隊在決定將其包含在技術棧中獲得的相同收益。通過容器化這些依賴關係,運營團隊可以從一種類似的加速器中受益,這種加速器無需編寫自己的 RDBMS 即可為開發人員提供幫助。

容器化 Postgres 提供了大量用於部署,監視和擴展此關鍵依賴性的選項。它還減少了一些更新,升級和管理該系統的開銷。這對運營團隊來說非常有用,但這是否符合開發人員的需求?

總而言之,即使簡單地運行 `docker-compose up -d` 後臺啟動並運行容器,它也不能很好地與絕大多數開發人員用於本地運行環境的心智模型協同工作。這兩種工作流程之間有著本質的差異。

Docker 開發環境的滑坡

開發人員希望能夠深入挖掘他們需要的抽象概念,而要求團隊使用一個全新的工具,用一種完全不同的方法來運行他們的本地環境,是一個很高的要求。具體來說,開發人員需要能夠運行數據庫遷移、跳轉到數據庫 CLI 並跟蹤數據庫日誌。對於堆棧中的任何關鍵組件也是如此。

這並不是說沒有開發人員樂意在本地使用 Docker 。但是我敢打賭,使用 Docker 的開發人員已經知道如何讓它在他們的工作流中無縫地工作,不管他們是剛剛做了一個習慣性的改變,還是他們已經編寫了腳本,以便更好地與他們自己的環境一起工作。

Docker 開發環境的滑坡

圍繞容器命令編寫新穎的腳本

說到腳本,如果你正在構建一個這樣的本地環境,並且你正在試圖減少必須由 `docker run 處各種事情的開銷,那麼你最初的衝動 (像我一樣) 可能是編寫許多與基於容器的工作相關的死記硬背的任務。

這種偏好並不一定是被誤導的。畢竟,我們被教導用腳本去掉冗餘的任務,這樣我們就可以減少重複工作。但是要注意尤其在你的團隊對容器瞭解不深的情況下,不要過多地使用腳本。

我提到過使用 `Docker` CLI 會產生開銷,但是如果有一個開發團隊積極地使用容器,那麼為他們提供使用 Docker 自己的工具的時間和培訓可能會更有意義,而不是潛在地模糊 Docker 本身的內部工作。這確實是一個必須掌握的工具,但是通過避免圍繞這些命令編寫新穎的腳本,你可以減少在故障排除和對工具本身的更廣泛理解上的認知壓力。

為了強調我對定製容器包裝程序的最高的關注,圍繞容器的新穎腳本產生了更多的代碼,從而需要維護更多東西。我要說的是,如果小組確定這對其工作流程是有利的,你可以繼續這麼做。尤其是在新人入職過程中,希望大家可以避免編寫那些註定被遺棄或某種場景定製的特定腳本,從而耗費大把的時間。

Docker 開發環境的滑坡


Docker 開發環境的滑坡

除了 Docker 化,別無選擇


如果你對容器化的開發環境感興趣,我認為你應該花很多的時間為本地運行系統構建簡單的替代方案。換句話說,不要認為在本地環境中使用 Docker 是一個非此即彼的決定。記錄在標準本地部署中設置應用程序的步驟,以及為那些對運行容器感興趣的人提供替代方案。讓你的團隊判斷這個工作流程是否適合。

總而言之,在不進行開發環境的權衡的情況下全部使用容器將給你的開發團隊帶來負擔。

Docker 開發環境的滑坡

結束

沒有正確搭建開發環境的統一的模式。雖然鼓勵你的團隊擁抱容器化可能會帶來一些好處,但最終的目標還是應該放在改善開發人員的工作流程。如果我們為了技術抽象而犧牲了編寫優秀代碼的能力,那麼我們就是在降低效率。

不管是選擇傳統的還是容器化的開發環境,都不應該讓個人的喜好所左右,最終應該讓整個團隊一起做決定。如果你能和團隊一起找出本地開發存在的痛點,就能夠幫助你準確評估是採用本地開發還是容器化。

原文:https://blog.testdouble.com/posts/2020-02-11-the-slippery-slope-of-docker-dev-environments/

本文為 CSDN 翻譯,轉載請聯繫我們。


分享到:


相關文章: