深入浅出边缘云 | 5. 运行时控制(下)

简介: 深入浅出边缘云 | 5. 运行时控制(下)
5.2.3 身份管理


运行时控制利用外部身份数据库(LDAP 服务器)存储用户数据,例如能够登录的用户的帐户名和密码,LDAP 服务器还具有将用户与组关联的功能。例如,将管理员添加到AetherAdmin组将是在运行时控制中授予个人管理权限的一种明显的方法。


外部认证服务 Keycloak 用作数据库(如 LDAP)的前端,对用户进行身份验证,处理接受密码、验证密码的机制,并安全返回用户所属的组。


延伸阅读:

Keycloak: Open Source Identity and Access Management.


然后,使用组标识符授予对运行时控制子系统内资源的访问权,这将指向相关的问题,即确定哪类用户被允许创建/读/写/删除各种对象集合。与身份管理一样,定义这样的 RBAC 策略是很容易理解的,并得到开源工具的支持。对于 Aether,Open Policy Agent (OPA)扮演了这个角色。


延伸阅读:

Policy-based control for cloud native environments.


5.2.4 适配器


并非每个服务以及运行时控制下面的子系统都支持 gNMI,在不支持 gNMI 的情况下,需要编写适配器来翻译 gNMI 和服务本地 API 之间的交互。以 Aether 为例,一个 gNMI->REST 适配器在运行时控制的南向 gNMI 调用和 SD-Core 子系统的 REST 北向接口之间进行转换。适配器不一定只是一个语法翻译器,还可能包括自己的语义层。这支持存储在 x-config 中的模型与南向设备/服务使用的接口之间的逻辑解耦,允许南向设备/服务和运行时控制独立发展,还允许南向设备/服务的替换不影响北向接口。


适配器不一定只支持单一服务。适配器采取的是一种跨越多个服务的抽象手段,并将其应用于每个服务中。Aether 中的一个例子是用户平面功能(SD-Core 用户平面中的主要数据包转发模块)和 SD-Core,它们共同负责确定服务质量,其中适配器将一套单一的模型应用于两个服务。需要注意处理部分失败的情况,即一个服务接受变化,但另一个不接受。在这种情况下,适配器会继续尝试失败的后端服务,直到它成功。


5.2.5 工作流引擎


图 22 中 x-config 左边的工作流引擎是实现多步工作流的地方。例如,定义新的 5G 连接或将设备与现有连接关联是一个多步骤的过程,需要使用多个模型并影响多个后端子系统。根据我们的经验,甚至可能有复杂的状态机来实现这些步骤。


有一些众所周知的开源工作流引擎(例如,Airflow),但我们的经验是,它们与 Aether 等系统典型的工作流类型不匹配。因此,当前采用了特别的实现,使用命令式代码监视目标模型集,并在它们发生更改时采取适当的行动。为工作流定义更严格的方法是正在进行中的课题。


5.2.6 安全通信


gNMI 自然适合使用双向 TLS 进行身份验证,这是使用 gNMI 的组件之间安全通信的推荐方式。例如,x-config 与其适配器之间的通信使用 gNMI,因此使用双向 TLS。在组件之间分发证书是运行时控制范围之外的问题,我们假定另一个工具将负责分发、撤销和更新证书。


对于使用 REST 的组件,HTTPS 用于保护连接,可以使用 HTTPS 协议中的机制进行身份验证(基本身份验证、令牌等)。当使用这些 REST API 时,Oauth2 和 OpenID Connect 被用作授权提供者。


5.3 连接服务建模


本节概述了 Aether 连接服务的数据模型,以说明运行时控制扮演的角色。这些模型是在 YANG 中指定的(我们为其中一个模型提供了具体示例),但由于运行时控制 API 是由这些规范生成的,它同样有效的考虑了支持 REST 的 GET, POST, PUT, PATCH 和 DELETE 操作的一组 web 资源(对象):


  • GET: 获取对象。
  • POST: 创建对象。
  • PUT, PATCH: 更改对象。
  • DELETE: 删除对象。


