Docker網絡管理之docker跨主機通訊

前言

因爲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

  • Host:至關於Vmware中的橋接模式,與宿主機在同一個網絡中,但沒有獨立的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和端口。基於Host模式啓動的容器,在容器內執行ifconfig時,看到的都是宿主機上的信息。該模式不夠靈活,容易出現端口衝突問題。
  • None:該模式將容器放置在它本身的網絡棧中,可是並不進行任何配置。實際上,該模式關閉了容器的網絡功能,相似於會換地址,在如下兩種狀況下是有用的:容器並不須要網絡(例如只須要寫磁盤卷的批處理任務)。
  • overlay:顧名思義:覆蓋,但它又不是覆蓋,它的做用就是在容器原有的網絡基礎之上,再添加一塊網卡,併爲其分配一個IP地址,能夠將全部的docker容器關聯到同一個局域網中,適用於容器與容器是跨主機進行通訊的場景。
  • Bridge:至關於Vmware中的NAT模式,容器使用獨立的network Namespace,而且鏈接到docker0虛擬網卡(默認模式)。經過docker網橋以及IPtables nat表配置與宿主機通訊;Bridge模式是Docker默認的網絡設置,此模式會爲每個容器分配一個Network nameSpace、設置IP等,並將一個主機上的Docker容器鏈接到一個虛擬網橋docker0上

雖然docker模式提供三種網絡模式,但實際上是有四種網絡模式的!
注:今天只介紹Overlay網絡,Macvlan網絡,想了解其他三種網絡模式請參考:http://www.javashuo.com/article/p-rajoxwmu-nr.htmldocker

1、Overlay網絡

使用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頁面
Docker網絡管理之docker跨主機通訊
Docker網絡管理之docker跨主機通訊
Docker網絡管理之docker跨主機通訊
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服務

訪問瀏覽器刷新瀏覽器頁面
Docker網絡管理之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服務

Docker網絡管理之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跨主機通訊
注:

  • 並且在另外兩臺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上容器通訊是沒有問題的;

    2、Macvlan網絡

    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機器上的網絡。

  • 兩臺主機在網卡配置混雜模式、兩臺主機上macvlan存在overlap、兩個macvlan網絡沒有分配過一樣的IP,以上三個條件知足後,一樣能夠實現跨主機通訊!
    一、實驗環境要求
    docker版本:18.09.0
    docker01:192.168.45.129/24
    docker02:192.168.45.143/24
    (1)關閉Linux防火牆和SELinux;
    (2)修改主機名;

    二、案例實施

    一)、macvlan的單網絡通訊

    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

二)、macvlan多網絡通訊

(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   //查看網卡是否生效

Docker網絡管理之docker跨主機通訊
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

Docker網絡管理之docker跨主機通訊
(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

Docker網絡管理之docker跨主機通訊
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虛擬機調製爲橋接模式;
Docker網絡管理之docker跨主機通訊

相關文章
相關標籤/搜索