文章目錄
1.docker原生網絡
docker在安裝好時會有3種網絡模型:bridge(默認),host,none
docker network ls
**docker在安裝好後會自動新建一個docker0的接口,所有的容器都會自動橋接到docker0 上 **
1.1 橋接模式
橋接模式下容器沒有公共ip,只有宿主機可以訪問,外部主機不可見。
容器要訪問外網必須通 過宿主機的NAT規則,所以在物理機上需要打開ip_forward路由轉發功能。
容器啓動時,默認會生成一個網絡對,一頭連接容器,一頭連接docker0,類似於網線的兩端,實現了容器和宿主機的數據互通。
docker run -d --name nginx nginx
brctl show
可以看到橋接到了docker0上
1.2 host模式
host模式可以讓容器共享宿主機的網絡棧,可以讓外部直接與容器通信,但是少了容器網絡的隔離性。
docker run -it --name vm1 --network host ubuntu
在容器內執行ipaddr,看到和宿主機一樣的網卡信息
ip addr
##發現確實和容器內看到的一致
1.3 none模式(禁用網絡模式)
有一些應用不需要連接外網,或者存放的數據是重要或祕密數據,可以使用none模式
docker run -it --name vm2 --network none ubuntu
在容器內執行ipaddr,可以看到只有一個lo接口
2.docker自定義網絡
三種網絡驅動:
1.bridge(自定義的bridge帶dns解析功能,可以 直接使用vm1vm2這種名字去訪問,不一定要使用ip)
2.overlay
3.macvlan,後面兩種用 於跨主機的網絡,也就是集羣等)
2.1 創建自定義網絡
docker network create --help
##可以看到如果不指定驅動,默認使用bridge
docker network create -d bridge my_net1
創建一個名爲 my_net1的自定義網絡
docker network ls
docker run -it --name vm1 --network my_net1 ubuntu
運行容器, 可以看到分配了一個172.18網段的ip,容器的ip是單調遞增,網段也是
docker network inspect my_net1
2.2 自定義網段、網關
docker network create -d bridge --subnet 172.22.0.0/24 --gateway 172.22.0.1 my_net2
指定子網和網關
docker network ls
docker run -it --name vm2 --network my_net2 ubuntu
運行容器查看ip addr,看到分配到了一個172.22.0.2的ip
2.3 自定義ip
docker run -it --name vm3 --network my_net2 --ip172.22.0.100 ubuntu
注意:使用–ip參數時,必須有之前的bridge網絡模式的配置–subnet
brctl show
看到my_net2上橋接了2塊網卡,my_net1 只有一個
iptables-S
查看防火牆規則,來自docker網卡之間的數據包雙向都被丟棄
2.4 配置容器間的通信
docker network connect my_net2 vm1
docker container attach vm1
可以看到vm1上現在有兩個子網的ip,ping容器名也能ping通,自帶dns解
vm1能ping通vm3的原因是給vm1上又添加了一個網絡接口並橋接在my_net2上
3.容器間的通信
3.1 內嵌DNSserver
除了使用–network指定ip訪問以外,docker在1.10以後,都會內嵌一個DNSserver
docker run -it --name vm1 --network my_net1 ubuntu
docker run -it --name vm2 --network my_net1 ubuntu
3.2 joined方式
joined方式類似於默認的host模式,容器之前共享網絡
docker run -it --name vm1 ubuntu
docker run -it --name vm2 --network container:vm1 ubuntu
指定共享的容器
這樣兩個容器之間可以使用localhost(迴環接口)進行快速通信,適用於web服務器和應用服務器。
3.3 使用–link來鏈接兩個容器
docker run -d nginx
先打開一個容器
docker ps
獲得系統分配的名稱
docker run -it --name vm1 --link elastic_cohen:web ubuntu
使用–link來鏈接兩個容器,可以ping通
容器裏做了下面兩件事:
1.容器裏添加了解析
2.環境變量裏設置了相應的地址和ip
docker stop elastic_cohen
docker run -d nginx
再打開一個新的nginx(讓172.17.0.2被佔用)
docker ps
docker inspect
docker start elastic_cohen
docker start vm1
iptables -t nat -S
查看火牆策略
docker network ls
查看docker網絡
docker container attach vm1
ping baidu發現是通的
容器訪問外網是通過iptables的SNAT實現的,容器和docker0是橋接的方式,docker0是容器的網關,到達docker0後,通過linux內核的路由功能(ip_forward),然後防火牆會做地址僞裝,也就是SNAT,然後通過物理網卡接口到外網
從防火牆策略和docker網絡中也可以看出,每個橋接都做了地址僞裝
4.外網如何訪問容器
docker run -d --name vm1 -p 80:80 nginx
做端口映射(冒號 後的是容器內部的端口)
docker port vm1
查看容器端口映射情況 80/tcp->0.0.0.0:80
iptables -t nat -S
查看防火牆策略
curl localhost
測試訪問
netstat -atnulp
每當運行一個容器,就會開啓一個docker-proxy進程
docker run -d --name vm2 -p 808:80 nginx
看到有2個docker-proxy進程
外部主機訪問時–> 宿主機的eth0(172.25.0.1:80)–>DNAT–>172.17.0.3(容器地址)
宿主機訪問本機容器使用iptables的DNAT,外部主機訪問容器或者容器之間訪問是docker-proxy實現的。
外部主機 --> 宿主機eth0–>docker-proxy(外部訪問容器時通過docker-proxy處理數據 包,不是防火牆)–>docker0(172.17.0.1)–> 容器
5.跨主機容器網絡
解決方案:
1)docker原生:overlay和macvlan
2)第三方:flannel、weave、calico
libnetwork(docker容器網絡庫)和docker集成在一起解決方案。其中CNM (ContainerNetworkModel)是libnetwork的核心,它對容器網絡進行了抽象)
CNM由3部分組成:
1.Sandbox:容器的網絡棧。包含容器的interface、路由表和DNS等 2.Endpoint:作用是將Sandbox接入Network。(生成vethpair,虛擬網絡對,相當於網線的兩端)
3.Network:包含一組Endpoint,同一Network的Endpoint可以直接通信
macvlan網絡方案實現(使用的是linux內核虛擬化技術,無需橋接,直接使用物理接口, 性能極好)
實驗環境:兩臺虛擬機
1.清理掉之前的容器,刪除自定義網絡
docker rm-f vm1
理掉之前的容器
docker network prune
刪除自定義網絡
2.給server1和server2各添加一塊虛擬網卡
ip link setup ens38
激活網卡
ip link set ens38 promisc on
都打開網卡的混雜模式
3.創建macvlan網絡模型
在server1
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
-oparent一定要加,因爲 macvlan模型不走橋接,直接走物理接口,所以需要指定
docker network ls
docker run -it --name vm1 --network macvlan1 --ip 172.20.0.12 ubuntu
運行容器,macvlan模型這裏必須手動指定ip地址,如果不指定會自動分配,單調 遞增,可能會衝突
在server2
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
docker run -it --name vm1 --network macvlan1 --ip 172.20.0.11 ubuntu
ping 172.20.0.11
在server1上ping server2的容器也通
brctl show
容器接口直接與主機網卡相連,無需NAT或端口映射
4.可以使用vlan子接口實現多macvlan網絡
vlan可以將物理二層網絡劃分爲4094個邏輯 網絡,彼此隔離,取值爲1~4094
在server1
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway 172.21.0.1 -o parent=ens38.1 macvlan2
創建邏輯網絡ens38.1
docker network ls
查看成功創建
ip addr
也可以看到子接口
docker run -it --name vm2 --network macvlan2 --ip 172.21.0.11 ubuntu
看到ip爲172.21.0.11 ,ping 172.20.0.11不通
在server2
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway 172.21.0.1 -o parent=ens38.1 macvlan2
創建邏輯網絡ens38.1
docker network ls
查看成功創建
docker run -it --name vm2 --network macvlan2 --ip 172.21.0.12 ubuntu
兩個容器互相ping對方ip通
注意:macvlan網絡在二層是隔離的,所以不同macvlan容器不能通信,可以在三層通過網關連接(加路由),docker本身不做任何限制,像傳統vlan那樣管理即可。網絡選型時如果對網絡比較熟悉,選macvlan較好,因爲只需要把網絡設備調整好,docker方面基本不用做什麼調整。