V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Igotyouinmysight
V2EX  ›  分享发现

Rainbond 设计分享系列(1)基于 Midonet 的多租户网络设计

  •  
  •   Igotyouinmysight · 2018-01-09 10:30:45 +08:00 · 1234 次点击
    这是一个创建于 2512 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天跟大家分享 Rainbond 基于 Midonet 的多租户网络设计和思考。

    Rainbond 对多租户支持的实现基础是对多租户的网络支持,Rainbond 公有云要求每个租户之间网络必须隔离,形成相互安全的租户网络环境。对于不同的 SDN 网络,实现方式各不相同,例如 Calico 从路由规则上隔离,Midonet 可以为不同租户创建子网等。Rainbond 底层采用 Kubernetes 作为应用运行方案,其采用标准的 CNI 网络接入规范,为 Rainbond 支持多种网络提供了标准化支持。

    对于中小集群用户,Rainbond 推荐使用基于 Calico 的网络方案,作为 Kubernetes 社区常用方案之一,本文不再详细介绍。我们今天分享重点是对于大型集群或对租户网络隔离有严格要求的用户,也就是基于 Midonet 的方案。

    什么是 CNI 规范

    (CNI)[https://github.com/containernetworking/cni/blob/spec-v0.2.0/SPEC.md]( Container Networking Interface )是为在 Linux 运行的容器提出的一种通用的基于插件的网络解决方案,其最初来源于 Rkt 容器网络设计,目前被 Kubernetes 等项目标准支持。其最新已到 0.3.0 版本,目前 Rainbond 支持 0.2.0 版本。其面向两个抽象实体:

    容器 可以被认为是 Linux 网络命名空间的同义词。与之相对应的单元取决于特定的容器运行时实现:例如,在应用容器规范(如 Rkt )的实现中,每个容器运行在唯一的网络名称空间中。另一方面,在 Docker 中,每个单独的 Docker 容器通常都存在网络名称空间。

    网络 是指一组实体,它们是唯一可寻址的,可以相互通信。这可以是单个容器(如上所述),机器或其他网络设备(例如路由器)。容器可以在概念上添加到一个或多个网络或从中删除。

    Rainbond 中每个应用运行实例使用一个网络空间,运行实例创建和销毁分别会设置和回收网络资源。因此,网络资源是一个动态的可复用的资源。

    MidoNet SDN 网络

    MidoNet 是由日本的 SDN 公司 Midkura 研发的一款网络虚拟化软件,其基于底层物理设施来实现网络虚拟化,具有分布式、分散、多层次的特点,主要作为 OpenStack 中的默认网络组件,可以让虚拟网络解决方案,特别是专为网络基础设施设计的方案,为云平台如 OpenStack 服务,并且将其网络存贮栈虚拟化。MidoNet 为每个租户分配一个逻辑 router,租户与租户之间是相互隔离的,租户内部之间是能够相互通讯的,Midonet 支持 L2 交换、L3 路由、L4 负载均衡 有状态和无状态 NAT,逻辑和分布式防火墙,BGP 与 ECMP 支持。其架构主要包含以下组件:

    Midolman ( Midonet Agent ):Midonet

    Agent 安装在各个计算节点,负责建立网络流量控制和提供分布式 Midonet 网络服务,路由,NAT 等他把相关的虚拟网络信息存放到 NSDB。

    Network State

    Database(NSDB):存储网络配置和状态,网络拓扑,路由,Midonet 不集中处理网络功能,由 Midonet Agent 处理,Midonet Agent 会跟 NSDBs 做实时同步当有变化时候会及时同步并且更新 NSDB

    MidonetAPI

    midonet 提供 restful API 接口提供全套的模型操作,这对于我们为其做 CNI-plugin 奠定基础。

    MidoNet 支持大规模 SDN 集群,其架构理论上支持上万节点。Rainbond 基于 Midonet 网络可支持上万节点集群,其最初设计用于 OpenStack 虚拟机网络,我们将其与容器适配,使其成为标准的容器网络解决方案。

    MidoNet 多租户下网络结构模型

    SDN(软件定义网络),midonet 软件定义你所熟知的网络组件。以下简单介绍几个核心的软件定义概念:

    • Router(路由器)
      一个租户对应一个 Router,连接到同一个 Router 的 Bridge 网络互通。Midonet 会创建一个 PrivierRouter,所有租户 Router 连接到 PrivierRouter 与外网互通。可以理解为一个路由器内网互通,连接上级路由器接入公网。
    • Bridge(网桥)
      一个租户下可以有多个 Bridge,每个 Bridge 使用不同的网段。例如一个 Bridge 网段为192.168.0.0/24,最多可以有 253 个虚拟设备连接到本 Bridge。
    • Port(设备通信端口)
      Router 与 Router 之间,Router 与 Bridge 之间的通信接口。
    • Route(路由)
      路由规则,给 Router 定义流量包转发端口的规则。
    • Rule(过滤规则)
      定义包过滤条件。类似于 iptables。 image

    基于 MidoNet 的 CNI 插件实现

    midonet 数据交换工作在三层,但是其本身不提供 IP 地址管理(IPAM),因此基于 Midonet 的 cni 插件需要完成以下工作:

    IPAM 区别不同的租户为应用实例分配可用 IP 和回收已销毁实例的 IP 地址,同时还需要为下文涉及的 Router,Bridge 分配 IP 网段。每一个 Router 具有一个 IP 地址,且全局唯一不冲突。每一个 Bridge 具有一个唯一网段,连接的虚拟网卡具有全局唯一 IP。IPAM 需要数据存储,本该是有状态的守护服务。但是 CNI-Plugin 必须设计成无状态的命令,因此我们使用 etcd 作为我们的数据存储服务,其全局一致性保证了我们端口分配的正确性。 租户 Router 创建 一个新租户第一个实例启动阶段会为当前租户在 Midonet 中创建虚拟租户子网。并连接到 PrivierRouter 与外围直连。 租户 Bridge 创建 一个租户可以有一个或多个 Bridge,根据其实例数量决定,每个网桥具有不同的虚拟网段,最多支持 253 个运行实例。 容器网卡创建 为目标容器创建网卡接口是 CNI 插件必备的功能,根据需要可创建多个或一个,这里接入 Midonet Bridge 需要一个网卡。 端到端连接建立 每一个 Bridge 需要与租户 Router 建立连接,每一个运行实例需要与对应的 Bridge 建立连接。 路由过滤规则 PrivierRouter 到租户 Router 需要路由规则,租户 Router 到 Bridge 需要路由规则和过滤规则。

    租户网络初始化

    当新租户第一次创建容器时进行租户虚拟设备的初始化创建,上文我们已经介绍了一个租户需要创建的虚拟设备有哪些,这里我讲讲细节。 Midonet 提供了 Rest-API 来操作虚拟设备。这里注意,根据使用的不同版本的 Midonet 使用不同版本的 API。 https://github.com/barnettZQG/golang-midonetclient
    我们基于 Golang 需要封装了 midonet client,支持 1.*和 5.*API 版本的常用 API。 创建步骤如下:

    1. 创建租户,调用 Keystone API。
    2. 创建 Router,并包含创建进出 Chain。
    3. 创建 PrivierRouter Port 并赋 IP,创建 Router Port 并赋 IP。创建 PortLink 连接两个 Port。
    4. 为前面创建的 Chain 创建对应的路由规则
    5. 为前面创建的 Port 创建包过滤规则
    6. 创建一个默认的 Bridge。并创建 Port 连上 Router。
    7. 存储以上创建的相关数据进 etcd.

    容器网卡创建和网络绑定

    Virtual Ethernet Pair

    简称 veth pair,是一个成对的端口,所有从这对端口一端进入的数据包都将从另一端出来,反之也是一样.其两端可存在于不同的网络空间( Network Namespace )。容器创建成功后具有一个网络空间,容器创建时调用 CNI 插件 ADD 方法进行网络设置。插件首先创建一对 Veth pair。将其一端置于宿主机网络空间,调用 Midonet 绑定 API 将其与 Bridge 一个 Port 绑定。另一端在容器内并由 IPAM 模块分配并赋予 IP 地址,其与 Docker0 网卡部分原理一致。

    设置容器内路由规则

    将默认路由设置到上文创建的网卡上。例如上文创建的网卡命名为 eth0,默认出口路由设置到 eth0 网卡,如此用户应用的出口网络将默认使用 Midonet 网络统一管理。在 Rainbond 的用例中,需要外网访问的应用除了 eth0 网卡以外还有一块接入宿主机的网卡 eth1,其映射到宿主机后由边缘负载均衡代理向外网提供服务,因此 Rainbond 还会设置自定义的路由规则。

    设置 DNS 根据需要设置一些 DNS 信息,例如 Rainbond 会设置 Rainbond 相关的应用 DNS 信息。

    CNI 插件实现的注意事项

    1. CNI 插件的添加和删除操作应该具有幂等性,即同样的参数传入不管调用多少次都应该有相同的效果。
    2. CNI 插件应该支持并发性,主要是租户相关组件的创建和 IP 地址分配的强一致性。
    3. CNI 插件有一定的规范,请参考:https://github.com/containernetworking/cni

    FAQ

    • Rainbond 是什么?是否开源?

    Rainbond 是国内首个开源的生产级无服务器 PaaS,深度整合基于 Kubernetes 的容器管理、多类型 CI/CD 应用构建与交付、多数据中心的资源管理等技术,提供云原生应用全生命周期解决方案,构建应用与基础设施、应用之间及基础设施之间的互联互通生态体系。Rainbond 目前基于 L-GPL(v3)开源协议开源。 项目地址: https://github.com/goodrain/rainbond 官网: http://www.rainbond.com

    • Midonet CNI-Plugin 是否开源?

    Midonet CNI-Plugin 作为 Rainbond 网络组件的一部分开源。 项目地址: https://github.com/goodrain/midonet-cni

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   997 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:09 · PVG 05:09 · LAX 13:09 · JFK 16:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.