Docker网络管理之docker跨主机通信

前言

由于docker技术的火爆,导致现在越来越多的企业都在使用docker这种虚拟化技术。企业中使用docker这种虚拟化技术,其目的就是为了让docker中的容器对外提供服务。因此,我e I N ` U e +们必须深入了解一下docker的网络知识,以满足更高网络需求。


我们安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host。
* host:容器x A B c将不会虚拟l T u出自己的网卡,配置6 E 5 q自己的IP等,而是使用宿主机的IP和端口。
* None:该模式关闭了容器的网络功能,相当于一个回环网络。
* Bridge:此模式会为每一个容器分配、设置IP等,并将容器连接到一个叫docker0的虚拟网G , * 4 * T l桥,? Z I ` d = u _ K通过docker0网桥以及Iptables nat表配置与宿主机通信。
[root@doP B o $cker ~]# docker network  ls          //执行该命令查看docker创建的网络
NETWORK ID          NAME                DRIVER              SCOPE
2edf7ef4f9fa        bridge              bridge              local
217d2e9a4785        host                host                local
c0bea73a8e1a        none                null                local

关于上述提到的三个网络解释如下:

  • Host:相当于Vmware中的桥接模式,与宿主机在同一个网络中,但8 . 3没有独立的IP地址。众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespac^ R I 1 E ] ^e隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一R B g 5 ~个Network NC Z I # & @amespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network NaW m P ; xmespace。但如果启动容器的时候使用hostJ [ t i ( :^ W 3式,那么这个容r 5 : _ - i器将不会获得一个独立的Network Namespace,而是和2 u宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿& k H G L | , $主机的IP和端口。基于Host模式启动的容器,在容器内执行ifconfig时,看到的都是宿主机上的信息。该模式不够灵活,容易出现端口冲突问题。
  • None:该模式将容器放置在它自己的网络栈中,但是并不t d X 2 Q H k W 7进行任何配置。实际上,该模式关? H # i i q * { /闭了容器的网络功能,类似于会换地址,在以下两种情= 9 G况下是G ` | p x 0有用的:容器并不需要* 9 - (网络(例如只需要写磁盘卷的批处理任务)。
  • overlay:顾名思义:覆盖,但它又不是覆盖,它的作用就是在| 2 T 9 w 1 l J容器原有的网络基础之上,再添加一块网卡,并为其分配一个IP地址,可以将所有的docker容器Y h { z @关联到同一个局域网l I v ! K中,适用于容器与容器是跨主机进行通信的场景。
  • Bridge:相当于VmwaO X A 6 Bre中的NAT模式,容器使用独立的networB 9 ; ck Namespace,并且连接到docker0虚拟网卡(默认模式)。通过docker网桥以及IPtables nat表配置与宿主机通信;Bridge模式是Docker默认的网络设置,此模式会为每一个容器分配一个Network nameSpace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥docker0上

虽然docker模式提供三种网络模式,但其实是有^ ^ + a j四种网络模式的!
注:今天只介绍Y S 2 & F : j $Overlay网络,Macvlan网络,想了解其余三种网络模式请参考:h_ p uttps://blog.51cto.com/14306186/2515603

一、Overlay网络

使用overlay网络需事先% V D K 2 h部署好consul服务!

consul:是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个一个分布r j H r i e U式的,高0 - l r @ O可用的系统,而且开发使用都很简便。它提供了0 J C 9一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、6 L D G o - !多数据中心。

通过一个实验案例来验证consul服务的特` ? ( E / B性!
1.案例环境

系统版本: CenU q b q yto9 3 o 8 f x 3 i 4s 7.3
Docker版本X G 3: 18.09.0
主机名IP地址:
docekr01:192.16.45.129
docekr02:192.16.45.141
docekr03:192.16.45.142

2、准备工作:

* 必须安装key-value存储服务,如consul;
* 宿主机已经安装docker engine;
* 宿主机的hostname必须不同 ,避& J 6免发生冲突 ;
* 关闭防火墙与SELinux(实验环境;

3、案例实施
1)docker01

[root@docker01 ~]#  docker pull progrium/con] { L c Bsul     //下载consul镜像
[root@docker01 ~]#  docker run -d -p 85~ * + ( ? z00:8500 -t l = @h consul --name consul  --restart=always progrium/consul -server9 b ) A B x # 4 } -bootstrap
//-d:后台运行;
//-p:将容器中的8500端口映射到宿主机的8500端口;
//-h:表示consul容器的主机名;
//--n/ Z C e N s j Mame:表示运行a  { .的容器名;
//--b / ! 1 [ 6 9 } krestart=always:随docker服务的启动而启动;
//-server -bootstrap:添加这两个选项,则表示在群集环境中可以使其以master的身份p G h ] n出现;
[root@docker01 ~]# netstar M T J p c & _t -anpt | grep 8500
tcp6       0      0 :::8500                 :::*                    LISTEN      3725/docker-proxy
//确定其8500端口正在监听
[root@docker01 ~]# vim /usr/lib/systemd/system/docker.service     //4 6 ^ ? o s p更改一下docker的主配置文件
ExecStart=/usr/bin/p # 4 v Fdockerd -H unix:///var^ * D/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.45.129:8500 --cluster-advertise=ens33:2376
//在第13行上原本的基础添加以上内容,各个J v A a I t配置项含 8 d 6 a F义如下:
# /var/run/docker.sock:Docker的一8 W 7 ! O f v ( t个套接字;
# “ -H tcp://0.0.0.0:2376 ” :使用本机的tcp2376端口;
# “ -- e d 0 y | d G-cluster-store=consul://192.168.45.129:8500”:指定运行着consulV x A h o服务的docker服务器IP及端口;
# “ --clu| D Cster-adverti8 l 5 N se=ens33:2376”:从本机的ens33网卡通过2376端口搜集网络信息,存储在consul上
[root@docker01 ~]# systemctl  daemon-reload
[root@docker01 ~]# systemctl  reO , , = B ( s h Astart docker.servic     //重新启动docker服务

使用浏览器访问consul服务的web页面

Docker网络管理之docker跨主机通信
Docker网络管理之docker跨主机通信
2)docker02

[root@docki X 3 f X 7 ? Wer02 ~]# vim /usr/lib/! 9 C : m I Usystemd/system/docker.service
ExecStart=/usr/bin/y 4 4 x R ) f @ Xdockerd -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/7 U jdo. t ocker.sock:Docker的一个套接字;
# “ -H tcp://0.0.0.0:2376 ” :使用本机的tcp2376端口;
# “ --cluster-store=consul://192.168.45.129M r q:8500”:指定运行着consul服务的docker服务器IP及端口;
# “ --cluster-advertise=ens33:2376”:从本机的ens33网卡通过2376端口搜集网络信息,存储在consul上
[root@U ; Ddocker02 ~]# systemctl  daemon-reload
[root@docker02 ~]# systemctl  restart docker.service    //重新启动docker服务

访问浏览器刷新浏览器页面
Docker网络管理之docker跨主机通信
3)Docker3

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
//x } & ~ ( p R d在第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-advertiW k Ese=ens33:2376”:从本机的ens33网卡通过2376端口搜集网络信息,存储在consul上
[root@docker03 ~]# systemctl  daemon-reload
[root@docker03 ~]# systemctl  restart docker b B 7 ~.service    //重新启动docker[ o P服务


注:如果在此过程中,s E s访问web页面如果出现“500”的错误页面,将运行co. f / v H a ] } *nsul服务的容器删除重新创新即可!
4)创建一个 overlay网1 = S K
docker01:

[root@docker01 ~]# docker network create -d overlay my_olay
//创建B { M一个名为my_olay的voerlay网络
//以上操作不管在那台f D ; f ` @docker主机上操作都可以
[rw x F y z boot@docker01 ~]#  docker network create -d oveA S L I frlay --subnet 200.9 . ? e g0.p c s H 30.0/24 --gateway 200.0.0.1 lv_olay
//也可以在创建overlay网卡时,指定其IP网段及网关
[root@docker01 ~]# docker network& K H H ls          //查看docker所支持的网络D a m @ ^

Docker网络管理之docker跨主机通信
注:

  • 而且在另外两台docker% Y 9 l服务器上也可看到,自行验证!

  • 在docker 1上创建的网络,可以看到其SPOCE(范围)定义的是global(全局),c j b # 8那么这就意味着加入consul这个服务群集的其他docker服务器也可以看到这张网卡!0 = :

  • 如果在创建网卡时,没有指定其网段,则默认是10.0.0.0网段,由于是自定义网络,所以满足自定义网络的特征(比如支持容器之间的通信)!
    58 & q a 1)在不同的docker服k ? m z ^ k # c d务器各自创建一个容器,验证是否可以通信!
    [root@docker01 ~]# docker run -itd --name t1 --network lv_olay --ip 200.0.0.10 busybot h I Z U ^x:latest
    //在docker1服务器上创建一个名为t1的容器并指定其ID l z 8P地址
    [root@docker02 ~]#  docker run -itd --name t2 --network lv_olay --ip 200.0.0.20 busybox:latest
    //在docker2上创建一个容器并指定If t .P地址
    [root@docker03 ~]# docker run -itd --name t3 --network lv_ola= S p D my --ip 200.0.0.30 busybox:latest
    //在docker3 b D ^上创建一个容器并指定IP地址
    [root@docker01 ~]# docker exec -& N R | + A G 9 0it t1 /biA P x Ln/sR o z X ? Ih
    //随便在一台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 tid 8 _ z dme=1.053 ms
    64| t n bytS a # X v nes 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= } ~ R地址,不同docker host上容器通信是没有问题的;