当前位置: 首页 > article >正文

Docker:网络

Docker:网络

    • Docker 网络架构
      • CNM
      • Libnetwork
      • 驱动
      • 网络类型
    • 命令
      • docker network ls
      • docker network inspect
      • docker network create
      • docker network connect
      • docker network disconnect
      • docker network prune
      • docker network rm
    • 网络操作
      • bridge
      • host
      • container
      • none


Docker 网络架构

Docker容器实现环境隔离,为内部进程提供一个独立的环境,这里面就包含网络环境的隔离。从容器内部来看,就好像自己独占一个主机,拥有一套完整的网络配置,包括IP协议栈、端口、套接字、防火墙等等。

为了实现这样的容器网络,采用的架构由三部分组成:CNMLibnetwork驱动

CNM

CNMDocker采用的网络设计规范,其又分为三个组成要素:SandBoxEndpointNetwork

  • SandBox:提供独立的网络协议栈,用于隔离容器网络与宿主机网络,形成了完全独立的容器网络环境
  • NetworkDocker内部的虚拟子网,使网络内的逻辑主机可以通信
  • Endpoint:虚拟网络的接口,通过该接口容器可以接入Network

在这里插入图片描述

上图中包含三个容器,每个容器都有自己的SandBox实现自己的独立网络协议栈。这些容器通过endpoint连接到network,再通过network连接到宿主机的网络,最后通过宿主机接入互连网。


Libnetwork

LibnetworkCNM的一个实现,其完成了CNM定义的三个核心功能,并拓展了容器负载均衡,网络控制以及管理。


驱动

容器具有独立完整的网络协议栈,协议栈的上三层应用层运输层网络层都没有变化。因为容器使用TCP/IP协议,宿主机也是用TCP/IP协议,这些协议在上三层实现,所以上三层没有修改的必要,直接复用宿主机的实现。

这里不是说容器和宿主机使用同样的网络栈,只是它们的网络栈上三层使用相同实现方案。

协议栈的最底层是数据链路层,数据链路层通过主机的驱动程序实现。为了实现网络的隔离性,那么就需要让不同容器之间,容器与宿主机之间的网络隔离。这就依赖于数据链路层的驱动程序,比如说Endpoint就是在数据链路层的驱动中实现的。

除去实现基本的隔离性,Docker还提供了多种类型的网络,并分别实现相应的驱动程序。比如桥接网络驱动Dridge Driver、宿主机网络驱动Host Driver等等。


网络类型

刚才提到,Docker实现了多个驱动程序,来支持不同类型的网络,在操作容器时,就可以选择不同的网络类型:

  1. Bridge网络:桥接网络,驱动在主机上创建一个网桥,多个容器可以接入网桥,相互通信,也可以通过网桥与互连网通信
  2. Host网络:宿主机网络,相当于移除了宿主机与容器之间的网络隔离,让容器可以直接使用宿主机的网络,此时容器直接使用宿主机的网络
  3. Container网络:容器网络,让一个容器共享另一个容器的网络,此时两个容器共享ip,端口号等等,也就是共享网络
  4. none网络:容器的网络依然隔离,但是不再拥有自己的网络,此时无法进行网络通信

接下来先讲解Docker的网络命令,再深入讲解以上四种网络的操作。


命令

docker network ls

  • 功能:查看docker的所有网络

语法:

docker network ls [option]

示例:

在这里插入图片描述

在这台主机上的Docker,共有四个网络,其中brideghostnone这三个网络,是Docker自带的网络,它们的网络名称和驱动名称相同。

后面的DRIVER是该网络使用的驱动程序,也就是先前提到的几种驱动程序之一。

第四个网络是用户自建的网络,使用的驱动是bridge


docker network inspect

  • 功能:输出网络的详细信息

语法:

docker network inspect [option]

查看默认的bridge网络:

在这里插入图片描述

此处可以看到其使用的驱动程序,是否使用IPv6。再比如Subnet表示可分配的子网,所有连接到这个网络的容器,可以分配到这些子网。Gateway表示网关,即这个网络通过172.17.0.1连接到宿主机。

使用ifconfig查看宿主机网络:

在这里插入图片描述

可以看到一个docker0网络,这是Docker安装时,自动配置的网络,也是所有容器的默认网络。其地址为172.17.0.1,也就是bridge网络使用的网关。

