docker容器虛擬化


1.虛擬化網絡

Network Namespace 是 Linux 內核提供的功能,是實現網絡虛擬化的重要功能,它能創建多個隔離的網絡空間,它們有獨自網絡棧信息。不管是虛擬機還是容器,運行的時候仿佛自己都在獨立的網絡中。而且不同Network Namespace的資源相互不可見,彼此之間無法通信。

假如我們的物理機有4塊物理網卡,我們要創建4個名稱空間,而這些設備是可以單獨關聯至某個單獨的名稱空間使用的


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

這種方式使得每一個名稱空間都能配置IP地址,並且與外部網絡直接通信,因為它們使用的是物理網卡。

但如果我們所擁有的名稱空間數量超過物理網卡數量呢?此時我們可以使用虛擬網卡設備,用純軟件的方式來模擬一組設備來使用。Linux內核級支持2種級別設備的模擬,一種是二層設備,一種是三層設備。

Linux內核模擬的二層設備,每個網絡接口設備是成對出現的,可以模擬為一根網線的兩端,其中一端模擬主機的虛擬網卡,另一端模擬虛擬交換機,就相當於讓一個主機連到一個交換機上去。Linux內核原生支持二層虛擬網橋設備,即用軟件虛擬交換機的功能。如下圖所示:

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

從網絡通信的物理設備到網卡都是用純軟件的方式來實現,這種實現方式就叫做虛擬化網絡。

2.單節點容器間通信

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

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

我們做兩個虛擬交換機,兩個交換機上各自連接不同的容器,如上圖所示,此時如果要C1和C3通信又該如何實現呢?其實我們可以通過名稱空間創建一對網卡,一端連SW1,另一端連SW2,這樣一來兩個交換機就連起來了,照理說這樣一來C1和C3這兩個處於不同交換機的容器就可以實現通信了,但是這樣一來又存在另一個問題,那就是如果C1和C3在不同網絡呢?如果不在同一網絡我們就必須要通過路由轉發才能使其通信,也就是我們得在兩台交換機之間加一個路由器,其實Linux內核本身就是支持路由轉發的,只需要我們將路由轉發功能打開即可。此時我們可以再啟動一個容器,這個容器里面就跑一個內核,並將其轉發功能打開,這樣一來就模擬了一台路由器,通過這台路由器來實現路由轉發。

3.不同節點容器間通信


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

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

此時我們可以采用一種叫做Overlay Network(疊加網絡)的技術來實現不同節點間容器的相互通信功能。

Overlay Network會將報文進行隧道轉發,也就是在報文發出去之前要為其添加一個IP首部,也就是上圖的1.1和1.2這部分,這里的1.1是源,1.2是目標,當宿主機2收到報文后解封裝發現要找的目標容器是C2,於是把包轉發給C2。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM