Docker 容器化技术:构建高效、可移植的开发环境和部署流程|Docker 网络

为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络命名空间。这些独立的协议栈被隔离到不同的命名空间中,处于不同命名空间中的网络协议栈是完全隔离的,彼此无法通信。通过对网络资源的隔离,就能在一台宿主机上虚拟多个不同的网络环境,Docker 正是利用了网络的命名空间特性,实现不同容器之间的网络隔离。

在 Linux 的网络命名空间中,每个空间都拥有独立的路由表和 iptables 设置,负责包转发、网络地址转换(NAT)和 IP 包过滤等功能。由于网络命名空间代表独立的协议栈,它们相互隔离且无法直接通信。但 Docker 通过虚拟接口 veth 实现了容器之间以及容器与宿主机之间的通信。虚拟以太网(veth)以成对的形式出现,就像管道的两端一样。数据从一个 veth 进入,经过协议栈后,从另一个 veth 出去,打通了互相隔离的协议栈之间的壁垒。通过连接两个网络命名空间或全局命名空间,veth 可以将物理网卡存在的命名空间内进行通信。要在两个网络命名空间之间实现通信,必须有一对虚拟接口对。

2、Linux 网络虚拟化

Docker 利用了 Linux 上的网络命名空间和虚拟网络设备来实现本地网络功能。了解 Linux 网络虚拟化技术有助于理解 Docker 网络的实现过程,其中 Linux 网络虚拟化是 LXC 项目的一部分。LXC 包括文件系统虚拟化、进程空间虚拟化、用户虚拟化和网络虚拟化等。

Docker 使用了LXC的网络虚拟化来模拟多个网络环境。Linux网络虚拟化主要有以下类型:

  • 桥接:创建虚拟桥设备(网桥),将虚拟机连接至桥设备上,再配置桥设备的 IP 地址,即可与外部通信。此时虚拟机使用的是公网地址
  • 隔离:将需要通信的虚拟机的网卡添加到同一个虚拟桥设备上,实现虚拟机之间的通信,与外网仍然隔离
  • 路由:将虚拟机关联至虚拟桥设备上,配置与虚拟机同段的 IP 地址作为虚拟机的网关,最后打开物理主机的核心转达功能,实现虚拟机与外部主机的通信
  • NAT:在路由模型的基础上,配置源地址转换(SNAT)规则,实现虚拟机与外网通信,但自己使用的是内网地址。外网无法主动访问内网的虚拟机,需要额外配置目标地址转换(DNAT)规则

Docker 中的网络接口默认为虚拟接口,其最大优势是转发效率高。Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,即直接将发送接口的数据包复制到接收接口的缓存中,无需通过外部物理网络设备进行交换。对于本地系统和容器内系统而言,虚拟接口和普通以太网卡没有区别,但速度更快。
Docker 容器网络利用了 Linux 虚拟网络技术,通过在本地宿主机和容器内部创建虚拟接口 veth 并连接二者,这样的一对虚拟接口称为 veth pair。

通常情况下,Docker 创建容器时执行以下操作:

  • 创建一对虚拟接口,一个放在本地宿主机,另一个放在新容器的命名空间中
  • 将本地宿主机端的虚拟接口连接到默认的网桥 docker0(实际上是一个 Linux 网桥)或指定的网桥上,并赋予一个以 veth 开头的唯一名称,如 veth18
  • 将容器端的虚拟接口放置到新创建的容器中,并将其名称修改为 eth0。此接口仅在容器的命名空间中可见
  • 从网桥可用地址段中获取一个空闲地址,分配给容器的 eth0 接口(如172.10.0.22/16),并配置默认路由网关为 docker0 网桥的内部接口IP地址(如172.10.1.1/16)

完成上述操作后,Docker 在宿主机和所有容器之间创建了一个虚拟共享网络。容器可以使用其可见的 eth0 虚拟网卡连接其他容器并访问外部网络。在使用 docker [container] run 命令启动容器时,可以通过--net参数指定容器的网络配置。目前有5个可选值,分别是 bridge、container、host、none 和自定义网络。

3、Docker 网络架构

前面介绍了使用 -p 参数实现 Docker 容器与宿主机端口的映射,以及通过--link参数实现容器之间的网络通信。随着 Docker 的不断发展,其网络架构也在逐步演进。

