Docker容器之bridge网络

docker ginotang 2777℃ 0评论

容器网络简介

容器之所以强大,是因为它的隔离性和连通性。隔离性是指每个容器是一个互相封闭的运行空间;而连通性指的是:当容器之间需要互相联系,可以通过Docker提供的网络模块进行通讯。Docker默认提供了3种内置网络模型和3种用户自定义网络模型。

三种内置网络模型分别是:

  • bridge: docker默认的网络驱动。当没有指定,所有的容器都挂在默认的bridge设备上。
  • host: 容器直接使用宿主机的网络环境,包括域名也是宿主机的
  • none: docker不适用任何网络,这种容器只有lo(本地回环)设备

可以使用docker network ls命令查看

三种自定义网络模型分别是:

  • bridge: 类似默认的桥接网络,但功能更加强大
  • overlay: 使不同主机上的容器可以互相通讯
  • macvlan: 为容器添加一个mac地址,使它看起来像是本地上的一个物理设备

默认bridge网络和自定义bridge网络的区别

  • 自定义bridge提供了更好的隔离性和更强大的协同性

    处于同一自定义bridge网络的所有容器,容器间的所有端口互相开放,可自由访问,但对外界来说,这些端口是不可见的。这使得容器间的通讯更加简单,也更加安全。

    对于默认的bridge来说,被访问的特定端口必须通过-p(–publish)参数向外暴漏,否则容器不能访问这些端口。从安全性考虑,我们必须手动block掉其他不需要访问这些端口的容器,例如通过iptables。

  • 自定义bridge提供了DNS解析功能

    一般来说,我们访问其他容器的时候都是使用IP地址的,但自定义bridge网络提供了DNS解析功能,也就是说,我们可以使用域名进行容器间的通讯。容器域名由docker run命令的--name参数指定。

    默认的bridge网络只能使用IP地址通讯,要使用域名,必须先通过旧式的--link(已废弃,未来可能移除)参数进行容器间的链接

  • 容器可以在运行时动态地断开或连接到用户自定义bridge网络

    要把容器从默认的bridge网络中断开,必须先让容器停止运行

使用bridge网络

上面已经介绍了两种bridge网络的区别,现在我们来实际操作它们。

默认bridge网络

一旦主机安装好docker,docker就会创建一个名为docker0的bridge设备,如果没有指定,默认所有容器都会挂在这个设备下面。可以通过brctl检查主机上的所有bridge设备,brctl命令在centos中由bridge-utils软件包提供,如果没有要先安装。

使用ifconfig观察docker0的信息

现在创建一个容器

再执行一次brctl命令

这次interfaces下面多了一个vethe800a9d设备,这个设备正是属于前面创建的busybox1容器的。

我们再进入容器里面环境观察它的网络结构:

在busybox1容器中我们执行了两条查询

  • 第一条查询获取容器的IP地址信息,地址段是172.17.0.0
  • 第二条查询获取容器的默认网关,是172.17.0.1,这个是docker0设备的IP地址,说明它隶属于docker0网络

查看对应网络中的所有容器

我们可以查看指定网络中都有什么容器,通过docker network inspect命令即可

其中Containers片段就列出了所有挂在这个网络中的容器。也可以通过--format参数提取特定字段的内容

创建第二个容器,检查它们是否相通

现在brctl命令应该显示docker0下有两个设备

进入busybox2对busybox1执行ping命令

很明显它们的网络是互通的,再使用域名ping busybox1

由于默认的bridge不支持DNS解析,因此ping不通。

最后,默认的bridge网络结构如下图:

docker bridge network

docker bridge network

用户自定义bridge网络

通过docker network create命令创建自定义bridge网络,下面的命令创建了一个名为my_bri的网络

--driver选项用于指定网络的驱动类型,可选值有bridge、macvlan和overlay。

使用brctl命令查看

br-351e7a677db5设备正是我们创建的自定义网络设备

创建两个容器,把它们都挂在my_bri网络上,只需要使用--network选项指定要加入的网络即可

再次执行brctl命令和ifconfig命令

一切准备就绪,进入busybox3容器

这次我们直接使用容器的名称进行ping测试

结果是通的,证明自定义bridge确实提供了DNS解析服务。

容器间的互相通讯

不同网络间的容器默认是不能互相通讯的,即docker0和my_bri上的容器是隔离的。现在我们的容器关系如下:

docker bridge network 2

docker bridge network 2

能不能让两个不同网络的容器通讯,例如busybox2和busybox3?答案是肯定的,只需要把busybox2连接到自定义的my_bri网络上,具体如下:

使用docker network connect命令

现在busybox2已经加入到my_bri网络中,既然在同一个网络中,它们自然可以通讯了。进入busybox2看一下改变了什么

其实就是添加了一块网卡eth1,这是理所当然的。使用brctl命令检查

多了一块设备和它关联,接着ping一下busybox3和busybox4

现在busybox2和busybox3、busybox4都可以连接了,而且是通过DNS通讯的。

网络结构如下:

docker bridge network 3

docker bridge network 3

容器和外界相互通讯

这里的外界指的是Docker Host之外的网络。分别有容器访问外界和外界访问容器两个方向。

容器访问外网

现在我们尝试一下进入busybox1 ping百度

从现象来看,似乎bridge网络默认就可以和外界通讯,但事实并非如下,运行如下命令

然后删除busybox1容器重新执行docker run命令创建一个

明显有一个WARNING,警告信息是:IPV4转发已被禁用,网络不可用。这时你再ping外网,发现已经不通了。

因此,我们可以这样认为:Docker Host实际上是一个路由器,docker容器要访问外网的主机,就要经过Docker Host的转发,即经过宿主机的NAT转换。

注意:net.ipv4.conf.all.forwarding参数开启与否对同一主机上的容器互相通讯没有影响

外网访问容器

我们假设宿主机已经拥有公网IP地址,否则宿主机所在的路由器必须做端口映射。

外网主机访问Docker Host容器提供的服务,只需通过-p选项把容器的端口暴露出来即可,例如nginx服务

-p(–publish)选项的作用是把宿主机的80端口映射到容器的80端口

网络管理

docker默认的网络设置并不一定适合每个人,例如掩码,网关等,幸运的是,我们可以自由修改这些信息

--subnet用于设置子网信息,--gateway用于设置网关信息

使用ifconfig命令查看

断开容器和网络间的连接

使用docker network disconnect命令断开网络连接

删除指定网络

使用docker network rm命令删除网络

转载请注明:Pure nonsense » Docker容器之bridge网络

喜欢 (1)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x