docker基础篇(一)补

  通过一个星期的加班到9点,终于将docker的网络部分小小的总结了一下,小编在这以前也发布过关于docker的内容,原本想就此结束,可是总感受少了些什么,只会docker的命令,仿佛不能深刻的理解docker强大之处,因此小编决定在补充一下关于docker的网络部分,包括docker的网络模式、容器通讯、以及相应的实战操做。虽然这部分有些难以理解,可是细细研读以后,必定会有所收获。git

1.docker的网络模式

  安装Docker时,它会自动建立三个网络,bridge(建立容器默认链接到此网络,也就是在不使用--network参数时)、 none 、host。还有之后一种自定义模式,自定义模式有三种:bridge、overlay、macvlan。
咱们可使用一下命令,查看本机容器间通讯的几种方式:github

docker network ls

docker基础篇(一)补
  咱们能够在docker run的时候使用--net= none/ host/ bridge来设置容器具体使用哪一种模式。web

(1)默认网络通讯模式bridge网桥

  默认状况下docker运行容器时,宿主机会建立一个bridge网桥,是一个名叫docker 0的虚拟网桥 ,默认docker 0 IP为172.17.0.1,网桥再给容器分配虚拟子网IP,而且以网桥IP做为网关。在不指定网络的状况下,容器之间的通讯都是经过bridge网桥进行通讯。而后网桥在与宿主机镜像进行IP转换,端口映射等通讯。
  这种bridge网桥与容器,与宿主机之间的通讯,有点相似与三层路由交换:
    docker基础篇(一)补docker

(2) host宿主机模式

  若是容器指定网络模式为host,容器不会有本身的network namespace,而是和宿主机共用一个network网络及IP,容器不会有虚拟出本身的网卡、IP等,固然除了网络通讯这一块和宿主机绑定了,其他的容器内容仍是和宿主机安全隔离了。这种在作容器迁移时,很不方便,不推荐使用。
docker基础篇(一)补apache

(3) none模式

  容器指定网络模式-net为none时,docker容器再也不拥有本身的network namespace,可是全部网络配置都得自行配置,如IP、网卡等,这种方式很麻烦。(关闭了容器的网络功能)
docker基础篇(一)补
这里补充两个docker服务运行时参数
-b BRIDGE or--bridge=BRIDGE ——指定容器挂载的网桥;
--fixed-cidr=10.200.55.64/26 #定制容器的IP地址范围编程

2.单机间的容器通讯

  单机间的通讯,就是同一宿主机中的不一样容器之间的通讯,容器之间可经过 IP,Docker DNS Server 和joined 容器三种方式通讯。ubuntu

(1)IP通讯

  两个容器要能通讯,必需要有属于同一个网络的网卡。知足这个条件后,容器就能够经过 IP 交互了。这也是默认的方式,咱们在使用--net= bridge,docker虚拟出来的一个docker0网桥,会给每个容器在docker0网桥的网段中分配一个IP,这样同主机中的容器的IP是同一网段的天然能够经过IP相互访问。
演示:vim

[root@zzy ~]# ifconfig

docker基础篇(一)补
这里看到个人这台机器中的docker0的网桥的地址为172.17.0.1,这台机器中启动的全部的docker的容器的IP都是这个网段的。安全

[root@zy ~]# docker ps  #查看正在运行的docker容器

docker基础篇(一)补
我这里有两个一个是registry一个是MySQL。bash

[root@zy ~]# docker inspect 28b2c91d4be4|grep -i ipaddress #查看容器的IP

docker基础篇(一)补

[root@zy ~]# docker inspect 5708c1dcbdd7|grep -i ipaddress #查看容器的IP

docker基础篇(一)补
能够发现这两个容器的IP地址果真都是172.17.0.1网段的。

(2)docker DNS server

  经过 IP 访问容器虽然知足了通讯的需求,但仍是不够灵活。由于咱们在部署服务以前可能不能肯定IP。好比:如今部署一个Nginx web服务,可是每次容器启动分配的IP地址都会改变,咱们没法经过固定的IIP地址去访问web服务,这样每次访问时都要查看IP,很是麻烦,对于这个问题,能够经过 docker 自带的 DNS 服务解决。
  从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器能够直接经过"容器名"通讯。方法很简单,只要在启动时用 --name 为容器命名就能够了。
演示:

#下面在同主机启动两个Ubuntu系统并指定--name:
[root@zy ~]#docker run -it --network=brideg2 --name box1 ubuntu:net /bin/bash
[root@zy ~]#docker run -it --name --network= brideg2 box2 ubuntu:net /bin/bash