与虚拟机或物理机不同,Docker 容器内部运行的应用程序需要大量不同类型的网络交互,这要求 Docker 具备强大的网络功能。幸运的是,Docker 提供了一套完整的解决方案,用于容器之间、容器与外部网络以及虚拟局域网(VLAN)之间的连接。这对于需要与外部系统(如虚拟机和物理机)进行通信的容器化应用至关重要。

Docker 1.9 版本引入了一套完整的 docker network 子命令和跨主机网络支持。用户可以通过 docker network --help 查看 Docker 网络命令的详细说明。这使得用户可以根据其应用程序的拓扑架构创建虚拟网络,并将容器连接到相应的网络上。事实上,在 Docker 1.7 版本中,网络部分代码就已经被抽离并单独形成了 Docker 的网络库,即 Libnetwork。随后,容器的网络模式被抽象成了统一接口的驱动。

为了标准化网络驱动的开发流程并支持多种网络驱动,Docker 在 Libnetwork 中采用了容器网络模型(CNM)。CNM 定义了构建容器虚拟化网络的模型,并提供了用于开发多种网络驱动的标准接口和组件。Libnetwork 是 Docker 对 CNM 的一种实现,提供了 Docker 核心网络架构的全部功能。不同的驱动可以通过插拔的方式接入 Libnetwork,以提供定制化的网络拓扑。为了实现即插即用的效果,Docker 封装了一系列本地驱动,覆盖了大部分常见的网络需求,包括单机桥接网络、多机覆盖网络,以及支持接入现有 VLAN。Libnetwork 与 Docker 守护进程及各个网络驱动之间的关系如图所示。

Docker 网络架构主要由 CNM、Libnetwork 和驱动三个主要部分组成。Docker 守护进程通过调用 Libnetwork 提供的 API 完成网络的创建和管理等功能;Libnetwork 则使用 CNM 来实现网络功能的提供;而 CNM 主要包括沙盒、接入点和网络三种组件。

Libnetwork 内置了 5 种驱动,为 Libnetwork 提供了不同类型的网络服务。

4、容器网络模型

Libnetwork 中的容器网络模型(CNM)简洁而精致,规定了 Docker 网络的基础组成要素,使得上层容器可以最大程度地摆脱底层实现的烦恼。CNM模型包括以下三种基本组件:

  • 沙盒:代表容器独立的网络栈,包括以太网接口、端口、路由表以及 DNS 配置
  • 接入点:在网络上代表可以连接容器的虚拟接口,会分配 IP 地址。类似于普通网络接入点,接入点主要负责创建连接,在 CNM 模型中,接入点负责将沙盒连接到网络
  • 网络:是一个虚拟子网,可以连接多个接入点,是 IEEE 802.1d 网桥的软件实现

Docker 环境中最小的调度单位是容器,而 CNM 则专注于为容器提供网络功能。下图展示了 CNM 组件如何与容器进行关联,沙盒被置于容器内部,为容器提供网络连接。

接入点类似于常见的网络适配器,一个接入点只能连接到一个网络。如果容器需要连接到多个网络,则需要多个接入点。例如,容器 A 只有一个接入点并连接到网络 A,容器 B 有两个接口分别连接到网络 A 和 B。容器 A 和 B 可以相互通信,因为它们都连接到了同一个网络 A。但是,如果没有三层路由器的支持,容器B的两个接入点之间是无法相互通信的。

通过面向接口的分层解耦设计,CNM 实现了关注点的分离,使得容器管理系统无需关心底层网络的实现细节和不同子网之间的隔离。只要插件能够提供网络和接入点,容器管理系统只需连接或断开容器,剩余的工作就交由插件自行处理,实现了容器和网络功能的解耦,具有极高的灵活性。

CNM 网络的创建过程是,Libnetwork 网络驱动将自身注册到网络控制器,网络控制器使用驱动类型创建网络,然后在创建的网络上创建接口,最后将容器连接到接口上。销毁过程则相反,首先从接入点上卸载容器,然后删除接入点和网络即可。

目前 CNM 支持四种网络驱动类型:

  • null:不提供网络服务,容器启动后无网络连接
  • bridge:Docker 传统的单机网络,基于 Linux 网桥和 iptables 实现
  • overlay:跨宿主机容器网络,利用虚拟扩展局域网(VXLAN)隧道技术实现
  • remote:扩展类型,为其他外部实现的方案保留,由第三方编写网络驱动,例如 Calico、Contiv、Kuryr、Weave 等