所有的Docker容器启动时,如果没有指定网络,默认使用bridge网络,bridge使用docker0,因此docker0是所有容器的默认网络。


docker network create

  • 功能:创建一个网络

语法:

docker network create [option] network_name

选项:

  • --driver, -d:指定网络驱动,默认是 bridge
  • --subnet:指定网络的子网
  • --gateway:指定网络的默认网关
  • --ip-range:指定分配给容器的连续 IP 地址范围
  • --enable-ipv6:启用 IPv6 网络

此处注意区别--subnet--ip-range,前者指定的是子网,这个会影响网络的广播,IP地址的范围等。而 --ip-range只限制地址范围,容器分配到的IP地址不会超过这个范围。

例如,指定子网为 172.17.0.0/16 并设置 IP 范围为 172.17.1.0/24,这意味着 Docker 将只从 172.17.1.0172.17.1.255 这个范围内为容器分配 IP 地址,但是容器的广播域是172.17.0.0/16

创建一个桥接网络test1

在这里插入图片描述

以上命令创建了一个test1桥接网络,并且分配了子网192.168.0.1

通过ifconfig查看主机网络:

在这里插入图片描述

此时多出一个br-8c5013a75f1d0网络,前面的brbridge简写,表示桥接网络,后面是一段随机生成的字符。这个网络的地址为192.168.0.1,就是先前指定的子网。


docker network connect

  • 功能:将容器连接到网络

语法:

docker network connect [option] network container

选项:

  • --ip:指定IP地址
  • --ip6:指定IPv6地址

示例:

在这里插入图片描述

以上命令,创建了一个busybox容器,并且执行以下命令分配网络:

docker network connect --ip 192.168.66.66 test1 bx1

分配的IP地址是192.168.66.66,来自网络test1,这是先前创建的一个桥接网络。

进入容器后,执行ifconfig,可以看到三个网络。

  1. eth0:由于在docker run的时候,没有指定网络,默认使用bridge网络,也就是eth0,为其分配的地址为172.17.0.2
  2. eth1:这是通过以上指令添加的网络,通过子网掩码可以看出所属子网为192.168.0.0/16,也就是test1可分配的子网,而分配的地址是192.168.66.66
  3. lo:一个本地环回地址

docker network disconnect

  • 功能:断开容器与网络的连接

语法:

docker newwork disconnect

docker network prune

  • 功能:删除所有不使用的网络

语法:

docker newwork prune

示例:

在这里插入图片描述

此处删除了两个用户自定的网络,因为这两个网络没有任何一个容器正在使用。


docker network rm

  • 功能:删除指定网络

语法:

docker newwork rm

网络操作

bridge

bridge是默认的网络配置,如果创建容器时,不配置网络属性,那么就会使用bridge网络。

创建一个容器,不配置任何网络:

在这里插入图片描述

查看网络信息,可以看到两个两个网络接口,分别是lo本地环回,以及eth0接口用于对外通信。

eth0的地址为172.17.0.2,子网掩码为255.255.0.0,可见其属于子网172.17.0.0/16

这个地址,其实属于宿主机的docker0

在这里插入图片描述

可以看到,docker0接口的地址为172.17.0.1,当一个容器创建时,不指定网络,就会通过docker0搭建网桥,与宿主机通信,最后通过宿主机的eth0与互连网通信。

在这里插入图片描述

从容器内部看,好像自己使用eth0就可以直接与互连网直接通信,自己独占一个主机的网络接口。

但是其实eth0本质是连接了docker0这个网桥,而宿主机的eth0也连接了docker0这个网桥。因此容器内部的eth0与宿主机的eth0可以通过网桥通信,进而让容器可以与外界网络通信。

在此处,docker0就类似于物理上的路由器或者说交换机,所有连接到这个网桥的接口都可以相互通信,实现的是宿主机与容器之间的通信。

同一个网桥上的任意两个接口都可以相互通信,那么同一网桥内的两个容器之间也能可以通信,并且还会自带DNS的解析服务

创建一个桥接网络test_net

在这里插入图片描述

在两个终端运行两个busybox容器bx3bx4,都连接到test_net网络:

在这里插入图片描述

docker run时加上参数--network,可以直接指定网络,无需通过docker network connect

bx3容器分配到的IP地址为172.18.0.2

在这里插入图片描述

bx4容器分配到的IP地址为172.18.0.3