docker基础篇(一)补
咱们发现使用--name,的容器名称能够ping通其余容器。
注意:使用 docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是没法使用 DNS 的。

(3) joined 容器

  joined 容器是另外一种实现容器间通讯的方式。它可使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间能够经过 127.0.0.1 直接通讯。
演示:

#启动一个http服务
[root@zy ~]# docker run -dit --name my-apache-app  -p 8099:80 -v "/http":/usr/local/apache2/htdocs/ httpd
#建立一个Ubuntu容器容器并经过 --network=container: my-apache-app指定 jointed 容器为 my-apache-app
[root@zy ~]# docker run -it --network=container:my-apache-app ubuntu:net /bin/bash
#使用命令去访问my-apache-app容器中的web页面
root@ec745e2fbf4a:/# curl 127.0.0.1

docker基础篇(一)补
此时咱们发现访问成功!缘由是:咱们分别查看着两个容器的IP:
Ubuntu:
docker基础篇(一)补
http:
docker基础篇(一)补
咱们发现两个容器的网卡 mac 地址与 IP 彻底同样,它们共享了相同的网络栈。因此Ubuntu容器可使用127.0.0.1直接访问http容器的web服务。

(4) 补充

docker run 命令的参数介绍:

-h 运行容器时指定主机名,这样咱们可使用主机名去与容器通讯。
    --link=容器名 别名  ,这样使用--link链接的容器间就可使用主机名进行通讯。
    -p host_port:container_port 端口映射,容器的服务端口映射到宿主机。
    -P  container_port    端口映射,映射到宿主机的任意空闲端口。

容器的访问控制
容器访问外部网络:两种方法:
  - sysctl -w net.ipv4.ip_forward=1 (设置宿主机的开启数据转发)
  - 启动Docker服务的时候设定--ip-forward=true,docker会自动打开宿主机系统的转发服务
外部访问容器:这里很简单,经过docker run -h hostname -p 端口映射,来实现外部访问容器。

3.跨主机间的容器通讯

(1)Docker网桥实现跨主机容器链接

  在同一宿主机下docker容器之间是能够相同连通的。这是由于默认的docker容器在同一宿主机下,全部容器分配的IP处于同一个地址段的,相互之间能够ping通;当咱们使用ifconfig命令查看IP时会发现,其中有一个docker0的网桥,docker容器经过docker0 网桥实现同一主机间中,容器的IP地址分配和访问,这就保证了全部的容器在同一地址段。
  虽然这些IP地址在同一宿主机中是处于同一网段而且相互之间能够通讯,可是若是在不一样宿主机之间,若是网桥的网段不一样,容器之间仍是不可能实现跨住进的通讯,那么咱们能够将每一个主机下的容器的网段都处于同一网段,这样,就能够实现跨主机的访问啦,这也是Docker容器默认跨主机之间的链接方法的第一种:网桥实现。
docker基础篇(一)补
  上图就是网桥方式实现跨主机的链接,可是缺点也很明显,宿主机和容器的IP处于同一网段,若是在局域网下,IP地址是有限的,那么一个容器占据一个IP地址,IP地址很快就会被用光,这就是个不友好的现象,因此这种方式仅仅只用来学习测试使用。
实战操做:
实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下载网桥管理工具

yum install -y bridge-utils

② 分别在docker主机上创建网桥

Host1: $ sudo brctl addbr br0
Host2: $ sudo brctl addbr br0

③ 为网桥分配一个同网段IP

Host1: $ sudo ifconfig br0 192.168.130.10 netmask 255.255.255.0
Host2: $ sudo ifconfig br0 192.168.130.20 netmask 255.255.255.0

④ 桥接本地网卡

Host1: $ brctl addif br0 eth0
Host2: $ brctl addif br0 eth0

⑤ 修改docker配置文件

$ Host1 vim /etc/default/docker
$ Host2 vim /etc/default/docker

改为:Host1: DOCKER_OPTS=” -b=br0 –fixed-cidr=‘192.168.130.64/26“
Host2: DOCKER_OPTS=” -b=br1 –fixed-cidr=‘192.168.130.128/26“
这里的:
-b :用来指定容器链接的网桥的名字。
--fixed-cidr :用来限定容器分配的IP地址的范围。
⑥重启docker

$ Host1 systemctl daemon-reload
$ Host1 systemctl restart docker 
$ Host2 systemctl daemon-reload
$ Host2 systemctl restart docker

⑦ 测试
这里在host1和host2中各启动一个容器,而后相互ping对方容器IP,若是能够ping桶表示配置成功。

