容器和虛拟機比較
- 虛拟機在基礎架構之上有一個虛拟機監控的程式,在它上面會有不同的作業系統,在不同的作業系統之上再運作獨立的應用程式;
- 采用容器技術的好處是運作相同的應用程式,使用容器額外開銷比較少,這也是它比較受歡迎的原因;
docker有個背景程序使用containerd,它是專門用來管理容器以及容器鏡像的一個應用,當然這個容器鏡像要符合OCI(開放容器标準),它會通過runc進行一個解包的處理,runc是專門用來運作容器中應用的。
容器技術的核心功能
命名空間(Namespace)
Linux命名空間提供了一種核心級别隔離系統資源的方法,通過将系統的全局資源放在不同的Namespace中來實作資源隔離的目的。
- 檔案系統隔離
- 程序隔離
- 網絡資源隔離
- 使用者和使用者組隔離
- 主機名和域名隔離
- 程序間通信隔離
控制組(CGroup)
Linux控制組是一個核心功能,用于限制,記錄和隔離一個或多個程序,對CPU、記憶體、磁盤I/O、以及網絡的使用量及通路。
- 限制程序組可以使用的資源數量
- 程序組的優先級控制,比如給特定程序組配置設定特定的CPU使用率
- 記錄程序組使用的資源數量
- 程序組控制,比如将程序組挂起和恢複
其實程序和程序之間是運作在同一個作業系統之上的,所謂的隔離是邏輯上的隔離,通過這兩種技術可以起到限制程序使用資源的目的。
啟動了一個apache pod。
這是目前k8s叢集裡使用到的容器,其中很多是系統容器不需要管。
容器清單裡面有很多pause這樣的容器鏡像所啟動的容器,所啟動的apache容器和某一個pause容器共享一個網絡命名空間。
檢視某個容器的描述,
這是程序的相關配置,其中entrypoint.sh是apache的啟動腳本,
這個是命名空間配置,隔離apchae所使用的命名空間,pid是apache程序本身在整個程序樹上是根程序,network是apache程序通信的網絡隔離。
網絡命名空間依賴446476這個程序,
可以看到apache本身的程序是446531,很明顯apache的網絡是由446476這個程序所影響的,那這個程序是什麼?
看下這個程序的狀态,
發現這個程序目前處理sleeping狀态,本身不幹活,那麼它存在的意義是什麼?
叢集節點上運作着linux作業系統,在上面運作所有的容器在邏輯上是隔離的,是因使用了命名空間和控制組這樣的技術。
目前機器本身就是k8s叢集的一個node節點,
直接通過ps指令可以看到apache和pause這樣的程序,因為它是運作在本機作業系統上的程序,但是pause程序在啟動的時候,會建立各種各樣的命名空間,進而把pause這個程序隔離起來,進而把它視為運作在一個獨立的作業系統上的一個程序,然後它進入了一個休眠的狀态,它的任務已經完成了。
後面啟動的apache程序在某些命名空間上會attach到這個pause命名空間,2個命名空間關聯起來,apache也可以把自己看作一個獨立在作業系統中的一個程序。
pause建立了命名空間,apache的程序關聯到這個命名空間中。
k8s的pause首先會啟動pause這個程序去建立一個命名空間,然後在k8s的pause裡面,無論有多少個container,都會共享同一個命名空間,比如共享一個網絡命名空間,它有獨立的端口範圍、主機名,路由。
從pod的角度來看它就是一個pod在運作,其實這個pod裡面的所有的容器通過共享命名空間來實作一個獨立的封裝,也就是說封裝在pod裡面的這些程序它們彼此之間都是可以共享同一個命名空間。
首先模拟一下啟動pause這樣一個程序進而建立各種各樣的命名空間,
做了一個docker鏡像用來模拟pause容器,
把容器裡面的8080端口暴露在主機的80端口上,運作容器了之後,直接删除鏡像,
這個容器本身有它獨立的命名空間,後面就需要一個應用的容器關聯到這個pod上,這裡用了一個python的容器 ,python比較容易啟動web服務,
新啟動的python的容器,本身會attach到pause容器上,本身和pause容器共享同一個網絡命名空間,
python容器把80應用跑起來了,進入python裡面,發現機器名和pause共享同一個機器名,因為在run python的時候并沒有指定host name,而是運作pause的時候指定的,
在python容器中啟動一個web服務,
當把web server跑在apache容器上,它實際上和pause容器共享了同一個網絡命名空間,
再啟動一個python容器,
依然使用8080端口,會有端口沖突。
在一個容器裡面生成新檔案,在另外一個容器裡面是沒有這個檔案的,說明檔案系統是獨立的,但是網絡空間卻是共享的。
總結
- 容器是通過命名空間互相隔離的系統程序
- K8s pod是一個抽象的概念,使用Pause容器建立命名空間并與使用者程序容器共享
- 在一個K8s pod中使用者程序容器之間通過網絡命名空間交換網絡資料
- 在一個K8s Pod中使用者程序容器共享同一主機名、端口範圍、網絡路由
- 一個node上啟了10個pause,并且每個pause裡面有10個容器,其實本質上來講在作業系統上啟動了100個程序,隻不過通過命名空間的方式把它們進行分組進行隔離。