docker network
Posted 穷少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker network相关的知识,希望对你有一定的参考价值。
文章目录
docker network是什么
容器网络实质上也是由Docker为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。
Docker网络中有三个核心概念:沙盒(Sandbox)、网络(Network)、端点(Endpoint)。
- 沙盒,提供了容器的虚拟网络栈,也即端口套接字、IP路由表、防火墙等内容。隔离容器网络与宿主机网络,形成了完全独立的容器网络环境。
- 网络,可以理解为Docker内部的虚拟子网,网络内的参与者相互可见并能够进行通讯。Docker的虚拟网络和宿主机网络是存在隔离关系的,其目的主要是形成容器间的安全通讯环境。
- 端点,位于容器或网络隔离墙之上的洞,主要目的是形成一个可以控制的突破封闭的网络环境的出入口。当容器的端点与网络的端点形成配对后,就如同在这两者之间搭建了桥梁,便能够进行数据传输了。
这三者形成Docker网络核心模型,也就是容器网络模型(Container Network Model)。
docker的网络实现
容器网络模型为容器引擎提供了一套标准的网络对接范式,Docker中,实现这套范式的是Docker所封装的libnetwork模块。
Docker官方提供了五种Docker网络驱动,分别是:Bridge Driver、Host Driver、Overlay Driver、MacLan Driver、None Driver。Bridge和 Overlay在开发中使用频率较高。
网络模式 | 简介 |
---|---|
host(主机模式) | 相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址 |
bridge(桥梁模式) | 相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。 |
overlay(覆盖模式) | Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。 |
container(容器模式) | 在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。 |
none(无网络模式) | 该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。实际上,该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络(例如只需要写磁盘卷的批处理任务)。 |
1. 默认网络(docker0)
当你安装Docker时,它会自动创建三个网络。你可以使用以下docker network ls命令列出这些网络:
Docker内置这三个网络,运行容器时,你可以使用该–network标志来指定容器应连接到哪些网络。
该bridge网络代表docker0所有Docker安装中存在的网络。除非你使用该docker run --network=
选项指定,否则Docker守护程序默认将容器连接到此网络。
2. 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和端口。
3. bridge网络模式(重点)
相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。下面着重介绍一下此模式。
Docker 默认的 bridge 网络是不支持通过 Docker DNS 服务进行域名解析的,自定义桥接网络是可以的。
Bridge模式的拓扑
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.0.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.0.186/24。
Docker完成以上网络配置的过程大致是这样的:
(1)在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(2)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中
(3)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
docker overlay模式
Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。
因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
要想使用Docker原生Overlay网络,需要满足下列任意条件
- Docker 运行在Swarm
- 使用键值存储的Docker主机集群
docker network指令
通过
docker network
指令,可以方便的管理docker服务器上的网络
docker network inspect # 根据网络的ID展示网络的详细信息
docker network ls # 展示所有的网络,以列表形式
docker network create # 创建一个自定义网络
docker network connect # 连接一个容器到指定网络上
docker network disconnect # 让一个容器从指定网络上断开
docker network prune # 删除所有未使用的网络
docker network rm # 根据网络的ID,删除一个或多个网络
自定义网络
- 自动DNS解析容器名称到IP地址,例如我们连接mysql服务器时,可以通过
容器名:端口
的形式,拼接url - 方便管理,在同一网络下的主机可以相互连通
自定义网络(案例)
-
创建一个自定义网络,
subnet
参数指定网络的范围以及网络前缀,--bridge
指定网络的类型,--gateway
指定当前网络的网关地址
-
查看网络详情
-
启动一个tomcat服务器,通过
--network
在启动时连接至自定义网络-
我们启动完成后,发现tomcat已经连接至自定义网络
-
启动一个centos系统 ,连接至自定义网络,以交互的方式启动,
ping
一下tomcat看能否ping
通
我们发现,在同一网络下,两个容器之间可以相互访问
docker自定义网络搭建redis集群
-
创建一个redis-net(自定义网络)
-
按照下面的配置启动6个redis容器
按照下面的命令依次运行
启动成功
查看redis-net网络详情,可以看出所有的redis容器都已经连接至一个网络
-
进入任意redis容器内,使用redis-cli搭建集群,如下所示,可见集群已经搭建成功,注意:最好使用每个容器的IP进行搭建,如果使用容器名,会出现映射不成功的错误
–link(容器互联)
在容器运行启动的时候,通过
--link
参数可以指定容器之间相互绑定,以达到容器之间的项目访问
其实原理就是在/etc/hosts里面添加了一个alias的名称。
测试
1.启动两个容器,进行测试
# 启动第一个容器
docker run -d --name tomcat1 tomcat
# 启动第二个容器
docker run -d --name tomcat2 tomcat
2.任意进入一个tomcat容器内部,去ping另一个tomcat容器,发现ping不通
3.我们再启动一个tomcat03,使用–link参数链接到tomcat01,tomcat02
4.我们进入tomcat03容器内部,去ping
tomcat01或tomcat02,发现tomcat03可以直接通过容器名访问其它两个容器
5.查看tomcat03的/etc/hosts
文件,发现,其实是做了一个域名映射
结论:
-
两个容器间互相通信使用–link,可以实现互通。
-
docker0 不支持容器名连接访问。
建议:
docker官方已不推荐使用docker run --link来链接2个容器互相通信,随后的版本中会删除–link,但了解其原理,对如何使2个容器之间互相通信还是有帮助。
参考文章
以上是关于docker network的主要内容,如果未能解决你的问题,请参考以下文章
[云原生专题-13]:容器 - 通过docker network 构建docker微服务网络:Docker network
Docker删除报错:Error response from daemon: conflict: unable to delete 08b152afcfae (must be forced)(代码片段