跨主机网络概述 - 每天5分钟玩转 Docker 容器技术(48)

前面已经学习了 Docker 的几种网络方案:none、host、bridge 和 joined 容器,它们解决了单个 Docker Host 内容器通信的问题。本章的重点则是讨论跨主机容器间通信的方案。

跨主机网络方案包括:

  1. docker 原生的 overlay 和 macvlan。
  2. 第三方方案:常用的包括 flannel、weave 和 calico。

docker 网络是一个非常活跃的技术领域,不断有新的方案开发出来,那么要问个非常重要的问题了:

如此众多的方案是如何与 docker 集成在一起的?

答案是:libnetwork 以及 CNM。

libnetwork & CNM

libnetwork 是 docker 容器网络库,最核心的内容是其定义的 Container Network Model (CNM),这个模型对容器网络进行了抽象,由以下三类组件组成:

Sandbox

Sandbox 是容器的网络栈,包含容器的 interface、路由表和 DNS 设置。 Linux Network Namespace 是 Sandbox 的标准实现。Sandbox 可以包含来自不同 Network 的 Endpoint。

Endpoint

Endpoint 的作用是将 Sandbox 接入 Network。Endpoint 的典型实现是 veth pair,后面我们会举例。一个 Endpoint 只能属于一个网络,也只能属于一个 Sandbox。

Network

Network 包含一组 Endpoint,同一 Network 的 Endpoint 可以直接通信。Network 的实现可以是 Linux Bridge、VLAN 等。

下面是 CNM 的示例:

如图所示两个容器,一个容器一个 Sandbox,每个 Sandbox 都有一个 Endpoint 连接到 Network 1,第二个 Sandbox 还有一个 Endpoint 将其接入 Network 2.

libnetwork CNM 定义了 docker 容器的网络模型,按照该模型开发出的 driver 就能与 docker daemon 协同工作,实现容器网络。docker 原生的 driver 包括 none、bridge、overlay 和 macvlan,第三方 driver 包括 flannel、weave、calico 等。

下面我们以 docker bridge driver 为例讨论 libnetwork CNM 是如何被实现的。

这是前面我们讨论过的一个容器环境:

  1. 两个 Network:默认网络 “bridge” 和自定义网络 “my_net2”。实现方式是 Linux Bridge:“docker0” 和 “br-5d863e9f78b6”。
  2. 三个 Enpoint,由 veth pair 实现,一端(vethxxx)挂在 Linux Bridge 上,另一端(eth0)挂在容器内。
  3. 三个 Sandbox,由 Network Namespace 实现,每个容器有自己的 Sanbox。

接下来我们将详细讨论各种跨主机网络方案,首先学习 Overlay。

时间: 2024-11-23 15:27:23

跨主机网络概述 - 每天5分钟玩转 Docker 容器技术(48)的相关文章

overlay 如何实现跨主机通信?- 每天5分钟玩转 Docker 容器技术(52)

上一节我们在 host1 中运行了容器 bbox1,今天将详细讨论 overlay 网络跨主机通信的原理. 在 host2 中运行容器 bbox2: bbox2 IP 为 10.0.0.3,可以直接 ping bbox1: 可见 overlay 网络中的容器可以直接通信,同时 docker 也实现了 DNS 服务. 下面我们讨论一下 overlay 网络的具体实现: docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux brid

macvlan 网络结构分析 - 每天5分钟玩转 Docker 容器技术(56)

上一节我们创建了 macvlan 并部署了容器,本节详细分析 macvlan 底层网络结构. macvlan 网络结构分析 macvlan 不依赖 Linux bridge,brctl show 可以确认没有创建新的 bridge. 查看一下容器 bbox1 的网络设备: 除了 lo,容器只有一个 eth0,请注意 eth0 后面的 @if4,这表明该 interface 有一个对应的 interface,其全局的编号为 4.根据 macvlan 的原理,我们有理由猜测这个 interface

如何使用 Weave 网络?- 每天5分钟玩转 Docker 容器技术(63)

weave 是 Weaveworks 开发的容器网络解决方案.weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来.对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交换机,容器可以直接通信,无需 NAT 和端口映射.除此之外,weave 的 DNS 模块使容器可以通过 hostname 访问. 实验环境描述 weave 不依赖分布式数据库(例如 etcd 和 consul)交换网络信息,每个主机上只需运行 weave 组件就能建立起跨主机容器网络.我们会在 ho

flannel 概述 - 每天5分钟玩转 Docker 容器技术(58)

flannel 是 CoreOS 开发的容器网络解决方案.flannel 为每个 host 分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可以在 host 间路由,容器间无需 NAT 和 port mapping 就可以跨主机通信. 每个 subnet 都是从一个更大的 IP 池中划分的,flannel 会在每个主机上运行一个叫 flanneld 的 agent,其职责就是从池子中分配 subnet.为了在各个主机间共享信息,flannel 用 etcd(与 cons

如何自定义容器网络?- 每天5分钟玩转 Docker 容器技术(33)

除了 none, host, bridge 这三个自动创建的网络,用户也可以根据业务需要创建 user-defined 网络. Docker 提供三种 user-defined 网络驱动:bridge, overlay 和 macvlan.overlay 和 macvlan 用于创建跨主机的网络,我们后面有章节单独讨论. 我们可通过 bridge 驱动创建类似前面默认的 bridge 网络,例如: 查看一下当前 host 的网络结构变化: 新增了一个网桥 br-eaed97dc9a77,这里 e

如何部署 Calico 网络?- 每天5分钟玩转 Docker 容器技术(67)

Calico 是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来.与 VxLAN 不同的是,Calico 不对数据包做额外封装,不需要 NAT 和端口映射,扩展性和性能都很好. 与其他容器网络方案相比,Calico 还有一大优势:network policy.用户可以动态定义 ACL 规则,控制进出容器的数据包,实现业务需求. 实验环境描述 Calico 依赖 etcd 在不同主机间共享和交换信息,存储 Cal

Weave 网络结构分析 - 每天5分钟玩转 Docker 容器技术(64)

上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构. 在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 -itd busybox   首先执行 eval $(weave env) 很重要,其作用是将后续的 docker 命令发给 weave proxy 处理.如果要恢复之前的环境,可执行 eval $(weave env --restore). 查看一下当前容器 bbox1 的网络配置: bbox1

如何定制 Calico 网络 Policy - 每天5分钟玩转 Docker 容器技术(70)

Calico 默认的 policy 规则是:容器只能与同一个 calico 网络中的容器通信.本节讨论如何定制 policy. calico 能够让用户定义灵活的 policy 规则,精细化控制进出容器的流量,下面我们就来实践一个场景: 创建一个新的 calico 网络 cal_web 并部署一个 httpd 容器 web1. 定义 policy 允许 cal_net2 中的容器访问 web1 的 80 端口. 首先创建 cal_web. docker network create --driv

跨主机使用 Rex-Ray volume - 每天5分钟玩转 Docker 容器技术(77)

上一节我们在 docker1 上的 MySQL 容器中使用了 Rex-Ray volume mysqldata,更新了数据库.现在容器已经删除,今天将演示在 docker2 中重新使用这个卷. 在 dokcer2 上执行如下命令,启动 MySQL 容器: docker run --name mydb_on_docker2 -v mysqldata:/var/lib/mysql -d mysql 新容器也使用相同的卷 mysqldata,不过这次不需要指定环境变量 MYSQL_ROOT_PASSW