從開始接觸并學習容器,至今已經數年。在離開技術運維團隊支援的情況下,叔獨自摸索,偶然拾起了容器技術,一頭紮進裡面,慢慢學習,逐漸部署應用。在這個過程中發現問題,解決問題,精進學習,管中窺豹。回顧這個學習過程中犯過的概念性錯誤、走過的彎路、掉過的坑,有趣且轉折。且抽空記錄在此,供初學者們借鑒。
如果在學習容器技術之前,未接觸過虛拟化技術,那麼恭喜你,你不太容易産生概念混淆,會比較容易地融入容器世界。當然,這不符合我的狀況。事實是,在接觸容器之前,基于XEN、KVM,我們深入研發了一套彈性計算平台,并基于這個平台釋出了我們自己的虛拟桌面和虛拟伺服器系統多年,虛拟化的概念已經深入骨髓。
容器技術跟虛拟化技術有共同點也有差異。最容易看到也讓人産生興趣的,是它們的共同點:計算單元隔離。基于對這個需求的了解,也很容易讓初學者覺得使用容器很容易上手。
是以,容器技術“速成”後,叔并沒有花時間深入去了解這種差異。叔最喜歡做的一件事,就是啟動一個目标作業系統的容器,比如CentOS7.9的容器,然後在這個容器裡面裝上SSHD,使用Yum在這個容器裡面安裝各種服務比如nginx、mysql、redis、mqtt等等。這簡直是對虛拟化的應用模式的完整複制。
docker run -d --name="server1" --entrypoint="/sbin/init" centos:centos7.9.2009
docker exec -it -uroot server1 /bin/bash
yum install -y net-tools mysql openssh openssh-server
這個階段并未真正去了解上面指令行中的entrypoint的意義,知道通過這個方式可以得到一個完全隔離的操作環境,然後在上面安裝和部署需要的服務和應用,這就夠了。但是看到運作中日益龐大的容器檔案系統,以及容器内數量漸增的系統程序數量後,隐隐覺得這樣不對。
于是産生了一個靈魂拷問:如果這樣使用,為什麼需要容器技術?它跟虛拟化技術到底有何差異?
先回顧一下虛拟化技術。
虛拟化技術(不管是半虛拟化還是全虛拟化)是從硬體層開始建構,從使用者視角建構了一台虛拟存在的PC:它具備BIOS,具備獨立的CPU、記憶體、硬碟、網卡、聲霸卡、USB外設等等你在普通PC上可以看到的一切。使用者通過虛拟化軟體操作這台PC,控制它的啟動和停止,将安裝媒體挂載到它裡面進行作業系統安裝;在裝好的作業系統裡面安裝和操控各種應用;管理這台機器的網絡模式,可以讓它在主控端所在的網絡裡看起來就是一台真實存在的PC裝置。
為了達成這些目的,虛拟化技術需要硬體的支援,主機闆和CPU必須支援虛拟化。Intel CPU 的虛拟化技術叫做 Intel Virtualization Technology (VT-x),AMD CPU 的虛拟化技術叫做 AMD Virtualization (AMD-V)。使用時,需要進入主機闆的BIOS設定内,确認上述選項的支援和開啟。
虛拟化技術讓使用者将一台實體上的主控端,靈活地分割成多台虛拟但又真實存在的”虛拟機“,這些虛拟機之間互相之間從作業系統層就完全隔離。是以,每個虛拟機内可以安裝互不相同的作業系統,比如Windows、Android、MacOS、FreeBSD、各種Linux等等,而這些作業系統并不需要與主控端作業系統相同或者類似。虛拟機的作業系統擁有自己獨立的完整的檔案系統,它的檔案系統可以是主控端上的一個獨立存在的檔案,也可以是主控端上的一個獨立分區,當然,它也可以共用主控端的分區和檔案系統——這種模式下需要非常小心,這個不是虛拟機技術的典型應用模式。
虛拟機的這種隔離帶來的好處是,使用者可以将需要分隔的服務分别部署到不同的虛拟機裡面,而不需要考慮互相之間的程序級别的安全問題和幹擾因素。虛拟機内的應用和服務的影響,被限制在虛拟機的架構之内。
從上面可以看到,由于每台虛拟機都擁有自己獨立的”硬體“和”作業系統“,那麼,”硬體層“和”作業系統層“就成了同一台主控端上多台虛拟機額外消耗的資源。有沒有一種技術,既能實作程序之間的隔離,又不需要獨自虛拟化出一套單獨的”硬體“和”作業系統“,隻需要共用主控端的硬體和作業系統呢?
容器技術生來就是解決上述問題的。
容器技術在容器内共用了主控端的硬體和作業系統核心,僅僅在作業系統之上、應用及服務之下,建構了簡單的一層操作環境(比如檔案系統、環境變量、作業系統差異),僅僅用于滿足容器本身運作的應用或者服務所需。通過容器技術,将宿主作業系統的公用作業系統程序、檔案系統、作業系統API接口等等,映射到容器内,實作了節約資源的同時又隔離程序運作空間的目的。
看到這裡,玩過FreeBSD的同學可能很自然就會想起一個技術:jail。Jail内完整模拟了一個主控端的作業系統操作環境,從操作體驗上看,Jail更接近虛拟機,它有完整的宿主作業系統操作體驗。使用Jail時,一般會登入到Jail内,通過shell操作Jail内資源和應用。但是容器技術比Jail節約的更純粹。
容器技術可以僅僅隻保留應用和服務必須的那部分宿主作業系統資源依賴,從宿主檔案系統中繼承來的檔案系統中裁剪掉其他不需要的庫和資源。如果需要,使用者甚至可以把容器當成主控端内的一個獨立程序來對待——這就是容器的entrypoint的意義——它并不需要自己獨自的shell,使用者可以在主控端上通過容器指令直接操作容器内的檔案、日志、程序。隻有體會了這一層,才能完整了解容器技術跟虛拟化技術的差異和應用精髓,才不會再在CentOS或者Ubuntu或者Debian的容器裡面部署多個應用。
當然,在單獨的CentOS等作業系統容器内部署關聯應用和服務,也可以是容器的一種應用模式,結合容器的嵌套技術,完全可以通過在容器内嵌套運作容器的方法來達成:https://blog.csdn.net/mycosmos/article/details/126247521 。