Go 程序到底需不需要 Docker?

zy1993 7年前發布 | 31K 次閱讀 Docker 程序員 虛擬化

我是Go的粉絲,而且我也對容器感興趣。容器可以使得代碼更容易部署也更容易擴展。 但并不是所有Go程序員都使用容器。 在本文中,我將探討一些真正應該考慮使用Go和容器的原因 - 然后我們來看一些容器根本不會增加任何好處的情況。

首先,我們要確保我們都在相同的起點上。

什么是容器

對于使用這些容器的人來說,可能有許多不同的定義。對于許多人來說,盡管容器比Docker開源項目或Docker公司要久遠得多,“容器”一詞與Docker是同義詞。如果您是容器的新使用者,Docker可能是您的最佳起點,其提供對開發人員友好的命令行支持,但依然還有其他可用的實現:

  • Linux容器 - 容器實現,包括LXC和LXD

  • 來自CoreOS的rkt-pod-native容器引擎

  • runc - 按OCI規范運行容器

  • Windows容器 - Windows Server容器和Hyper-V容器

容器是一種虛擬化技術 - 它們允許您隔離應用程序,使其認為自己在單獨物理機器中運行。在這個意義上,容器類似于虛擬機,除了它使用主機操作系統而不是擁有自己的操作系統以外。

您可以從容器鏡像啟動容器,該容器會捆綁應用程序運行所需的所有內容,包括其所有運行時依賴關系。這些鏡像使分發程序更容易。

容器使你更容易分發代碼

由于依賴關系是容器鏡像的一部分,因此當您在開發機,測試或生產環境中運行它時,您將獲得完全相同的依賴關系。因為數據中心的機器和你的筆記本的環境差異導致的問題將不復存在。

但是Go的一個優勢就是將編譯成一個單獨的二進制可執行文件。您必須在構建時處理依賴關系,而沒有運行時依賴,也不需要管理庫。如果您曾經在Python,JavaScript,Ruby或Java中工作過,您會發現Go的這個特性是其優勢:您可以在Go編譯過程中得到單個可執行文件,它可以在你需要的機器上運行。您不需要確保目標機器具有正確的版本庫或執行環境。

呃,所以,如果你有一個二進制文件,那么在容器中打包二進制文件的要點是什么?

答案是可能還有其他的東西你想打包在你的二進制文件里。如果您正在構建一個網站,或者您的程序附帶配置文件,則可能會將靜態文件分開。您可以使用go-bindata或類似的方法將它們構建到可執行文件中。或者您可以使用包含一個包含二進制文件及其靜態資源的容器鏡像。無論您如何放置該容器鏡像,它都具有程序運行所需的一切。

容器幫助你部署代碼

讓我們假設你沒有任何靜態資源,只是一個二進制文件。您構建該可執行文件,然后將其移動到需要運行的計算機(您只需移動該文件)。 Go使得交叉編譯變得容易,所以即使要運行代碼的目標機器與您正在構建的代碼不同,也沒什么大不了的。您需要做的只是在運行go構建時指定目標機器的體系結構和操作系統。

在許多傳統部署中,您將確切知道哪個(虛擬)機器將運行哪個可執行文件。您可能擁有多個主機(例如為了高可用性),但是現在我們知道為目標機器構建容器是很容易的事情,而將Go二進制文件部署到機器上并非是高深莫測的事情。

但是現代部署方式是運行一組機器,并使用諸如Kubernetes,ECS或Docker Swarm之類的協調者將容器放置在集群中的某個位置。

容器對此非常有用,因為鏡像作為協調執行標準“部署單位”。管理員通過給它一個容器鏡像的標識符告訴機器運行什么代碼?如果機器還沒有該鏡像的副本,它可以從容器注冊表中獲取它。

當然也可以運行一個流程來部署沒有打包在容器鏡像中的代碼。但是通過使用容器,您正在利用廣泛使用并語言無關的部署方法,這種方法在行業中越來越多地被使用。即使你的公司今天是一個純粹的Go語言棧,通過使用容器,您將有一個通用的機制來部署不同的代碼組件。不管它們可能使用哪種語言,因此避免語言鎖定。