每个对象都是 YANG 定义的某个模型的实例,每个对象都包含用于标识对象的 id 字段。这些标识符是特定于模型的,例如,站点有 site-id,而企业有 enterprise-id。模型通常是嵌套的,例如,站点是企业的成员。对象还可以包含对其他对象的引用,这样的引用是基于对象的唯一 id 实现的。在数据库设置中,通常称为外键(foreign keys)。


除了 id 字段之外,其他几个字段对于所有模型也是通用的。这些包括:


  • description: 人类可读的描述,用于存储关于对象的附加上下文。
  • display-name: 用于在 GUI 中显示人类可读的名称。


因为这些字段对所有模型都是通用的,所以将在接下来的模型介绍中省略。在下面的例子中,我们用大写来表示模型(例如,Enterprise),用小写表示模型中的字段(例如,enterprise)。


5.3.1 企业(Enterprises)


Aether 部署在企业中,因此定义了一组具有代表性的组织抽象。其中包括 Enterprise,它形成了特定于客户的层次结构的根。Enterprise 模型是许多其他对象的父对象,并允许将这些对象限定在特定的 Enterprise 范围内,以实现所有权和基于角色的访问控制目的。Enterprise 模型包含以下字段:


  • connectivity-service: 为该企业实现连接性的后端子系统列表,对应 SD-Core、SD-Fabric 和 SD-RAN 的 API 端点。


Enterprises 进一步分为 Sites。站点是 Enterprise 的接入点,可以是物理的,也可以是逻辑的(例如,一个地理位置可以包含多个逻辑站点)。Site 模型包含以下字段:


  • imsi-definition: 如何为本站点建立 IMSI 的描述,包含以下子字段:
  • mcc: Mobile country code。
  • mnc: Mobile network code。
  • enterprise: 数字表示的 enterprise id。
  • format: 允许上述三个字段嵌入到 IMSI 中的掩码。例如,CCCNNNEEESSSSSS 将使用 3 位 MCC、3 位 MNC、3 位 ENT 和 6 位 subscriber 构建 IMSI。
  • small-cell: 5G 无线基站或接入点或无线电的列表,每个 small cell 有以下内容:
  • small-cell-id: small cell 的标识符,与其他 id 字段的用途相同。
  • address: small cell 的主机名。
  • tac: Type Allocation Code。
  • enable: 如果设置为 true,启用 small cell,否则为禁用。


imsi-definition 是特定于移动蜂窝网络的,对应于刻入每一张 SIM 卡的唯一标识符。


5.3.2 切片(Slices)


Aether 将 5G 连接建模为一个 Slice,表示一个隔离的通信通道(和相关的 QoS 参数),该通道将一组设备(建模为一个 Device-Group)连接到一组应用程序(每个应用程序建模为一个 Application)。每个 slice 都嵌套在某个 site 中(该 site 又嵌套在某个 enterprise 中),例如,企业可能配置一个切片承载 IoT 流量,另一个切片承载视频流量。Slice 模型有以下字段:


  • device-group: 可以加入此 Slice Device-Group 对象列表。列表中的每个条目都包含对 Device-Group 的引用以及 enable 字段,该字段可能用于临时删除对组的访问。
  • app-list: 这个 Slice 允许或拒绝的 Application 对象列表。列表中的每个条目都包含对 Application 的引用以及 allow 字段,该字段可以设置 true 或者 false 以允许或拒绝应用程序接入。
  • template: 对用来初始化这个 Slice Template 的引用。
  • upf: 索引用于处理该 Slice 报文的 UPF(User Plane Function),允许多个 Slices 共享一个 UPF
  • sst, sd: 3GPP 定义的切片标识符,由运维团队分配。
  • mbr.uplink, mbr.downlink, mbr.uplink-burst-size, mbr.downlink-burst-size: 该切片所有设备的最大比特率和峰值大小。


使用选定的模板(template) 初始化与速率相关的参数,如下所述。还要注意,这个例子说明了如何使用建模来强制定义不变量,在这种情况下,UPF Device-Group Site 必须匹配 Slice Site。也就是说,连接到切片的物理设备和实现切片的核心段的 UPF 必须被限制在一个物理位置内。


