1. 程式人生 > 實用技巧 >Linux虛擬網路:Docker網路知識之基礎篇

Linux虛擬網路:Docker網路知識之基礎篇

我們在工作中應用了docker容器化技術,服務的部署、維護和擴充套件都方便了很多。然而,近期在私有化部署過程中,由於不同伺服器環境的複雜多變,常常遇到網路方面的問題,現象為容器服務執行正常,但宿主機、容器之間網路不通。

本篇部落格旨在總結:

  • Linux虛擬網路及docker網路的基礎知識
  • 遇到網路問題時排查問題思路
  • 常用指令和工具的使用

以上三部分作為之後的參考,本篇文章也將會在日後實踐過程中逐漸補充。本篇為第一篇,主要介紹基礎知識

Linux網路虛擬化基礎

Network Namespace

網路名稱空間,是Linux 2.6.x核心版本之後提供的功能,主要用於資源的隔離。namespace是實現網路虛擬化的重要功能,使用它,一個Linux系統可以抽象出多個網路子系統,各個子系統都有自己獨立的網路卡、路由表、iptables、協議棧等網路資源。不管是虛擬機器器還是容器,執行時彷彿自己都在獨立的網路中。

ip netns命令用於完成對ns的各種操作,ip netns exec子命令用於在namespace執行指令。

Veth Pair(Virtual Ethernet Pair)

成對虛擬裝置埠。它總是成對出現,一端連著協議棧,一端彼此連著。從其中一個埠發出的資料包,可以直接出現在與它對應的另一個埠上,即使它們在不同的namespace中。



如上圖,一對veth-pair直接將兩個namespace連線在一起。

  • 使用如下圖所示命令,測試veth pair功能

Bridge 網橋

veth pair打破了Network Namespace的限制,實現了不同Network Namespace之間的通訊。但是veth pair的侷限性也很明顯,只能實現兩個網路介面的通訊。


Linux中引入網橋來實現多個網路介面之間的通訊,可以將一臺機器上的若干介面連通起來。在OSI網路模型中,網橋屬於資料鏈路層。

和網橋相關的操作使用命令brctl,需要先安裝bridge-utils工具包。安裝指令:

yum install bridge-utils

iptables/Netfilter

請參考:iptables詳解(1):iptables概念

Docker網路基礎

Docker支援四種網路模式:host模式,container模式,none模式和bridge模式。預設使用的是橋接模式。

使用docker network ls指令可以檢視到宿主機上所有的Docker網路:

Bridge 橋接模式

Docker在啟動時,預設會自動建立網橋裝置docker0,Docker在執行時,守護程式通過docker0為docker的容器提供網路通訊服務。

當Docker啟動容器時,會建立一對Veth Pair,並將其中一個veth網路裝置附加到網橋docker0,另一個加入容器的network namespace中。

根據上一節中關於網橋的定義,我們很容易畫出示意圖:

由上圖可得,容器可以通過網橋互相通訊。如果不想使用預設的網橋裝置,也可以在啟動docker daemon的時候使用 --bridge==BRIDGE引數指定其他網橋。

然而這還不夠,Docker容器還需要與外網進行相互通訊。這裡涉及到NAT相關知識。

  • NAT

    網路地址轉換,就是替換IP報文頭部的地址資訊。NAT通常部署在一個組織的網路出口位置,通過將內部網路IP地址替換為出口的IP地址,提供公網可達性和上層協議的連結地址。(請參考:NAT相關科普
  • SNAT

    源地址轉換即內網地址向外訪問時,發起訪問的內網ip地址轉換為指定的ip地址(可指定具體的服務以及相應的埠或埠範圍),這可以使內網中使用保留ip地址的主機訪問外部網路,即內網的多部主機可以通過一個有效的公網ip地址訪問外部網路。

使用iptables -t nat -vnL指令檢視宿主機NAT表。

檢視規則:

2051 125K MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0

這條規則就關係著Docker容器與外界的通訊,含義為將源地址為172.17.0.0/16的資料包(就是docker容器中發出的資料),如果不是從docker0網路卡發出時,做SNAT轉換,將IP包的源地址替換為相應網路卡的地址。

對於外界來說,從docker容器內發出的請求,和宿主機發出的請求相同。

外界想要訪問Docker容器的服務呢?

在啟動docker容器時,我們使用 -p引數指定埠,這時其實是在iptables中添加了規則,如下圖所示:

DNAT規則,將傳送到宿主機的流量轉發到真正提供服務的容器IP埠上。

host模式

Docker容器與宿主機使用相同的網路環境,直接使用宿主機的IP和埠及其他網路裝置。這樣雖然避免了很多橋接帶來的網路問題,但同時也容易造成網路環境的混淆和衝突,比如埠被佔用等。不推薦。

container

指定與某一容器共享網路。

none

不配置任何網路。

--link

docker容器之間還可以通過--link闡述進行通訊,當提供服務的容器只希望個別容器能夠訪問時,我們可以使用該指令,提供更為高效、安全的連線方式。

小結

對Linux虛擬網路基礎知識的簡單學習後,有助於理清楚下一步排查問題思路。

下一篇部落格將介紹目前遇到問題時的排查思路和解決方案,並列舉一些常用工具。