首先,要實現(xiàn)網(wǎng)絡通信,機器需要至少一個網(wǎng)絡接口(物理接口或虛擬接口)來收發(fā)數(shù)據(jù)包;此外,如果不同子網(wǎng)之間要進行通信,需要路由機制。
Docker 中的網(wǎng)絡接口默認都是虛擬的接口。虛擬接口的優(yōu)勢之一是轉(zhuǎn)發(fā)效率較高。 Linux 通過在內(nèi)核中進行數(shù)據(jù)復制來實現(xiàn)虛擬接口之間的數(shù)據(jù)轉(zhuǎn)發(fā),發(fā)送接口的發(fā)送緩存中的數(shù)據(jù)包被直接復制到接收接口的接收緩存中。對于本地系統(tǒng)和容器內(nèi)系統(tǒng)看來就像是一個正常的以太網(wǎng)卡,只是它不需要真正同外部網(wǎng)絡設備通信,速度要快很多。
Docker 容器網(wǎng)絡就利用了這項技術。它在本地主機和容器內(nèi)分別創(chuàng)建一個虛擬接口,并讓它們彼此連通(這樣的一對接口叫做 veth pair)。
創(chuàng)建網(wǎng)絡參數(shù)
Docker 創(chuàng)建一個容器的時候,會執(zhí)行如下操作:
創(chuàng)建一對虛擬接口,分別放到本地主機和新容器中;
本地主機一端橋接到默認的 docker0 或指定網(wǎng)橋上,并具有一個唯一的名字,如 veth65f9;
容器一端放到新容器中,并修改名字作為 eth0,這個接口只在容器的名字空間可見;
從網(wǎng)橋可用地址段中獲取一個空閑地址分配給容器的 eth0,并配置默認路由到橋接網(wǎng)卡 veth65f9。
完成這些之后,容器就可以使用 eth0 虛擬網(wǎng)卡來連接其他容器和其他網(wǎng)絡。
可以在 docker run 的時候通過 --net 參數(shù)來指定容器的網(wǎng)絡配置,有4個可選值:
--net=bridge 這個是默認值,連接到默認的網(wǎng)橋。
--net=host 告訴 Docker 不要將容器網(wǎng)絡放到隔離的名字空間中,即不要容器化容器內(nèi)的網(wǎng)絡。此時容器使用本地主機的網(wǎng)絡,它擁有完全的本地主機接口訪問權限。容器進程可以跟主機其 它 root 進程一樣可以打開低范圍的端口,可以訪問本地網(wǎng)絡服務比如 D-bus,還可以讓容器做一些影響整個主機系統(tǒng)的事情,比如重啟主機。因此使用這個選項的時候要非常小心。如果進一步的使用 --privileged=true,容器會被允許直接配置主機的網(wǎng)絡堆棧。
--net=container:NAME_or_ID 讓 Docker 將新建容器的進程放到一個已存在容器的網(wǎng)絡棧中,新容器進程有自己的文件系統(tǒng)、進程列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網(wǎng)絡資源,兩者進程可以直接通過 lo 環(huán)回接口通信。
--net=none 讓 Docker 將新容器放到隔離的網(wǎng)絡棧中,但是不進行網(wǎng)絡配置。之后,用戶可以自己進行配置。
四種單節(jié)點網(wǎng)絡模式
1、bridge 模式
Docker 容器默認使用 bridge 模式的網(wǎng)絡。其特點如下:
使用一個 linux bridge,默認為 docker0
使用 veth 對,一頭在容器的網(wǎng)絡 namespace 中,一頭在 docker0 上
該模式下Docker Container不具有一個公有IP,因為宿主機的IP地址與veth pair的 IP地址不在同一個網(wǎng)段內(nèi)
Docker采用 NAT 方式,將容器內(nèi)部的服務監(jiān)聽的端口與宿主機的某一個端口port 進行“綁定”,使得宿主機以外的世界可以主動將網(wǎng)絡報文發(fā)送至容器內(nèi)部
外界訪問容器內(nèi)的服務時,需要訪問宿主機的 IP 以及宿主機的端口 port
NAT 模式由于是在三層網(wǎng)絡上的實現(xiàn)手段,故肯定會影響網(wǎng)絡的傳輸效率。
容器擁有獨立、隔離的網(wǎng)絡棧;讓容器和宿主機以外的世界通過NAT建立通信
2、Host 模式
定義:
Host 模式并沒有為容器創(chuàng)建一個隔離的網(wǎng)絡環(huán)境。而之所以稱之為host模式,是因為該模式下的 Docker 容器會和 host 宿主機共享同一個網(wǎng)絡 namespace,故 Docker Container可以和宿主機一樣,使用宿主機的eth0,實現(xiàn)和外界的通信。換言之,Docker Container的 IP 地址即為宿主機 eth0 的 IP 地址。其特點包括:
這種模式下的容器沒有隔離的 network namespace
容器的 IP 地址同 Docker host 的 IP 地址
需要注意容器中服務的端口號不能與 Docker host 上已經(jīng)使用的端口號相沖突
host 模式能夠和其它模式共存
3、container 模式
定義:
Container 網(wǎng)絡模式是 Docker 中一種較為特別的網(wǎng)絡的模式。處于這個模式下的 Docker 容器會共享其他容器的網(wǎng)絡環(huán)境,因此,至少這兩個容器之間不存在網(wǎng)絡隔離,而這兩個容器又與宿主機以及除此之外其他的容器存在網(wǎng)絡隔離。
4、none 模式
定義:
網(wǎng)絡模式為 none,即不為 Docker 容器構(gòu)造任何網(wǎng)絡環(huán)境。一旦Docker 容器采用了none 網(wǎng)絡模式,那么容器內(nèi)部就只能使用loopback網(wǎng)絡設備,不會再有其他的網(wǎng)絡資源。Docker Container的none網(wǎng)絡模式意味著不給該容器創(chuàng)建任何網(wǎng)絡環(huán)境,容器只能使用127.0.0.1的本機網(wǎng)絡。
實驗:
rhel7.3 172.25.12.250(物理機)
啟動一個容器,不指定時,容器默認使用 bridge 模式
[root@foundation12 ~]# docker run -it --name web ubuntu
查看物理機
物理機橋接情況
設定為none 模式
[root@foundation12 ~]# docker run -it --name vm1 --net none ubuntu
查看PID:
[root@foundation12 ~]# docker inspect -f '{{.State.Pid}}' vm1
虛擬化網(wǎng)絡都是基于netns 實現(xiàn),netns 可以創(chuàng)建一個完全隔離的新網(wǎng)絡環(huán)境,這個環(huán)境包括一個獨立的網(wǎng)卡空間,路由表,ARP表,ip地址表,iptables等??傊?,與網(wǎng)絡有關的組件都是獨立的。
eg:
[root@foundation12 netns]# ip link add name veth0 type veth peer name veth1 添加網(wǎng)口到namespace(創(chuàng)建端口對)
在當前namespace可以看到veth0和veth1
[root@foundation12 ~]# ip link list 查看端口對
[root@foundation12 netns]# brctl addif docker0 veth0 將veth0加入docker0這個網(wǎng)橋
默認網(wǎng)橋都是down的,置為up狀態(tài)
[root@foundation12 netns]# ip addr
[root@foundation12 netns]# ip link set up veth0
[root@foundation12 netns]# ip link set up veth1
[root@foundation12 netns]# ip link set veth1 netns 4943 增加端口到namespace
查看net namespace
修改名字,添加IP和網(wǎng)關
[root@foundation12 netns]# ip netns exec 4943 ip link set veth1 name eth0
[root@foundation12 netns]# ip netns exec 4943 ip link set up eth0
[root@foundation12 netns]# ip netns exec 4943 ip addr add 172.17.0.100/24 dev eth0
[root@foundation12 netns]# ip netns exec 4943 ip route add default via 172.17.0.1
如下效果,none網(wǎng)絡變得可以通信
聯(lián)系客服