當我說“部署代碼的現代方法”時,您可能會非常正常地認為“無服務器”架構?無服務器架構就是在容器內運行某個可執行函數。今天部署到無服務器看起來有很大不同(跟其他方式比),但我不會驚訝地看待這些術語 - 在某些環境中,您可以用Docker容器鏡像的形式部署無服務函數(不僅僅是它具有全部依賴關系)。

容器限制代碼可以訪問的資源

當您在Linux機器上運行Go(或任何其他)可執行文件時,您將啟動一個進程。如果您在Linux容器中執行代碼,您也將以幾乎完全相同的方式啟動一個進程。該進程實際上認為它運行在單獨的機器上,并且具有所有的資源權限。

在容器內可以限制程序權限。虛擬機在同一硬件上運行多個不同應用程序具有許多相同的優點。例如,容器化進程無法訪問其容器外的文件或設備,除非您明確允許它可以訪問,因此它不能影響這些文件或設備(由于錯誤等)。它可能會認為可以使用所有CPU來進行CPU密集型的操作,但系統可能會限制其可以使用CPU的能力,以便其他應用程序和服務可以繼續運行。

資源限制是通過使用命名空間和cgroups創建的。這些術語意味著什么是另一個時代的話題,但是人們告訴我,他們發現我在英國做的這個演講是有幫助的。

如果要限制可執行文件并只訪問有限的資源集合,容器會為您提供一個整潔,友好和可重復的方式。

可以用其他方式為可執行文件創建相同的限制,但是使用容器會更容易。例如,傳統的系統管理員已經做了大量的工作,為文件,設備和網絡端口等設置權限。在容器的世界中,開發人員很容易表達他們的意圖,即代碼應該能夠使用某些端口或卷(而不是其他端口),并且默認情況下,容器內的所有內容都對于容器是私有的。您需要確保您的Dockerfiles遵循最佳安全做法,而每次開發團隊部署新的應用程序或服務時,都不需要定制操作來獲取權限設置。

容器幫助你在本地測試其他組件

許多應用程序需要訪問其他組件,如數據庫或排隊服務(或其他無限的)。 當您想在本地運行程序進行測試時,您還需要安裝這些組件。

但是如果不同應用程序需要不同版本的組件怎么辦? 或者如果不同項目的配置有所不同? 例如,如果您是開發人員,您可以輕松地使用不同版本(例如Postgres)運行兩個客戶端。 可以在筆記本電腦上運行多個副本,但可能會很痛苦(您必須確保使用正確的版本)。

如果您使用所需服務的docker版本,那么生活可以簡單得多。 您可以為每個項目設置一個docker-compose文件,以使用正確配置啟動正確的組件集。

容器能為你做什么

總之,docker容易:

  • 將代碼分發到可以在任何地方運行的程序包中

  • 通過一個協調者部署您的軟件

  • 限制您(或其他人的)代碼可以在主機上使用的資源

  • 在本地運行和測試您的軟件(包括所需的所有服務)

如果您是Go開發人員從事“后端”開發或將代碼部署在云端的系統軟件,這些都是可能使用容器的原因。 但是如果那些不適用于你,你是否應該使docker部署Go代碼?

什么時候不該使用容器

Docker有一個口號:“Build, Ship and Run Any App, Anywhere”。Go已經有一些內置的屬性支持這一點。正如我前面提到的,比如交叉編譯和生成單個沒有依賴的可執行文件。除非您使用可執行文件打包其他文件(或新插件),否則除非“運行”是指“通過編排器進行部署”,容器不能提供便捷。

也許你是一個Go開發者,并不必擔心將代碼部署到一組機器上。如果你建立一個獨立的桌面或移動應用程序作為下載分發奇,那么使用容器不會增加任何好處,反而會增加你的工作流和構建過程的不必要的復雜性。

同樣,如果我正在編寫一個獨立的程序(我只打算在本地運行,也許是一個實驗或演示,或者一個不需要與其他組件交互的小型實用程序),我就不會使用容器。和往常一樣,使用正確的工具作業,如果不會增加價值,就不要使用容器。

有沒有使用容器的其他原因?我很想聽聽你的經歷。

 

來自:https://mp.weixin.qq.com/s/9q5pt-aEQnt28S1zmL6eGw

 

 本文由用戶 zy1993 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!