因爲docker技術的火爆,致使如今愈來愈多的企業都在使用docker這種虛擬化技術。企業中使用docker這種虛擬化技術,其目的就是爲了讓docker中的容器對外提供服務。所以,咱們必須深刻了解一下docker的網絡知識,以知足更高的網絡需求。linux
咱們安裝Docker時,它會自動建立三個網絡,bridge(建立容器默認鏈接到此網絡)、 none 、host。 * host:容器將不會虛擬出本身的網卡,配置本身的IP等,而是使用宿主機的IP和端口。 * None:該模式關閉了容器的網絡功能,至關於一個迴環網絡。 * Bridge:此模式會爲每個容器分配、設置IP等,並將容器鏈接到一個叫docker0的虛擬網橋,經過docker0網橋以及Iptables nat表配置與宿主機通訊。
[root@docker ~]# docker network ls //執行該命令查看docker建立的網絡 NETWORK ID NAME DRIVER SCOPE 2edf7ef4f9fa bridge bridge local 217d2e9a4785 host host local c0bea73a8e1a none null local
關於上述提到的三個網絡解釋以下:web
雖然docker模式提供三種網絡模式,但實際上是有四種網絡模式的!
注:今天只介紹Overlay網絡,Macvlan網絡,想了解其他三種網絡模式請參考:http://www.javashuo.com/article/p-rajoxwmu-nr.htmldocker
使用overlay網絡需事先部署好consul服務!bootstrap
consul:是一個服務網格(微服務間的 TCP/IP,負責服務之間的網絡調用、限流、熔斷和監控)解決方案,它是一個一個分佈式的,高度可用的系統,並且開發使用都很簡便。它提供了一個功能齊全的控制平面,主要特色是:服務發現、健康檢查、鍵值存儲、安全服務通訊、多數據中心。vim
經過一個實驗案例來驗證consul服務的特性!
1.案例環境瀏覽器
系統版本: Centos 7.3 Docker版本: 18.09.0 主機名IP地址: docekr01:192.16.45.129 docekr02:192.16.45.141 docekr03:192.16.45.142
二、準備工做:安全
* 必須安裝key-value存儲服務,如consul; * 宿主機已經安裝docker engine; * 宿主機的hostname必須不一樣 ,避免發生衝突 ; * 關閉防火牆與SELinux(實驗環境;
三、案例實施
1)docker01服務器
[root@docker01 ~]# docker pull progrium/consul //下載consul鏡像 [root@docker01 ~]# docker run -d -p 8500:8500 -h consul --name consul --restart=always progrium/consul -server -bootstrap //-d:後臺運行; //-p:將容器中的8500端口映射到宿主機的8500端口; //-h:表示consul容器的主機名; //--name:表示運行的容器名; //--restart=always:隨docker服務的啓動而啓動; //-server -bootstrap:添加這兩個選項,則表示在羣集環境中可使其以master的身份出現; [root@docker01 ~]# netstat -anpt | grep 8500 tcp6 0 0 :::8500 :::* LISTEN 3725/docker-proxy //肯定其8500端口正在監聽 [root@docker01 ~]# vim /usr/lib/systemd/system/docker.service //更改一下docker的主配置文件 ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.45.129:8500 --cluster-advertise=ens33:2376 //在第13行上本來的基礎添加以上內容,各個配置項含義以下: # /var/run/docker.sock:Docker的一個套接字; # 「 -H tcp://0.0.0.0:2376 」 :使用本機的tcp2376端口; # 「 --cluster-store=consul://192.168.45.129:8500」:指定運行着consul服務的docker服務器IP及端口; # 「 --cluster-advertise=ens33:2376」:從本機的ens33網卡經過2376端口蒐集網絡信息,存儲在consul上 [root@docker01 ~]# systemctl daemon-reload [root@docker01 ~]# systemctl restart docker.servic //從新啓動docker服務
使用瀏覽器訪問consul服務的web頁面
2)docker02網絡
[root@docker02 ~]# vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.45.129:8500 --cluster-advertise=ens33:2376 //在第13行上本來的基礎添加以上內容,各個配置項含義以下: # /var/run/docker.sock:Docker的一個套接字; # 「 -H tcp://0.0.0.0:2376 」 :使用本機的tcp2376端口; # 「 --cluster-store=consul://192.168.45.129:8500」:指定運行着consul服務的docker服務器IP及端口; # 「 --cluster-advertise=ens33:2376」:從本機的ens33網卡經過2376端口蒐集網絡信息,存儲在consul上 [root@docker02 ~]# systemctl daemon-reload [root@docker02 ~]# systemctl restart docker.service //從新啓動docker服務
訪問瀏覽器刷新瀏覽器頁面
3)Docker3tcp
Docker3與Docker2的操做就是如出一轍的,因此這裏就很少作解釋了!
[root@docker03 ~]# vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.45.129:8500 --cluster-advertise=ens33:2376 //在第13行上本來的基礎添加以上內容,各個配置項含義以下: # /var/run/docker.sock:Docker的一個套接字; # 「 -H tcp://0.0.0.0:2376 」 :使用本機的tcp2376端口; # 「 --cluster-store=consul://192.168.45.129:8500」:指定運行着consul服務的docker服務器IP及端口; # 「 --cluster-advertise=ens33:2376」:從本機的ens33網卡經過2376端口蒐集網絡信息,存儲在consul上 [root@docker03 ~]# systemctl daemon-reload [root@docker03 ~]# systemctl restart docker.service //從新啓動docker服務
注:若是在此過程當中,訪問web頁面若是出現「500」的錯誤頁面,將運行consul服務的容器刪除從新創新便可!
4)建立一個 overlay網絡
docker01:
[root@docker01 ~]# docker network create -d overlay my_olay //建立一個名爲my_olay的voerlay網絡 //以上操做無論在那臺docker主機上操做均可以 [root@docker01 ~]# docker network create -d overlay --subnet 200.0.0.0/24 --gateway 200.0.0.1 lv_olay //也能夠在建立overlay網卡時,指定其IP網段及網關 [root@docker01 ~]# docker network ls //查看docker所支持的網絡
注:
並且在另外兩臺docker服務器上也可看到,自行驗證!
在docker 1上建立的網絡,能夠看到其SPOCE(範圍)定義的是global(全局),那麼這就意味着加入consul這個服務羣集的其餘docker服務器也能夠看到這張網卡!
若是在建立網卡時,沒有指定其網段,則默認是10.0.0.0網段,因爲是自定義網絡,因此知足自定義網絡的特徵(好比支持容器之間的通訊)!
5)在不一樣的docker服務器各自建立一個容器,驗證是否能夠通訊!
[root@docker01 ~]# docker run -itd --name t1 --network lv_olay --ip 200.0.0.10 busybox:latest //在docker1服務器上建立一個名爲t1的容器並指定其IP地址 [root@docker02 ~]# docker run -itd --name t2 --network lv_olay --ip 200.0.0.20 busybox:latest //在docker2上建立一個容器並指定IP地址 [root@docker03 ~]# docker run -itd --name t3 --network lv_olay --ip 200.0.0.30 busybox:latest //在docker3上建立一個容器並指定IP地址 [root@docker01 ~]# docker exec -it t1 /bin/sh //隨便在一臺docker服務器上進入其建立的容器中,進行測試 / # ping -c 2 t2 PING t2 (200.0.0.20): 56 data bytes 64 bytes from 200.0.0.20: seq=0 ttl=64 time=1.053 ms 64 bytes from 200.0.0.20: seq=1 ttl=64 time=1.052 ms / # ping -c 2 t3 PING t3 (200.0.0.30): 56 data bytes 64 bytes from 200.0.0.20: seq=0 ttl=64 time=1.053 ms 64 bytes from 200.0.0.20: seq=1 ttl=64 time=1.052 ms
注:能夠看出IP地址,不一樣docker host上容器通訊是沒有問題的;
Macvlan是linux kernel比較新的特性,能夠經過如下方法判斷當前系統是否支持:
[root@localhost ~]# modprobe macvlan [root@localhost ~]# lsmod | grep macvlan macvlan 19239 0
若是是第一個命令報錯,或者第二個命令沒有返回信息,則說明當前系統不支持macvlan,須要升級內核。
[root@docker01 ~]# modprobe 8021q //加載內核模塊 [root@docker01 ~]# modinfo 8021q //若是有信息返回則表示開啓8021q模塊,若是沒有使用上條命令
這兩組命令所支持的效果同樣!
以上命令主要驗證Linux內核是否支持macvlan功能!
macvlan容許在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡接口有本身獨立的mac地址,也能夠配置IP地址進行通訊。macvlan下的虛擬機或者容器網絡和主機在同一網段中,共享一個廣播域。macvlan和bridge比較類似,但由於它省去了bridge的存在,因此在配置和調試時比較簡單,並且效率較高。除此以外,macvlan自身也完美支持VLAN。
若是但願容器或者虛擬機放在主機相同的網絡中,享受已經存在網絡棧的各類優點,能夠考慮macvlan。
macvlan和overlay網絡不一樣,overlay的做用範圍是global;而macvlan的做用範圍是local。global類型的網絡其做用於一組docker daemon集羣,local類型的網絡只做用於單一主機。
每臺主機建立的macvlan網絡是獨立的,A機器行建立的macvlan網絡並不影響B機器上的網絡。
docker版本:18.09.0 docker01:192.168.45.129/24 docker02:192.168.45.143/24 (1)關閉Linux防火牆和SELinux; (2)修改主機名;
二、案例實施
1)打開網卡的混雜模式
//須要在docker01和docker02上都進行操做。 [root@docker01 ~]# ip link set ens33 promisc on [root@docker01 ~]# ip link show ens33 [root@docker01 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1 //在docker01上建立macvlan網絡 //PS: -o parent=綁定在哪張網卡之上 [root@docker01 ~]# docker run -itd --name bbox1 --ip 172.22.16.10 --network mac_net1 busybox //基於建立的macvlan網絡運行一個容器
在docker02上建立macvlan網絡,注意與docker01上 的macvlan網絡如出一轍。
//須要在docker01和docker02上都進行操做。 [root@docker02 ~]# ip link set ens33 promisc on [root@docker02 ~]# ip link show ens33 [root@docker02 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o parent=ens33 mac_net1 [root@docker02 ~]# docker run -itd --name bbox2 --network mac_net1 --ip 172.22.16.20 busybox
驗證:
[root@docker01 ~]# docker exec -it bbox1 sh / # ping 172.22.16.20 PING 172.22.16.20 (172.22.16.20): 56 data bytes 64 bytes from 172.22.16.20: seq=0 ttl=64 time=0.884 ms 64 bytes from 172.22.16.20: seq=1 ttl=64 time=1.478 ms 64 bytes from 172.22.16.20: seq=2 ttl=64 time=1.182 ms
(1)開啓網卡混雜模式
docker01:
[root@docker01 ~]# ip link set ens33 promisc on //開啓網卡的混雜模式 [root@docker01 ~]# ip link show ens33 //查詢網卡已經支持PROMISC 2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 00:0c:29:33:22:73 brd ff:ff:ff:ff:ff:ff [root@docker01 ~]# modprobe 8021q /加載8021q內核模塊 [root@docker01~]# modinfo 8021q //有返回信息則表示支持8021q內核模塊
(2)建立虛擬網卡
因爲一個網卡最好建立出一個macvlan網卡,因此需建立虛擬網卡以知足要求!
[root@docker01 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=manual //將網絡獲取模式改成手動模式 [root@docker01 ~]# cd /etc/sysconfig/network-scripts/ [root@docker01 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10 [root@docker01 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.20 [root@docker01 network-scripts]# vim ifcfg-ens33.10 BOOTPROTO=none NAME=ens33.10 DEVICE=ens33.10 ONBOOT=yes IPADDR=192.168.10.1 NETMASK=255.255.255.0 GATEWAY=192.168.10.254 VLAN=yes //保證和本來的物理網卡不在同一網段,而且打開vlan的支持模式 [root@docker01 network-scripts]# vim ifcfg-ens33.20 BOOTPROTO=none NAME=ens33.20 DEVICE=ens33.20 ONBOOT=yes IPADDR=192.168.20.1 NETMASK=255.255.255.0 GATEWAY=192.168.20.254 VLAN=yes [root@docker01 network-scripts]# ifup ifcfg-ens33.10 [root@docker01 network-scripts]# ifup ifcfg-ens33.20 [root@docker01 network-scripts]# ifconfig ens33.10 [root@docker01 network-scripts]# ifconfig ens33.20 //查看網卡是否生效
docker02主機上的操做與docker01主機上的操做一致(注意IP不同)!要保證兩臺docker主機的虛擬網卡能夠通訊!
docker02:
[root@docker02 ~]# ip link set ens33 promisc on //開啓網卡的混雜模式 [root@docker02 ~]# ip link show ens33 //查詢網卡已經支持PROMISC 2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 00:0c:29:06:84:51 brd ff:ff:ff:ff:ff:ff [root@docker02 ~]# modprobe 8021q /加載8021q內核模塊 [root@docker02 ~]# modinfo 8021q //有返回信息則表示支持8021q內核模塊
[root@docker01 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=manual //將網絡獲取模式改成手動模式 [root@docker02 ~]# cd /etc/sysconfig/network-scripts/ [root@docker02 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10 [root@docker02 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.20 [root@docker02 network-scripts]# vim ifcfg-ens33.10 BOOTPROTO=none NAME=ens33.10 DEVICE=ens33.10 ONBOOT=yes IPADDR=192.168.10.2 NETMASK=255.255.255.0 GATEWAY=192.168.10.254 VLAN=yes [root@docker02 network-scripts]# vim ifcfg-ens33.20 BOOTPROTO=none NAME=ens33.20 DEVICE=ens33.20 ONBOOT=yes IPADDR=192.168.20.2 NETMASK=255.255.255.0 GATEWAY=192.168.20.254 VLAN=yes [root@docker01 network-scripts]# ifup ifcfg-ens33.10 [root@docker01 network-scripts]# ifup ifcfg-ens33.20 [root@docker02 network-scripts]# ifconfig ens33.10 [root@docker02 network-scripts]# ifconfig ens33.20
(3)建立macvlan網卡
[root@docker01 ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10 [root@docker01 ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20 //建立虛擬網卡並針對其網段、網關 //-d:指令網卡驅動類型,-o parent:綁定在那張網卡上 [root@docker01 ~]# docker network ls
docker02主機上的建立虛擬網卡時,命令如出一轍,指定的網段、名稱必須同樣,由於要保證其經過虛擬網卡能夠通訊!
[root@docker02 ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10 [root@docker02 ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20
(4)基於建立的macvlan網卡建立容器,驗證是否能夠通訊!
dockerA主機建立容器:
[root@docker01 ~]# docker run -itd --name box10 --network mac_net10 --ip 172.16.10.10 busybox [root@docker01 ~]# docker run -itd --name box20 --network mac_net20 --ip 172.16.20.10 busybox
dockerB主機建立容器:
[root@docker02 ~]# docker run -itd --name box11 --network mac_net10 --ip 172.16.10.20 busybox [root@docker02 ~]# docker run -itd --name box21 --network mac_net20 --ip 172.16.20.20 busybox
進入容器進行驗證:
[root@docker01 ~]# docker exec -it box10 /bin/sh / # ping 172.16.10.20 PING 172.16.10.20 (172.16.10.20): 56 data bytes 64 bytes from 172.16.10.20: seq=0 ttl=64 time=0.653 ms 64 bytes from 172.16.10.20: seq=1 ttl=64 time=0.966 ms [root@docker01 ~]# docker exec -it box20 /bin/sh/ # ping 172.16.20.20 PING 172.16.20.20 (172.16.20.20): 56 data bytes 64 bytes from 172.16.20.20: seq=0 ttl=64 time=0.734 ms 64 bytes from 172.16.20.20: seq=1 ttl=64 time=0.718 ms
注:如若出現不能通信的狀況!請把實驗環境兩臺docker虛擬機調製爲橋接模式;