Libnetwork 位于 Docker 上方支持 Docker,下方支持网络插件,处于十分关键的中间层。熟悉计算机网络协议模型的读者可以将 Libnetwork 视为传输控制协议/网际协议(TCP/IP)层的核心。每个驱动负责管理其上的所有网络资源。为了满足复杂且多变的环境需求,Libnetwork 支持同时激活多个网络驱动,从而支持庞大的异构网络。

5、单机桥接网络

最简单的 Docker 网络是单机桥接网络,从名称中即可了解以下两点:

  • 单机:该网络仅在单个 Docker 宿主机上运行,只能连接到该宿主机上的容器
  • 桥接:这意味着它是 IEEE 802.1d 桥接的一种实现,即二层交换机

每个 Docker 宿主机都默认拥有一个单机桥接网络。在 Linux 上,网络名为 bridge;在 Windows 上,网络名为 NAT。除非在创建容器时明确指定了 --network 参数,否则新创建的容器都会自动连接到该网络。

在 Linux 宿主机上,Docker 网络由 bridge 驱动创建,底层基于 Linux 内核的 Linux 网桥技术。这意味着 bridge 网络具有高性能和稳定性,并且可以通过标准的 Linux 工具进行管理。

默认情况下,Linux Docker 宿主机上的 bridge 网络映射到内核中的 docker0 Linux 网桥。通过 docker network inspect bridge 命令可以查看该虚拟网络的详细信息。

docker0 网桥类似于交换机,用于转发连接到其上的设备的数据帧。网桥上的 veth 网卡设备相当于交换机上的端口,可连接多个容器或虚拟机,工作在二层,无需配置 IP 信息。

在 Docker 的桥接网络模式中,docker0 的 IP 地址作为连接到其上的容器的默认网关地址存在。

在宿主机上安装 Docker 引擎时,Docker 默认会创建 bridge 网络,并且宿主机上的所有容器默认都会连接到此网络。可通过 docker network create 命令创建新的单机桥接网络,并通过在容器启动时使用 docker run 命令的 --network 参数指定容器要连接的网络。

在同一网络中,不同容器可以通过容器名相互访问,因为所有容器都注册在指定的 Docker DNS 服务上。在单机桥接网络模式下,不同网络中的容器要相互访问,则需要使用端口映射来避免容器名解析限制。通过在容器启动时使用 docker run 命令的 -d 参数指定容器与宿主机的端口映射,将容器端口映射到 Docker 宿主机端口上,从而实现访问。

6、多机覆盖网络

覆盖网络适用于跨多个宿主机的环境,它创建了一个扁平、安全的二层网络,用于连接这些宿主机。容器可以连接到覆盖网络并直接相互通信,实现链路层的数据传输。覆盖网络是实现容器间通信的理想方式,具有良好的网络伸缩性。

Docker 提供了本地驱动来支持覆盖网络,该驱动是基于 Libnetwork 和 overlay 驱动构建的,使得创建覆盖网络非常简单,只需在 `docker network create` 命令中添加 `--d overlay` 参数。

overlay 驱动默认使用 VXLAN 协议,在可相互访问的多个宿主机之间建立隧道,从而实现容器之间的互相访问。Docker 使用 VXLAN 隧道技术创建虚拟的二层覆盖网络。VXLAN 是一种封装技术,能够使现有的路由器和网络架构看起来像普通的 IP/UDP 包一样,并且可以无缝处理。为了创建二层覆盖网络,VXLAN 基于现有的三层 IP 网络创建了隧道。

在 VXLAN 的设计中,每个节点之间建立了 VXLAN 隧道,这些节点称为 VXLAN 隧道终端(VTEP)。VTEP 完成了封装和解压缩的操作,以及一些必要的功能实现。在两个节点之间建立 VXLAN 隧道后,为了实现跨节点的容器间互联,我们需要在每个宿主机上创建一个沙盒(网络命名空间)。沙盒类似于容器,但其中运行的是当前宿主机上独立的网络栈。在沙盒内部,创建一个名为 Br0 的虚拟交换机(也称为虚拟网桥)。同时,在沙盒内部创建一个 VTEP,其中一端连接到名为 Br0 的虚拟交换机,另一端连接到宿主机的网络栈(VTEP)。