bx3ping 172.18.0.3

在这里插入图片描述

成功了,说明bx3bx4可以通过网桥test_net进行通信。

不仅如此,还可以直接ping 容器名

在这里插入图片描述

bx3ping bx4也成功了,这是因为处于同一网桥下的容器,网桥会对域名进行DNS解析,容器名就是域名,bx4直接被解析为了172.18.0.3

不过这个DNS解析只有用户自己创建的桥接网络才有,docker0不带有这个功能。


host

host是一种非常简单粗暴的容器网络模式,这种模式下,容器不会进行网络隔离,直接使用宿主机的网络配置。

在这里插入图片描述

上图中,container A使用host网络,其箭头直接指向整个宿主机网络,宿主机有什么接口,container A就有什么接口

创建一个busybox容器,使用host网络:

在这里插入图片描述

其包含的网络接口与宿主机完全一致,比如docker0etho以及一个br-xxxx网络,这个是先前创建的test_net网络的接口。

虽然这种方式很简单粗暴,但是相比于bridge,不需要通过网桥进行数据转发,网络效率会更高。缺点是与宿主机共用网络,可能会有端口冲突等问题。


container

container网络模式下,一个容器会直接使用另一个容器的网络,两个容器共享网络栈。

在这里插入图片描述

上图中,container A使用的就是container模式的网络,其与container B共用一份网络。

创建容器bx6,使用test_net桥接网络:

在这里插入图片描述

其分配到的地址为172.18.0.2

再创建一个容器bx7,使用container网络,与bx6共享网络:

docker run是添加以下参数,则为container网络:

--network container:被共享网络的容器

在这里插入图片描述

--network container:bx6表示bx7共享了bx6的网络,其eth0接口的地址也为172.18.0.2

对于被共享网络的容器,不一定就是桥接网络,也有可能是host等其它网络。不论是什么网络,都支持被container网络进行容器之间的共享。

container网络的实现原理很简单,容器网络通过net namespace进行隔离,每个容器都会创建自己的net namespace。当一个容器使用container网络时,不会创建自己的net namespace,而是直接进入到别的容器的net namespace中,那么这两个容器的网络就不会被隔离,于是新容器就可以使用别的容器的网络了。


none

none就是没有网络,可以在docker run时通过--network=none来指定。

在这里插入图片描述

在这种模式下,只有一个lo本地环回接口,无法与外部进行网络连接。

对于一些不需要互连网的应用,或者安全要求高的内容,可以使用none网络进行。

最后,再总结一下以上四种网络:

  • bridge:容器通过net namespace隔离网络环境,再使用一个接口连接到网桥与外部通信
  • host:容器不创建自己的net namespace,直接与宿主机共享网络
  • container:容器不创建自己的net namespace,直接使用其他容器的net namespace
  • none:容器通过net namespace隔离网络环境,但是不开放接口,形成一个完全独立,无法联网的网络环境


http://www.kler.cn/a/378185.html

相关文章:

  • GUI07-学工具栏,懂MVC
  • 【NLP 16、实践 ③ 找出特定字符在字符串中的位置】
  • postman读取文件执行
  • 机器学习基础算法 (二)-逻辑回归
  • 内核执行时动态的vmlinux的反汇编解析方法及static_branch_likely机制
  • JavaWeb期末复习(习题)
  • synchronized加锁原理以及锁升级过程
  • 微服务架构深入理解 | 技术栈
  • vue3项目history模式部署404处理,使用 historyApiFallback 中间件支持单页面应用路由
  • 最新指南,如何使用 ChatGPT 提示词指令进行学术写作
  • 人工智能原理实验一:知识的表示与推理实验
  • Windows Server2012 R2搭建NFS服务器
  • 认识类与对象(下)
  • 算法——递推
  • 组织架构图
  • Linux: network: hw csum failure
  • 【ceral】c++轻量的序列化库
  • 2024 年( 第五届)“ 大湾区杯” 粤港澳金融数学建模竞赛A 题
  • 背包问题的详细理解(无基础->详细掌握)
  • Ubuntu 24 配置vsftp
  • SpringBoot抗疫物资管理与数据分析系统
  • vulhub之Spring篇
  • AIGC与虚拟现实(VR)的结合与应用前景
  • 人工智能中FOPL语言是什么?
  • php实现sl651水文规约解析
  • 自定义view实现历史记录流式布局