如何在容器内高效编程?
作者 |?Daniel Lemire
譯者 |?蘇本如,責編 | 郭芮
頭圖 | CSDN 下載自東方IC
出品 | CSDN(ID:CSDNnews)
以下為譯文:
我個人的編程環境中包括了一些服務器、筆記本電腦和臺式電腦。我的服務器是在不同的時間購買和配置的,根據需求不同,它們有不同的硬件和軟件配置。這些硬件的處理器不同,AMD、英特爾、Ampere和Rockchip的處理器都有。同時這些機器上安裝有各種各樣的Linux發行版,包括各種舊版本和新版本。在實驗室技術人員幫助我做好初始設置后,基本上這些電腦所有的管理工作都是由我一人負責。
所以,最終我時常面對這樣的情形:有時候我會遇到一些非常有趣的系統,這些系統都帶有舊的Linux發行版,而重新安裝新Linux發行版并保證它的安全并非易事。而且,即使我費盡心力地更新了我的Linux發行版,我最終也可能會得到一個與我的合作者不同的Linux發行版,使用不同的編譯器等等。更不用說在同一個Linux發行版上安裝多個不同的編譯器是一件非常耗費時間的事。
那么,應對這種問題,你能做些什么呢?
你可以運行虛擬機。使用VirtualBox之類的工具,你可以在Windows和 macOS中運行Linux。這種方式很簡單。然而,它速度很慢,而且計算的代價高昂。
你可以切換到容器,特別是Docker容器,它們的開銷要少得多。Docker現在已經是云計算中無處不在的工具。作為一個簡單的描述,你可以把Docker看作一個允許你在Linux中運行Linux的容器。Docker實際上是一個沙箱,但它是一個幾乎可以直接在主機上運行的沙箱。與虛擬機不同,我的測試顯示,在計算密集型任務中,Docker容器可以以“原生速度”(裸機速度)運行。有報道稱Docker的交互速度較慢,網絡連接和磁盤訪問速度也較慢。但就我的用途而言,Decker能很好地滿足我的要求。
當然,如果必須的話,你也可以在macOS和Windows下運行Docker容器,不過我想這樣做會需要更多的開銷。
容器方法的思想始終是基于系統的起始狀態。比如說,你定義了你的數據庫服務器需要的配置,并且每次都以這種精確的狀態(配置)來啟動它。這樣就使得你的基礎架構具有可預測性。
這聽起來不是那么完美。你仍然必須依賴于你的容器的起始配置。如果兩個具有不同要求的應用程序需要在同一個映像中一起運行,那么你可能需要進行各種配置操作。
話雖如此,容器仍然工作得很好,它們基本上成了維系我們當令技術文明的基礎:許多基于云的應用程序都是以某種方式基于容器的。
容器的目是將軟件部署到生產環境中去。在容器內編程是不被直接支持的:你將找不到關于容器編程的很多文檔,而且圍繞著容器編程也根本沒有什么業務模型。那么這里我提到的“在容器內編程”是什么意思呢?我的意思是:我要啟動一個C編程項目,決定使用Linux Ubuntu16.10發行版,并在Linux Ubuntu16.10下編譯和運行我的代碼,即使我的服務器可能運行完全不同的Linux發行版(或者可能在macOS下)。
第一個問題是,你的磁盤和從容器構建來的映像的磁盤是不同的。正在運行的映像無法自由訪問底層服務器(主機)。記住容器本質上是一個沙箱。
因此,你只可以在映像里面做所有的工作。但是,請記住,容器技術的重點是始終從原始狀態開始。如果你加載了一個圖像,做了一些工作,然后離開……你的工作就不見了。映像被設計成是不可變的。這是一件很好的事情,因為這保證了你不會因為一不小心就把映像弄亂。
在映像中完成一些工作后,可以為新狀態拍攝快照,提交它并創建一個新映像,再從中重新開始。這個過程既復雜又不實用。
那么你能做什么呢?你可以做的是保持映像的無狀態,就像一個映像本來就應該是無狀態的那樣。這樣的話,映像中將只能包含編譯器和構建工具。因為沒有理由頻繁地更換這些工具。同時你將所有的代碼都放在一個目錄中,就像你通常所做的那樣。要運行和編譯代碼,你可以進入映像中并運行命令。你可以在進入代碼存儲庫時將其從主機磁盤綁定到映像。
這種方式效果更好。但是如果直接執行Docker命令行,則會出現以下問題:
1)根據你機器上的Docker配置,你可能會發現無法從映像讀取或寫入綁定到該映像的磁盤。對這個問題的一個快速修復方法是以特權訪問方式來運行映像,但這種方法通常不受歡迎(而且不必要)。
2)從Docker映像中創建或修改的文件顯示在主機磁盤上時,通常帶有奇怪的文件權限。比如說,可能所有文件都屬于根用戶。我的一個研究助理有一個很好的變通解決辦法:他一直以根用戶的身份運行Linux。但是,我不推薦這樣的方法。
這些小問題根源在于Docker以一種奇怪的方式來處理權限和安全性。可能與你了解的相反,設置用戶和組標識符并不是一件簡單的事情:在某些系統上可能足夠簡單,但在一些需要額外注意的支持增強的安全性的Linux系統上就不那么簡單了。
最后,你需要記住很多復雜的命令。如果你和我一樣,想把所有的注意力都集中在代碼上,而不愿意在Docker上面浪費太多的時間。怎么辦?
解決方法是使用一個小小的腳本。以我為例,我使用一個bash腳本。你可以在GitHub上找到它。它可以幫助你理清零亂的命令和文件權限。
盡管多年來,我一直試圖避免依賴腳本,但是為了高效的工作,這是無可避免的。
基本上,我的做法是向我工作的目錄的根目錄中復制兩個文件(Dockerfile和run文件),然后鍵入命令:
./run bash就是這么簡單!現在我進入了主機目錄的一個子shell中。我可以在這里運行我的程序,編譯我的代碼,我對最近的Ubuntu發行版有完全的訪問權限,這種方式甚至在我的基于ARM的服務器環境中也能很好地工作。
這個run腳本也可以接受其他命令,因此我可以將它作為其他腳本的一部分。
原文:https://lemire.me/blog/2020/05/22/programming-inside-a-container/
本文為 CSDN 翻譯,轉載請注明來源出處。
6月3日20:00,CSDN 創始人&董事長、極客幫創投創始合伙人蔣濤攜手全球頂級開源基金會主席、董事,聚焦中國開源現狀,直面開發者在開源技術、商業上的難題,你絕不可錯過的開源巔峰對談!立即免費圍觀:
推薦閱讀
因為一個跨域請求,我差點丟了飯碗
沒錯,你離分布式搜索只差一個Elasticsearch入門!
Python開發之:Django基于Docker實現Mysql數據庫讀寫分離、集群、主從同步詳解 | 原力計劃
全球Python調查報告:Python 2正在消亡,PyCharm比VS Code更受歡迎
無代碼來了,還要程序員嗎?
再見,Eclipse | 原力計劃
區塊鏈共識算法總結 | 原力計劃
真香,朕在看了!
總結
以上是生活随笔為你收集整理的如何在容器内高效编程?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你抢的不是春节红包而是云
- 下一篇: 2020 年,为什么非要采用 DevOp