在宿主机网络栈中,VTEP 从基础网络中获取 IP 地址,并通过 UDP 套接字绑定到 4789 端口(IANA 规定的 UDP 端口)。不同宿主机上的两个 VTEP 通过 VXLAN 隧道创建了一个覆盖网络。

每个容器都有自己的虚拟以太网适配器(veth),并连接到本地虚拟交换机 Br0。目前的拓扑结构如图所示。

虽然宿主机网络相互独立,但位于不同宿主机上的容器可以通过 VXLAN 覆盖网络进行通信。例如,容器 C1(位于节点1)希望 ping 通容器 C2(位于节点2)。C1 发起 ping 请求,目标 IP 为 C2 的地址 10.1.0.8。请求流量通过连接到虚拟交换机 Br0 的 veth 发送出去。Br0 不知道将数据包发送到哪里,因此会将其发送到所有端口。连接到 Br0 的 VTEP 接口知道如何转发这个数据帧,并将自己的 MAC 地址返回给 Br0。这是一个代理 ARP 响应,使得 Br0 学会了如何转发该包。之后,Br0 更新了自己的 ARP 映射表,将 10.1.0.8 映射到本地 VTEP 的 MAC 地址。现在,Br0 已经学会如何转发到 C2 的流量,之后所有发送到 C2 的包都将直接转发到 VTEP 接口。

当包到达节点2后,内核发现目标端口为 UDP Socket 端口 4789,并且知道存在 VTEP 接

口绑定到该 Socket。因此,内核将包发送给 VTEP,VTEP 读取 VNID,解压缩包信息,并根据 VNID 发送到本地连接到 VLAN 的虚拟交换机 Br0。在 Br0 上,包被发送给容器 C2。

7、混合互联网络

在先前的介绍中,讨论了单节点和跨节点下多个 Docker 容器之间的互联互通。然而,在企业的实际 IT 架构中,由于历史原因,大量传统架构的应用需要进行集成。因此,将容器化应用连接到外部系统和物理网络是至关重要的能力。一个常见的场景是部分容器化的应用需要与运行在物理网络和 VLAN 上的未容器化应用进行通信。这就引入了虚拟网络和物理网络之间混合互联的网络架构。

Docker 内置的 macvlan 驱动就是为这种场景而设计的。通过为容器提供 MAC 地址和 IP 地址,macvlan 允许容器在物理网络上成为“一等公民”。

macvlan 本身是一个 Linux 内核模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个接口,每个接口可以配置自己的 IP 地址。macvlan 本质上是一种网卡虚拟化技术,其优点在于性能优异,因为无需端口映射或额外桥接,可以直接通过主机接口(或子接口)访问容器接口。但缺点是需要将主机网络接口卡(Network Interface Card,NIC)设置为混杂模式(promiscuous mode),而这在大部分公有云平台上是不允许的。因此,macvlan 对于公司内部的数据中心网络来说非常实用(假设公司网络组能接受 NIC 设置为混杂模式),但在公有云上则不可行。

创建 macvlan 网络非常简单,只需在 Docker 创建网络命令 docker network create 中添加 -d macvlan 参数即可。创建的 macvlan 网络可以是 bridge 模式或 802.1q trunk bridge 模式:

  • 在 bridge 模式中,macvlan 流量通过主机上的物理设备
  • 在 802.1q trunk bridge 模式中,流量通过 Docker 在运行中创建的 802.1q 子接口,用户可以更细粒度地控制路由和过滤

8、网络访问控制

Docker 容器的网络访问控制主要通过 Linux 系统上的 iptables 防火墙软件来进行管理和实现。iptables 是 Linux 系统中流行的防火墙软件,在大多数发行版中都自带。

安装完 Docker 后,宿主机系统会默认添加一些 iptables 规则,用于管理 Docker 容器之间以及容器与外部世界的通信。iptables 的工作原理是基于规则,这些规则实际上是由网络管理员预定义的条件。一般情况下,规则定义了如果数据包头符合某种条件,就对这个数据包采取相应的处理方式。这些规则存储在内核空间的信息包过滤表中,其中包括了源地址、目的地址、传输协议(如TCP、UDP、ICMP)以及服务类型(如HTTP、FTP、SMTP)等信息。当数据包与规则匹配时,iptables 会根据规则所定义的方法来处理这些数据包,比如允许通过(accept)、拒绝(reject)或丢弃(drop)等。

