docker網絡模式

我們在使用docker run創建Docker容器時,可以用--net選項指定容器的網絡模式,Docker有以下4種網絡模式:
1.host模式,使用--net=host指定。

2.container模式,使用--net=container:NAME_or_ID指定。

3.none模式,使用--net=none指定。

4.bridge模式,使用--net=bridge指定,默認設置

5.overlay模式:使用--net=overlay(覆蓋網絡,跨主機通信)

一、host模式

Docker使用的網絡實際上和宿主機一樣,在容器內看到的網卡ip是宿主機上的ip。

衆所周知,Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離進程,Mount Namespace隔離文件系統,Network Namespace隔離網絡等。一個Network Namespace提供了一份獨立的網絡環境,包括網卡、路由、Iptable規則等都與其他的Network Namespace隔離。一個Docker容器一般會分配一個獨立的Network Namespace。但如果啓動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口

docker run -it --net=host centos /bin/bash
docker網絡模式
可以看到容器內網卡直接複用宿主機網絡,該模式將禁用Docker容器的網絡隔離
docker網絡模式

二、container模式
多個容器使用共同的網絡看到的ip是一樣的。

在理解了host模式後,這個模式也就好理解了。這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口範圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過lo網卡設備通信

例子:
docker run -it --net=container:169c875f4ba0 centos /bin/bash (複用169c875f4ba0容器的網絡)
docker網絡模式
可以看出和容器169c875f4ba0的網絡環境一樣

三、none模式
這種模式下不會配置任何網絡。

這個模式和前兩個不同。在這種模式下,Docker容器擁有自己的Network Namespace,但是,並不爲Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。需要我們自己爲Docker容器添加網卡、配置IP等。
例子:
docker run -it --net=none centos /bin/bash
docker網絡模式
可以看出,並沒有配置網卡信息,需要自己手動配置
docker網絡模式

四、bridge模式
bridge模式是Docker默認的網絡設置,此模式會爲每一個容器分配Network Namespace、設置IP等,並將一個主機上的Docker容器連接到一個虛擬網橋上。

同一個宿主機上的所有容器會在同一個網段下,相互之間是可以通信的

例子:
docker run -it --net=bridge centos /bin/bash
docker網絡模式

docker網絡模式

對比宿主機網橋,發現容器內網卡和宿主機網橋在同一網段.
通過網橋和外界通信
docker網絡模式

五、overlay neetwork模式(跨主機通信)
容器在兩個跨主機進行通信的時候,是使用overlay network這個網絡模式進行通信,如果使用host也可以實現跨主機進行通信,直接使用這個物理的ip地址就可以進行通信。overlay它會虛擬出一個網絡比如10.0.9.3這個ip地址,在這個overlay網絡模式裏面,有一個類似於服務網關的地址,然後把這個包轉發到物理服務器這個地址,最終通過路由和交換,到達另一個服務器的ip地址
在docker容器裏面overlay 是怎麼實現的呢

例子:
宿主機:172.16.1.56,172.16.1.57 修改
vim /lib/systemd/system/docker.service
docker網絡模式
修改啓動參數
--cluster-store 指定 consul 的地址。
--cluster-advertise 告知 consul 自己的連接地址。
之後重啓docker
systemctl daemon-reload
systemctl restart docker.service

使用docker部署服務發現工具consul
docker run -d -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h consul progrium/consul -server -bootstrap -ui-dir /ui

http://172.16.1.57:8500/
可以看到已經存在的服務
docker網絡模式

查看目前的網絡模式
docker網絡模式
創建overlay網絡
docker網絡模式
-d overlay: 指定driver爲overlay
可以注意到ov_net1的scope爲global

在另一臺機器傻女查看網絡模式
docker網絡模式
發現也存在ov_net1網絡

查看網絡詳細信息
docker網絡模式

創建容器
docker run -it --net=ov_net1 centos /bin/bash
docker網絡模式
發現兩個不同主機的容器可以ping通

恢復netns命名空間
執行下面的命令來獲取容器進程號
docker inspect adaea943f075|grep Pid

ln -s /proc/26398/ns/net /var/run/netns/adaea943f075(容器id) #netns目錄不存在則創建

查看網絡空間
docker網絡模式

恢復docker容器netns
ln -s /var/run/docker/netns /var/run/netns

查看指定網絡命名空間的網絡
ip netns exec 1-46663fb66b ip addr
docker網絡模式

查看網絡網卡
ip netns exec 1-46663fb66b brctl show

實現步驟
從這個通信過程中來看,跨主機通信過程中的步驟如下:

容器的網絡命名空間與overlay網絡的網絡命名空間通過一對veth pair連接起來,當容器對外通信時,veth pair起到網線的作用,將流量發送到overlay網絡的網絡命名空間中。
容器的veth pair對端eth2與vxlan設備通過br0這個Linux bridge橋接在一起,br0在同一宿主機上起到虛擬機交換機的作用,如果目標地址在同一宿主機上,則直接通信,如果不再則通過設置在vxlan1這個vxlan設備進行跨主機通信。
vxlan1設備上會在創建時,由docker daemon爲其分配vxlan隧道ID,起到網絡隔離的作用。
docker主機集羣通過key/value存儲共享數據,在7946端口上,相互之間通過gossip協議學習各個宿主機上運行了哪些容器。守護進程根據這些數據來在vxlan1設備上生成靜態MAC轉發表。
根據靜態MAC轉發表的設置,通過UDP端口4789,將流量轉發到對端宿主機的網卡上。
根據流量包中的vxlan隧道ID,將流量轉發到對端宿主機的overlay網絡的網絡命名空間中。
對端宿主機的overlay網絡的網絡命名空間中br0網橋,起到虛擬交換機的作用,將流量根據MAC地址轉發到對應容器內部。
雖然上面的網絡通信模型可以實現容器的跨主機通信,但還是有一些缺陷,造成實際使用上的不便,例如:

由於vxlan網絡與宿主機網絡默認不再同一網絡環境下,爲了解決宿主機與容器的通信問題,docker爲overlay網絡中的容器額外增加了網卡eth1作爲宿主機與容器通信的通道。這樣在使用容器服務時,就必須根據訪問性質的不同,選擇不同的網卡地址,造成使用上的不便。
容器對外暴露服務仍然只能使用端口綁定的方式,外界無法簡單地直接使用容器IP訪問容器服務。
從上面的通信過程中來看,原生的overlay網絡通信必須依賴docker守護進程及key/value存儲來實現網絡通信,約束較多,容器在啓動後的一段時間內可能無法跨主機通信,這對一些比較敏感的應用來說是不可靠的。
docker網絡模式

不通overlay network網絡空間的容器如何通信
使用連接網絡
docker network connect ov_net1 containId(容器名或者ID) (該容器位於另一個網絡空間)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章