Slice 的一端是 Device-Group,标识一组允许使用切片连接到各种应用程序的设备。Device-Group 模型包含以下字段:


  • devices: 设备列表,每个设备都有 enable 字段,可以用来启用或禁用设备。
  • ip-domain: 引用 IP-Domain 对象,描述该组内终端的 IP 和 DNS 设置。
  • mbr.uplink, mbr.downlink: 设备组的每设备最大比特率。
  • traffic-class: 该组中设备使用的流量类。


Slice 的另一端是 Application 对象列表,指定程序设备通信的端点。Application 模型包含以下字段:


  • address: 终端的 DNS 名称或 IP 地址。
  • endpoint: 端点列表,每个都有以下字段:
  • name: 端点名称,用作 key。
  • port-start: 起始端口号。
  • port-end: 结束端口号。
  • protocol: 端点的协议(TCP|UDP)。
  • mbr.uplink, mbr.downlink: 应用程序端点的每设备最大比特率。
  • traffic-class: 与此应用程序通信的设备的流量类。


熟悉 3GPP 的人都知道 Aether 的 Slice 抽象类似于规范中的网络切片概念。Slice 模型定义包括 3GPP 指定的标识符(例如,sst sd)的组合,以及底层实现的细节(例如,upf 表示核心网用户平面的 UPF 实现)。虽然还不是生产系统的一部分,但有一个版本的 Slice 也包括了与 RAN 切片相关的字段,其中的运行时控制子系统负责将 RAN、Core 和 Fabric 之间的端到端连接无缝整合在一起。


平台服务 API


我们使用 Connectivity-as-a-Service 作为运行时控制扮演的角色的一个示例,但也可以使用相同的机制为其他平台服务定义 API。例如,由于 Aether 中的 SD-Fabric 是用可编程交换硬件实现的,转发平面是用带内网络遥测(INT)仪表化的,北向 API 支持在运行时对每个流进行细粒度数据收集,这使得在 Aether 之上编写闭环控制应用程序成为可能。


本着类似的精神,本节中给出的与 QoS 相关的控制示例可以通过附加对象进行扩展,这些对象提供了对 SD-RAN 实现的各种无线电相关参数的可见性和控制机会。这样做将是向平台 API 迈出的一步,该 API 有助于实现一类新的行业自动化边缘云应用程序。


一般来说,IaaS 和 PaaS 产品需要支持面向应用程序和用户的 API,这些 API 超出了底层软件组件(即微服务)所使用的 DevOps 级配置文件。创建这些接口是定义有意义的抽象层的练习,如果使用声明性工具,就变成了定义高级数据模型的练习。运行时控制是管理子系统,负责为这样的抽象层指定和实现 API。


5.3.3 模板和流量类


与每个 Slice 相关联的是 QoS 相关配置文件,该配置文件管理如何处理该 Slice 携带的流量。从 Template 模型开始,定义了有效的(可接受的)连接设置。Aether 运维团队负责定义这些(他们提供的特性必须得到后端子系统的支持),企业可以选择想要应用于创建的连接性服务的任何实例的模板(例如,通过下拉菜单)。也就是说,模板被用来初始化 Slice 对象。Template 模型有以下字段:


  • sst, sd: 切片标识符,由 3GPP 指定。
  • mbr.uplink, mbr.downlink: 最大上下行带宽。
  • mbr.uplink-burst-size, mbr.downlink-burst-size: 最大峰值大小。
  • traffic-class: 链接到描述流量类的 Traffic-Class 对象。


注意,Device-Group Application 模型也包含类似字段。其理念是,将 QoS 参数作为一个整体(基于所选 template)建立起来,然后连接到该切片的各个设备和应用程序可以在逐个实例的基础上分配自己的、限制性更强的 QoS 参数。


如前一节所述,Aether 将抽象 Slice 对象从端到端切片的后端段的实现细节中分离出来。这种解耦的一个原因是,支持选择一个全新的 SD-Core 副本,而不是与另一个 Slice 共享同一个 UPF。这样做是为了确保隔离,并说明了运行时控制和生命周期管理子系统之间可能的接触点: 运行时控制通过适配器,与生命周期管理一起启动必要的 Kubernetes 容器集,以实现隔离的切片。