配置防火墙的主要任务就是添加、修改和删除这些规则。您可以使用 iptables-save命令来查看宿主机中Docker引擎为我们设置的iptables规则信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/541222.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字信封

一、概念 数字信封是将对称密钥通过非对称加密(即:有公钥和私钥两个)的结果分发对称密钥的方法。数字信封是实现信息保密性验证的技术。 二、过程描述 在数字信封中,信息发送方采用对称密钥来加密信息内容,然后将此…

第二证券|AIGC行业新突破不断 文化传媒板块活跃

本周以来,以短剧、游戏为代表的文明传媒板块实现三连涨。3月13日,游戏股逆势大涨,游戏出海、网络游戏、短剧游戏方向领涨。到收盘,因赛集团以20%幅度涨停,掌趣科技涨超10%,凯撒文明、中广天择、时代出书、大…

ansible 部署FATE集群单边场景

官方文档: https://github.com/FederatedAI/AnsibleFATE/blob/main/docs/ansible_deploy_FATE_manual.md https://github.com/FederatedAI/AnsibleFATE/blob/main/docs/ansible_deploy_two_sides.md gitee详细文档: docs/ansible_deploy_one_side.md…

使用docker-compose部署Redis集群

一、部署三主三从的Redis集群 分别为6个节点建立挂载目录,每个目录下建立数据、配置、日志文件夹。 docker-compose内容如下: version: 3 services:redis1:image: redis:6.2.3restart: alwaysports:- "6379:6379"- "16379:16379"v…

短剧APP系统开发:打造全新的掌上剧场体验

随着移动互联网的普及和人们娱乐方式的多样化,短剧已经成为现代人生活中不可或缺的一部分。为了满足用户对高质量、便捷观看短剧的需求,我们致力于开发一款功能全面、操作简便的短剧APP系统,为用户带来前所未有的掌上剧场体验。 一、系统开发…

教你如何用Python生成随机数字和随机字符串

直接看代码 随机整数: >>> import random >>> random.randint(0,99) 21 随机选取0到100间的偶数: >>> import random >>> random.randrange(0, 101, 2) 42 随机浮点数: >>> import random >…

【leetcode】二叉树的前序遍历➕中序遍历➕后序遍历

大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1. 二叉树的前序遍历2. 二叉树的中序遍历3. 二叉树的后序遍历 1. 二叉树的前序遍历 点击查看题目 根…

ChatGPT终于有身体了

目录 一、开启 AI 机器人新纪元:Figure 01 的惊艳亮相 二、网友热议与技术探索:Figure 01 的广泛影响 三、未来展望:人形机器人与日常生活的融合 一、开启 AI 机器人新纪元:Figure 01 的惊艳亮相 在人工智…

18 OpenCV霍夫变换检测直线

文章目录 HoughLines 算子HoughLinesP 算子示例 HoughLines 算子 cv::HoughLines( InputArray src, // 输入图像,必须8-bit的灰度图像 OutputArray lines, // 输出的极坐标来表示直线 double rho, // 生成极坐标时候的像素扫描步长 double theta, //生成极坐标时候…

【阿里云系列】-部署ACK集群的POD应用日志如何集成到日志服务(SLS)中

介绍 我们在实际部署应用到阿里云的ACK集群后,由于后期应用服务的持续维护诉求可能需要跟踪排查问题,此时就要具备将应用的历史日志存档便于后期排查问题 处理方式 为了解决以上的普遍需求,需要将ACK中的应用日志采集到SLS的Logstore中,然…

使用CIP采集欧姆龙EtherNet/IP从入门到精通

本文将会从以下几个方面介绍 1.CIP是什么 2.EtherNet/IP通信是什么 3.CIP通信报文解析 4.使用CIP常用的方法和功能介绍(UCMM) 5.自己封装了一个类,只要知道标签名称,和数据类型即可读写数据 6.demo展示 1.CIP是什么 CIP通信…

CSS:过渡动画 (Transition)与关键帧动画(Keyfram)

一、过渡动画 (Transition) 1.简单介绍 Transition能为样式的变化提供过渡效果,例如在下面的代码中: .main {width: 300px;height: 100px;background-color: #d26f6f;}.main:hover {width: 300px;height: 200px;background-color: #5e3e3e;transition:…