(2)Open vSwitch 实现跨主机容器通讯

  Open vSwitch是一个高质量、多层虚拟交换机。使用Apache2.0许可协议,旨在经过编程扩展,使庞大的网络自动化(配置、管理、维护),同时还支持标准的管理接口和协议。
docker基础篇(一)补
实战操做:

实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

虚拟机网段:

主机名 网段
Host1 192.168.1.1
Host2 192.168.2.1

操做步骤:

  • 在虚拟机中创建ovs网桥
  • 添加gre链接
  • 配置docker容器虚拟网桥接
  • 为虚拟网桥添加ovs接口
  • 添加不一样Docker容器网段路由
    ① 安装Open vSwitch并启动

    [root@ Host1~]#yum install -y openvswitch.x86_64
    [root@ Host1~]#systemctl start openvswitch

② 安装网桥

[root@ Host1~]# yum install -y bridge-utils

③ 创建ovs网桥并添加GRE接口

[root@ Host1~]# ovs-vsctl add-br obr0
[root@ Host1~]# ovs-vsctl add-port obr0 gre0

④ 设置远程的网桥链接

[root@ Host1~]#ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.130.131
#查看osv网桥配置
[root@ Host1~]#ovs-vsctl show

⑤ 设置docker的虚拟网桥

[root@ Host1~]#brctl addbr br0
[root@ Host1~]#ifconfig br0 192.168.1.1 netmask 255.255.255.0
[root@ Host1~]#brctl addif br0 obr0
[root@ Host1~]#brctl show

⑥ 设置路由规则

[root@ Host1~]#ip route add 192.168.2.0/24 via 192.168.130.131 dev ens33

同理host2也须要按照上述方式配置。最后两个容器之间就能够通讯。

(3)Weave实现跨主机容器通讯

   Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它可以建立一个虚拟网络,用于链接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序没必要去配置端口映射和连接等信息。
  外部设备可以访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也可以暴露到应用程序容器上。Weave可以穿透防火墙并运行在部分链接的网络上,另外,Weave的通讯支持加密,因此用户能够从一个不受信任的网络链接到主机。
原理:

docker基础篇(一)补
  Weave会在主机上建立一个网桥,每个容器经过 veth pair 链接到该网桥上,同时网桥上有个 Weave router 的容器与之链接,该router会经过链接在网桥上的接口来抓取网络包(该接口工做在Promiscuous模式)。
  在每个部署Docker的主机(多是物理机也多是虚拟机)上都部署有一个W(即Weave router),它自己也能够一个容器的形式部署。Weave run的时候就能够给每一个veth的容器端分配一个ip和相应的掩码。veth的网桥这端就是Weave router容器,并在Weave launch的时候分配好ip和掩码。
  Weave网络是由这些weave routers组成的对等端点(peer)构成,每一个对等的一端都有本身的名字,其中包括一个可读性好的名字用于表示状态和日志的输出,一个惟一标识符用于运行中相互区别,即便重启Docker主机名字也保持不变,这些名字默认是mac地址。
  每一个部署了Weave router的主机都须要将TCP和UDP的6783端口的防火墙设置打开,保证Weave router之间控制面流量和数据面流量的经过。控制面由weave routers之间创建的TCP链接构成,经过它进行握手和拓扑关系信息的交换通讯。 这个通讯能够被配置为加密通讯。而数据面由Weave routers之间创建的UDP链接构成,这些链接大部分都会加密。这些链接都是全双工的,而且能够穿越防火墙。
实战操做:
实验环境:

主机名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下载复制weave二进制执行文件

[root@ Host1~]#git clone https://github.com/weaveworks/weave
[root@ Host1~]#cp -p /root/weave/weave  /usr/bin/
[root@ Host1~]#cd /usr/bin/
#查看weave版本
[root@ Host1~]#weave version

docker基础篇(一)补
② 启动weave服务

[root@ Host1~]# weave launch --no-detect-tls  #注意第一次启动会在docker中拉取相应的镜像

③ 运行一个容器

[root@ Host1~]#docker run -it ubuntu:net /bin/bash

而后Ctrl+p+q退出容器,而且让容器后台运行
④ 进入容器

[root@ Host1~]#weave attach 192.168.2.1/24 c45932ef7da4

注意:这里的192.168.2.1/24 是默认的给当前容器分配的一个weaveIP
docker基础篇(一)补
以后再host2宿主机中也执行以上的命令,而且在“weave attach 192.168.2.1/24 容器ID” 这里分配一相同网段的不一样IP。
docker基础篇(一)补
此时经过这个ethwe中的IP,去相同ping对方容器,这里就能够相同访问:
docker基础篇(一)补

相关文章
相关标签/搜索