Traffic-Class 模型指定了流量的分类,包括以下字段:


  • arp: 分配和保留优先级(Allocation and retention priority)。
  • qci: QoS 类标识符(QoS class identifier)。
  • pelr: 丢包率(Packet error loss rate)。
  • pdb: 包时延预算(Packet delay budget)。


完整起见,下面显示了 Template 模型对应的 YANG。为了简单起见,示例省略了一些介绍性的样板文件。该示例突出了模型声明的嵌套性质,包括container字段和leaf字段。


module onf-template {
  ...
  description 
    "The aether vcs-template holds common parameters used
     by a virtual connectivity service. Templates are used to
     populate a VCS.";
  typedef template-id {
        type yg:yang-identifier {
            length 1..32;
        }
  }
  container template {
    description "The top level container";
    list template {
      key "id";
      description
        "List of vcs templates";
      leaf id {
        type template-id;
        description "ID for this vcs template.";
      }
      leaf display-name {
        type string {
            length 1..80;
        }
        description "display name to use in GUI or CLI";
      }
      leaf sst {
        type at:sst;
        description "Slice/Service type";
      }
      leaf sd {
        type at:sd;
        description "Slice differentiator";
      }
      container device {
        description "Per-device QOS Settings";
        container mbr {
          description "Maximum bitrate";
          leaf uplink {
            type at:bitrate;
            units bps;
            description "Per-device mbr uplink data rate in mbps";
          }
          leaf downlink {
            type at:bitrate;
            units bps;
            description "Per-device mbr downlink data rate in mbps";
          }
        }
      }
      container slice {
        description "Per-Slice QOS Settings";
        container mbr {
          description "Maximum bitrate";
          leaf uplink {
            type at:bitrate;
            units bps;
            description "Per-Slice mbr uplink data rate in mbps";
          }
          leaf downlink {
            type at:bitrate;
            units bps;
            description "Per-Slice mbr downlink data rate in mbps";
          }
        }
      }      
      leaf traffic-class {
        type leafref {
          path "/tc:traffic-class/tc:traffic-class/tc:id";
        }          
        description
          "Link to traffic class";
      } 
      leaf description {
        type at:description;
        description "description of this vcs template";
      }
    }
  } 
}


5.3.4 其他模型


上述介绍参考了其他模型,我们在此不做全面描述。其中包括 IP-Domain,指定 IP 和 DNS 设置,以及 UPF,指定用户平面功能(SD-Core 的数据平面组件),代表连接服务的特定实例转发数据包。UPF 模型是必要的,因为一个 Aether 部署可以运行许多 UPF 实例。有两种不同的实现方式(一种是作为服务器上的微服务运行,另一种是作为加载到交换网络中的 P4 程序运行),而且在任何时候都可以实例化多个基于微服务的 UPF,每个都隔离不同的流量。


延伸阅读:

L. Peterson, et al. Software-Defined Networks: A Systems Approach. November 2021.


5.4 重温 GitOps


正如我们在第四章末尾所做的那样,重温如何区分配置状态和控制状态的问题是有意义的,生命周期管理(和它的配置存储库)负责前者,而运行时控制(和它的键值存储)负责后者。现在我们已经更详细的了解了运行时控制子系统,很明显,关键因素是访问和更改该状态是否需要通过编程接口(加上访问控制机制)。


云运营商和 DevOps 团队完全有能力将配置变化签入配置存储库中,这可能会使人们倾向于将所有在配置文件中指定的状态视为生命周期管理的配置状态。增强的配置机制的可用性,如 Kubernetes Operators,使这种诱惑力更大。但是,任何可能被运维人员以外的人触及的状态,包括企业 IT 管理员和运行时控制应用程序,都需要通过定义明确的 API 来访问。给予企业设置隔离和 QoS 参数的能力是 Aether 的一个说明性例子。从一组模型中自动生成 API 是实现这种控制接口的一个有吸引力的方法,不考虑其他原因的话,至少它迫使接口定义与底层实现解耦(用适配器来弥补这个差距)。


