四層結構
我們考慮四層的網絡結構,如下圖右側:
由這個圖,我們可以簡單得到幾個結論:
① 網卡層的轉發,是靠MAC地址;
② 網絡層的轉發,是靠IP地址;
③ 傳輸層的轉發,是靠端口;
⑤ Socket就是操作系統提供的,通過一個fd的占用,就可以屏蔽下面的工作,順利讀取數據,并做對應協議解析;
⑥ 對于輸入的數據,從下到上解析;對于輸出的數據,從上到下解析;當然也有可能是平級傳輸(在對等情況下,忽略上下過程);
⑦ 數據包轉發過程中,IP地址是不會改變的,都是通過MAC地址改變來傳遞,除非做了NAT;
⑧ 網橋和交換機工作在第一層;NAT工作在第三層;
橋接與交換機[1]
橋接原理
可以看到,網橋通過記錄A、B兩個端口的MAC地址,可以實現在第一層解包后,向另一個網段轉發消息。
交換機原理
可以知道,交換機上面是有N個插口的,所以他的表記錄的內容是每一個插口的MAC地址。
此時如果某個插口對應的是交換機,就會進一步套娃:在外層交換機視角,記錄可能被內存交換機反復刷新,觸發“擴散”操作,即廣播到內層;在內層交換機視角,有所記錄,直接轉發即可。
特征
① 網卡層;
② 集中式管理,即所有節點會先發送到網橋,再轉發,即使是內網設備;
③ 能實現內網穿透,但是因為ip地址,不能在公網訪問。
NAT
NAT不是特指一個設備,更多是指實現了一個功能。
原理
可以看到,NAT實現了將一個“IP+Port”替換為另一個“IP+Port”的功能。
從IP角度,此時這個設備必須同時存在于“公網IP環”上和“內網IP環”上,同時也正是這個功能,使得數據能在兩個環上跳轉。
特征
① 傳輸層
② IP地址會發生變化
③ 兩個環的交匯處
Docker的網絡模式
常見的網絡模式有5種,分別為
- bridge:實際上是NAT模式;Docker中默認的網絡驅動模型,在啟動容器時如果不指定則默認為此驅動類型;
- host:實際上是橋接模式;打破Docker容器與宿主機之間的網絡隔離,直接使用宿主機的網絡環境,該模型僅適用于Docker17.6及以上版本;
- overlay:可以連接多個docker守護進程或者滿足集群服務之間的通信;適用于不同宿主機上的docker容器之間的通信;
- none:即禁用了網絡驅動,需要自己手動自定義網絡驅動配置;
- plugins:使用第三方網絡驅動插件;
主要關注橋接(Bridge)模式
可以很明顯看到,docker0作為一個虛擬網橋(擁有ip),和ens160這個物理網卡做了橋接(ip_forwad),然后Docker Container在連在虛擬網卡的環上。
此時兩個環就出來了,只不過,內層環是在宿主機內部的。
無論這個模式叫什么名字,我們都要清楚,他的實現實際上是NAT,也就是說,container的網絡是在宿主機的下層網絡,即如果不通過宿主機,宿主機同級網絡無法訪問container網絡。
為什么要叫橋接模式呢?
我個人更傾向于叫做NAT模式,除了滿足NAT的一些特征,一些相關組件也能和NAT對應上,比如地址轉換是通過iptables轉換的(而不是通過一個表)
but 暫且認為是docker覺得自己docker0最精妙的地方就是網卡和veth-pair的設計,所以取名叫做橋接模式吧,同時它抽象了iptables的功能,讓讀者認為他就是簡單能將container的流量轉發到docker0上(忽略ip地址變化,甚至認為公網上就直接是指向container的ip),此時就滿足了橋接的含義。
VMware的網絡模式
一共有三種網絡模式:橋接模式(VMnet0)、NAT(VMnet8)、僅主機模式(VMnet1)
橋接模式
對于虛擬機的流量,會被物理網卡轉發到虛擬交換機上再轉發,所以可以認為路由器直接相連交換機,交換機再與這些網卡平等相連。
它橋接了物理網卡,這樣物理網卡的消息就能轉發到虛擬機上。
注意,VMnet0只是一個擺設,沒有實際用處。
NAT模式
圖示中的NAT設備如同iptables一樣,對發送過來的ip地址做轉換;我們知道,NAT必須要主動向外界發消息,不然無法訪問內部,即我們不能走"物理網卡-NAT設備"這條線相連,為了解決這個問題,于是引入了VMnet8,使得物理機網絡與虛擬網絡有一個重疊,這樣通過VMnet8可以訪問到虛擬機(如主機模式)。
主機模式
圖示很明顯,我們在物理機想訪問虛擬網絡,只有通過VMnet8,但是VMnet8又與物理網卡隔離,這樣整個虛擬網絡都無法被外界訪問。
Docker端口映射猜想
我們都知道,在啟動一個container的時候,如果想要公網訪問(即不在機器上直接訪問),必須要做端口映射,如“-p 9980:80”。
- 從原理上,這個參數代表了iptables中增加了一條轉換規則(這不就是NAT嗎!),這樣流量就能打到對應的container上了。
- (猜想)具體的數據流向
<1.14.46.100:8723, 1.14.46.101:12443>
,其中1.14.46.101
為宿主機路由器的公網IP,當數據到達路由器時,觸發NAT,進入下一層網絡:<1.14.46.100:8723, 192.168.1.10:9980>
,由路由器送到宿主機,iptables攔截下,轉發到再下一層網絡(下證):<1.14.46.100:8723, 172.18.0.2:80>
,此時就完成了從公網打到container的流程。 - 宿主機上一定有一個socket文件(可能在overlay中),在監聽
172.18.0.2:80
這個端口,這樣container中的應用就能從這里面取出數據進行應用層的處理了。
這個參數會帶來一個iptables的增加,如下,作用是將主機9980的流量,轉發到172.17.0.2:80上。
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 9980 -j DNAT --to-destination 172.17.0.2:80
[1](網絡基礎之網橋和交換機的工作原理及區別ugly_girl的博客-CSDN博客網橋和交換機的區別)
[2](VMware Workstation 的三種網絡模式 - 知乎 (zhihu.com))
[3](iptables詳解及docker的iptables規則_摩洛哥M的博客-CSDN博客_docker iptables)