docker容器虛擬化

2022-06-09 18:21:06 字數 2458 閱讀 3461

network namespace 是 linux 核心提供的功能,是實現網路虛擬化的重要功能,它能建立多個隔離的網路空間,它們有獨自網路棧資訊。不管是虛擬機器還是容器,執行的時候彷彿自己都在獨立的網路中。而且不同network namespace的資源相互不可見,彼此之間無法通訊。

假如我們的物理機有4塊物理網絡卡,我們要建立4個命名空間,而這些裝置是可以單獨關聯至某個單獨的命名空間使用的

如上圖所示,把第一塊網絡卡分配給第乙個命名空間,第二塊分給第二個命名空間,第三塊分給第三個命名空間,第四塊分給第四個命名空間。此時其它命名空間都是看不見當前所在命名空間的,因為乙個裝置只能屬於乙個命名空間。

這種方式使得每乙個命名空間都能配置ip位址,並且與外部網路直接通訊,因為它們使用的是物理網絡卡。

但如果我們所擁有的命名空間數量超過物理網絡卡數量呢?此時我們可以使用虛擬網絡卡裝置,用純軟體的方式來模擬一組裝置來使用。linux核心級支援2種級別裝置的模擬,一種是二層裝置,一種是三層裝置。

linux核心模擬的二層裝置,每個網路介面裝置是成對出現的,可以模擬為一根網線的兩端,其中一端模擬主機的虛擬網絡卡,另一端模擬虛擬交換機,就相當於讓乙個主機連到乙個交換機上去。linux核心原生支援二層虛擬網橋裝置,即用軟體虛擬交換機的功能。如下圖所示:

那麼此時如果再有乙個命名空間,它有建立了一對虛擬網絡卡,一端連線命名空間,一端連線虛擬交換機,此時就相當於兩個命名空間連線到了同乙個交換機網路中,此時如果兩個命名空間的網絡卡位址配置在同一網段,那麼很顯然他們之間是可以互相通訊的。如下圖所示:

從網路通訊的物理裝置到網絡卡都是用純軟體的方式來實現,這種實現方式就叫做虛擬化網路。

如果在同乙個物理機上的兩個容器想通訊,我們的辦法就是在這台主機上建立乙個虛擬交換機,而後讓兩個容器各自用純軟體的方式建立一對虛擬網絡卡,一半在容器上,一半在虛擬交換機上,從而實現通訊。如下圖所示:

這就是單節點上兩個容器間的通訊方式。單節點上兩個容器之間的通訊也有一些複雜情況,比如我們期望構建的容器要跨交換機通訊呢?

我們做兩個虛擬交換機,兩個交換機上各自連線不同的容器,如上圖所示,此時如果要c1和c3通訊又該如何實現呢?其實我們可以通過命名空間建立一對網絡卡,一端連sw1,另一端連sw2,這樣一來兩個交換機就連起來了,照理說這樣一來c1和c3這兩個處於不同交換機的容器就可以實現通訊了,但是這樣一來又存在另乙個問題,那就是如果c1和c3在不同網路呢?如果不在同一網路我們就必須要通過路由**才能使其通訊,也就是我們得在兩台交換機之間加乙個路由器,其實linux核心本身就是支援路由**的,只需要我們將路由**功能開啟即可。此時我們可以再啟動乙個容器,這個容器裡面就跑乙個核心,並將其**功能開啟,這樣一來就模擬了一台路由器,通過這台路由器來實現路由**。

如上圖所示,此時如果c1要與c5進行通訊又該如何實現呢?如果我們採用橋接的方式,很容易產生廣播風暴,因此,在大規模的虛擬機器或容器的場景中,使用橋接的方式無疑是自取滅亡,所以我們不應該使用橋接的方式來實現通訊。

如果一來,我們既不能橋接,又需要與外部來實現通訊,那就只能使用nat技術了。通過dnat將容器的埠暴露到宿主機上,通過訪問宿主機的埠來實現訪問容器內部的目的,而在請求端我們需要做snat將資料報通過宿主機的真實網絡卡**出去。但這樣做的話,因為要進行兩次nat轉換,所以效率會比較低。

此時我們可以採用一種叫做overlay network(疊加網路)的技術來實現不同節點間容器的相互通訊功能。

overlay network會將報文進行隧道**,也就是在報文發出去之前要為其新增乙個ip首部,也就是上圖的1.1和1.2這部分,這裡的1.1是源,1.2是目標,當宿主機2收到報文後解封裝發現要找的目標容器是c2,於是把包**給c2。

docker容器虛擬化

network namespace 是 linux 核心提供的功能,是實現網路虛擬化的重要功能,它能建立多個隔離的網路空間,它們有獨自網路棧資訊。不管是虛擬機器還是容器,執行的時候彷彿自己都在獨立的網路中。而且不同network namespace的資源相互不可見,彼此之間無法通訊。假如我們的物理機...

Docker容器虛擬化

network namespace 是 linux 核心提供的功能,是實現網路虛擬化的重要功能,它能建立多個隔離的網路空間,它們有獨自網路棧資訊。不管是虛擬機器還是容器,執行的時候彷彿自己都在獨立的網路中。而且不同network namespace的資源相互不可見,彼此之間無法通訊。假如我們的物理機...

docker容器虛擬化

目錄network namespace 是 linux 核心提供的功能,是實現網路虛擬化的重要功能,它能建立多個隔離的網路空間,它們有獨自網路棧資訊。不管是虛擬機器還是容器,執行的時候彷彿自己都在獨立的網路中。而且不同network namespace的資源相互不可見,彼此之間無法通訊。假如我們的物...