在后一点上,我们很容易想象一种运行时控制操作的实现,包括将配置变更签入配置存储库中并触发重新部署。认为这样的方法是优雅的还是笨拙的这是一个品味问题,但如何做出这样的工程决策,很大程度上取决于后端组件的实现方式。例如,如果配置变更需要重新启动容器,那么可能没有什么选择。但理想情况是,微服务实现有自己明确的管理接口,可以被初始化时的操作者(启动初始化组件)或控制时的适配器(在运行时改变组件)调用。


对于与资源相关的操作上,如响应用户请求创建 Slice 或激活边缘服务而启动额外的容器,类似的实施策略是可行的。Kubernetes API 可以从 Helm(在启动时初始化微服务)或从运行时控制适配器(在运行时添加资源)调用。剩下的挑战是决定哪个子系统维护该状态的权威副本,并确保该决定作为系统的不变性而被强制执行<sup>[2]</sup>。这样的决策通常是根据情况而定的,但我们的经验是,使用运行时控制作为唯一真实来源是一个可靠的方法。


[2] 还可以维护状态的两个权威副本,并实现保持同步的机制。这种策略的困难在于如何避免绕过同步机制的后门访问。


当然,硬币有两面。提供配置参数的运行时控制也很有诱惑力,在一天结束的时候,只有云运维人员需要能够更改这些参数。配置 RBAC(例如,添加组并定义允许给定组访问哪些对象)是一个示例。除非有令人信服的理由向最终用户开放这样的配置决策,否则在配置存储库中维护 RBAC 相关配置状态(即 OPA 规范文件),在生命周期管理的权限下,是完全有意义的。


这些示例说明了运行时控制接口的核心价值主张,即扩展操作,让终端用户和闭环控制程序直接控制系统,而不需要运维团队充当中介。

目录
相关文章
|
存储 运维 Kubernetes
深入浅出边缘云 | 2. 架构
深入浅出边缘云 | 2. 架构
342 0
深入浅出边缘云 | 2. 架构
|
边缘计算 容器
阿里云最新产品手册——阿里云核心产品——边缘节点服务ENS ——边缘容器
阿里云最新产品手册——阿里云核心产品——边缘节点服务ENS ——边缘容器自制脑图
145 1
|
存储 运维 Kubernetes
深入浅出边缘云 | 1. 概述(下)
深入浅出边缘云 | 1. 概述(下)
238 0
深入浅出边缘云 | 1. 概述(下)
|
存储 运维 监控
深入浅出边缘云 | 5. 运行时控制(上)
深入浅出边缘云 | 5. 运行时控制(上)
606 0
深入浅出边缘云 | 5. 运行时控制(上)
|
存储 运维 Kubernetes
深入浅出边缘云 | 3. 资源配置(下)
深入浅出边缘云 | 3. 资源配置(下)
197 0
深入浅出边缘云 | 3. 资源配置(下)
|
网络协议 JavaScript 应用服务中间件
深入浅出边缘云 | 3. 资源配置(上)
深入浅出边缘云 | 3. 资源配置(上)
467 0
深入浅出边缘云 | 3. 资源配置(上)
|
存储 Kubernetes 监控
深入浅出边缘云 | 4. 生命周期管理(上)
深入浅出边缘云 | 4. 生命周期管理(上)
169 0
深入浅出边缘云 | 4. 生命周期管理(上)
|
存储 运维 Kubernetes
深入浅出边缘云 | 4. 生命周期管理(下)
深入浅出边缘云 | 4. 生命周期管理(下)
262 0
深入浅出边缘云 | 4. 生命周期管理(下)
|
运维 监控 Kubernetes
深入浅出边缘云 | 1. 概述(上)
深入浅出边缘云 | 1. 概述(上)
211 0
|
传感器 边缘计算 物联网
边缘网关树莓派最佳实践| 学习笔记
快速学习边缘网关树莓派最佳实践
387 0