5G时代边缘计算:LF Edge生态与EdgeGallery技术详解
上QQ阅读APP看书,第一时间看更新

2.2 边缘计算架构设计原则

2.2.1 模型驱动

在边缘计算环境中,硬件与资源受限,导致需要差异化对待来自不同厂商的软硬件产品与服务;另外,极简运维又要求服务应标准化和模板化,尤其是服务快速部署和弹性运维是开展规模化边缘计算服务的前提。这就要求应对典型边缘计算场景、算力、带宽等资源进行标准化和模板化设计,实现快速复制和拓展。因此边缘计算系统应该是个模型驱动的系统。

介绍模型驱动前,需要介绍一下什么是模型。模型是对“事物”的一种抽象化表达,即从特定角度对系统进行描述,省略部分不重要的细节,聚焦感兴趣的特性。

模型驱动在软件开发领域有多种表达方式,比如MBD(Model Based Development,基于模型的开发)、MDD(Model Driven Development,模型驱动开发)、MDA(Model Driven Architecture,模型驱动架构)。模型驱动的核心是从模型中生成代码和其他开发过程中的组件,在解决领域问题的同时,提高生产效率。比如,发生需求变更时,软件设计不变或变更较少(模型不变)。与之对应的传统开发方式则是硬编码(即使用编程语言C、C++、Java、Python等编写代码)。但从本质上来说,只要是进行变更,就肯定需要某人/某个应用在某个地方进行某些修改,这样才能让变更真正生效。模型驱动的修改与硬编码方式的修改真正的差异在于谁负责修改、改什么(包括在哪修改)和影响多大。对于硬编码方式而言,所有变更都需要由原软件提供者来修改,且需要在实际产品代码上重新进行编译、发布、打包等操作,再经过商业交付流程提供给使用者。而使用者在此过程中只能等待,等待供应商提供修改后的版本,然后再经过入网测试、升级部署等流程才能在实际网络中使用。传统修改方式不仅代价大、周期长(一般以月为单位),而且多数情况下,产品升级还可能需要重启系统,影响较大。如果整个过程中发生任何问题,包括理解上的差异,很可能需要从头再来。

而对于模型驱动的架构,在进行变更时,平台开发者(比如边缘计算产品的供应商)不需要参与代码修改,平台本身也不需要停机,不需要进行重新编译、发布等开发过程,使用者通过修改外部(相对平台/边缘计算产品自身代码而言)的模型文件(TOSCA或YANG等)或插件(可能包括JavaScript、Python等动态语言)即可动态变更,这一开发过程可称为模型驱动的设计。当然,为了实现这一点,需要提前定义一些内容:模型的格式(模型文件应该如何描述)、模型生效的流程(模型如何加载、生效,如果中间出现错误如何处理等)。多数模型驱动的架构还会定义一些预定制的元模型或领域模型示例,以简化学习流程,加速在指定领域中的应用。

在本书中,模型驱动是指,系统支持在不修改自身框架代码的前提下,通过对模型进行组合/变更(新增、删除或修改),进而实现业务变更。上述这些一般通过修改某些脚本,或动态加载部分插件、驱动来实现。

注意

模型驱动并不意味着业务变更完全不需要修改代码,只是不需要修改系统自身的框架代码,即修改分成两部分:一部分是对平台的修改,尽可能少甚至不需要修改;另一部分是(在多数场景下)第三方(非系统开发人员)对模型进行组合与修改(也可能包括一些脚本的开发)。

1. 常见模型

常见模型包括信息模型、数据模型、对象实例(物理数据模型)以及元模型等,这些模型分别表示从现实世界到信息世界的不同层次的抽象。

信息模型(Information Model,IM):包括业务模型和概念模型,是对现实世界中真实事物的描述,不涉及具体软件实现,是根据现实世界中具体事物定义出的抽象概念(对象名称),例如员工、合同、客户、网络、站点、设备等,也包括这些抽象概念之间的关系,比如站点中“包含”设备,而交换机“属于”某种设备等。

数据模型(Data Model,DM):是对业务模型或概念模型的进一步分解和细化,包括所有的实体(抽象代表一类对象,员工代表所有具体的员工)和关系(实体间的关系)。需要确定每个实体的属性,定义每个实体的主键,指定实体的外键,需要进行范式处理。一般在软件设计中定义对应的数据/对象结构,比如员工包括工号—字符Char(8)、姓名—最长20个字符的可变字符串varchar(20)、年龄—数字integer、出生日期—日期date等。

对象实例:用于在数据模型基础上定义每个具体的独立对象,比如某个具体员工A的工号是00123456,则员工A就是一个实例。

元模型(Meta Data):即模型的模型,是模型驱动设计中更高层次的抽象。一般针对特定领域的模型定义抽象概念(元模型),并用其构建该领域中的具体数据模型。比如在网络领域,IPV4(形如10.10.10.10的32位的对象)或IPV6(形如:1:123::ABCD:0:1/96的128位的对象)就可视为元模型,用它们的组合可表示新的模型对象,比如VPN(每个接入点都可以是IPV4/IPV6的IP地址)。

目前很多领域都有自己特有的模型和模型语言。下面就一一介绍。

2. 常见模型语言

(1)XML

XML(eXtensible Markup Language,可扩展的标记语言),1998年2月由W3C(World Wide Web Consortium,万维网联盟)正式批准定义的标准且通用的标记语言。“标记”指计算机所能理解的信息符号,通过标记,计算机之间可以处理包含各种信息的文档。在定义这些标记时,既可以选择国际通用的标记语言,比如HTML(Hyper Text Markup Language,超文本标记语言),也可以使用像XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是由SGML(The Standard Generalized Markup Language,标准通用标记语言)简化修改而来的。XML是一套定义语义标记的规则,这些标记将文档分成很多部件并对这些部件加以标注,即定义了用于定义其他与特定领域中有关的、语义的、结构化的标记语言的句法语言(元标记语言)。

直白解释就是,XML是一种规则,其把一个文档划分为不同的层次或部分,并对这些层次或部分做好标记。这个文档支持不同领域,比如文学、物理、化学、音乐等。不同领域的文档可定义特有的领域语言(也用XML定义)。XML文档的字符分为标记与内容两类。标记通常以<开头,以>结尾;或者以字符&开头,以;结尾。

XML有如下几个特征:

□ 内容与形式分离,XML的设计宗旨是传输数据和存储数据,而不是显示数据。

□ 良好的可扩展性,标签没有被预定义,需要自行定义标签。

□ 具有自我描述性。

□ 遵循严格的语法要求。

□ 便于不同系统之间进行信息传输,是W3C的推荐标准。

一个简单例子如下:


<student>
    <age>19</age>
    <name>John</name>
    <school> Wuhan University</school>
</student>

以上XML脚本描述的是一个学生,记录了学生如下信息:年龄、姓名、学校。其中的<student>学生和<age>年龄等即为自定义标签(tag)。具体如图2-1所示。

图2-1 学生模型示意

(2)XML Schema

XML虽然可以描述一个对象(通过自定义标签),如上例所示,但对于计算机处理来说这是不够的,上述示例只能说是“语法正确”(术语称为well-formed XML),但不一定“合法”(术语称之为validating XML)。

比如年龄这个标签,在计算机处理中还需更进一步严格定义,数据类型是一个“数值”,而不是字符串。显然,说年龄是10(岁)是合法的(一个数值),而把年龄说成一个字符串“OK”或“非常大”,则是非法的。

为了约束一个字段或者说为了约束XML的类型,就有了XML Schema,它是一套W3C标准,即用于XML的模式定义语言,定义XML标记规范。

以下是一个对年龄进行约束的例子。年龄这个标签(XML也称为元素,element)有如下定义/约束:

□ value必须是整型(xs:integer);

□ 取值范围必须是7~50。


<xs:element name="age">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="7"/>
            <xs:maxInclusive value="30"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

(3)YAML

YAML(Yet Another Markup Language,另一种标记语言)是一种以数据为中心的标记语言,是一种人性化的数据格式定义语言。数据组织主要依靠的是空白、缩进、分行等结构,相比XML其有如下优点:

□ 可读性好;

□ 和脚本语言的交互性好;

□ 使用实现语言的数据类型;

□ 有一致的信息模型;

□ 易于实现。

比如上面那个学生的例子,用YAML语言可表述为如下形式。


- student:
    name: John
    age: 19
    school:  Wuhan University
    friends:              # YAML用缩进后的横杠‘-’表示列表项的多个取值
      - 'mike'
      - 'Tom'

由于YAML有较好的可扩展性与可读性,且比XML编码效率更高,故在特定场景下具备明显优势。比如常用的动态语言(Python、Ruby等)就支持用YAML定义的数据结构与数据类型。一些常见的IT工具也使用YAML来定义模板,比如Heat、Cloud Formation、Saltstack、Puppet、Chef。

一个环境描述的Heat实例(包括对Nova、Database、Chef的定义)如下:


# Environment
environment: environment_1000_stag
    name: Rackspace Cloud US - staging
    Providers:
        Nova:
            id: nova
            vendor: rackspace
            provides:
            - compute: Linux
            - compute: windows
            constraints:
            - region: ORD
        Database:
            id: Database
            vendor: rackspace
            provides:
            - Database: MySQL
        Chef:
            id: chef-Server
            vendor: opscode
            provides:
            - Application: http 
            - Database: MySQL

(4)YANG

YANG是IETF在RFC 6020中定义的用于网络配置的数据模型描述语言,可支持NETCONF接口协议,实现网络配置的标准化,是一种DSL(领域特有语言)。

注意

NETCONF(Network Configuration Protocol)是一个网络配置管理协议,是由IETF标准组织定义的一套管理网络设备的机制。用户可使用这套机制增加、修改、删除网络设备的配置,获取网络设备的配置和状态信息。

YANG与XSD(XML Schema Definition)基本等价,也就是说YANG是一种Schema定义语言,而不是像XML或YAML一样用于数据的传输和存储。

从设备维护的角度,YANG将数据的层次结构模型化为一棵树,树中每个节点都有名称且有一个值或一个子节点集。YANG给节点提供了清晰简明的描述,同样提供了节点间的交互。相比XML Sechema,YANG语言定义的数据模型具有可读性好、简单易懂、可扩展的特点。当前YANG已在设备配置领域被普遍采用,IETF、ONF等标准组织都要求提交的模型用YANG来写。其他组织(如Openconfig、OpenDayLight等)也普遍支持YANG。

用YANG定义一个RPC(远程进程调用)的示例代码如下所示。


rpc activate-software-image {
    input {
        leaf image-name {
            type string;
        }
    }
    output {
        leaf status {
            type string;
        }
    }
}

上述示例表示一个activate-software-image的远程调用方法,输入是一个string参数image-name,输出是string类型的status。

(5)TOSCA

TOSCA(Topology and Orchestration Specification for Cloud Applications)是一种数据建模描述语言,一种面向云计算环境中的应用拓扑和编排描述语言,由OASIS组织(https://www.oasis-open.org/)制定,目前支持YAML和XML实现。

TOSCA基本概念有两个—节点(node)和关系(relationship),且都可通过程序来扩展,同时TOSCA规范中也支持Plan(即Workflow工作流文件)。

节点预定义了很多基础类型,包括云基础设施中常用的计算节点、网络节点、数据库节点等。

关系定义了节点之间的关联关系,常见关系类型如下。

DependsOn(依赖):表示节点间的顺序依赖关系,一般影响实例化过程中的创建顺序,比如A节点依赖B节点,则在创建A对象前须先创建B。

HostedOn(运行):比如“MySQL数据库”与“计算机”的关系就是HostedOn的关系,即数据库运行在计算机上。

ConnectsTo(连接):表示连接关系。

TOSCA面向云计算环境中的应用拓扑和编排场景预定义了一些属性,因此一般认为较适合用于满足以下需求:

□ 自动化部署和管理软件。

□ 应用生命周期(安装、扩容、卸载等)管理方案的可移植性(注意:不是应用本身的可移植性)。

□ 组件之间的互操作性和重用性。

注意

OpenStack中的Heat子模块也是基于TOSCA标准的。

YANG、TOSCA都具备较强的扩展能力。笔者认为,语言本身没有本质区别,也不存在谁一定更适合某领域的说法,这更多是不同领域使用习惯的问题。而且IETF、OASIS等组织也都在不断扩展这两种语言。比如,NFV领域的VNFD就是用TOSCA来描述文件的(可以是YAML或XML格式),描述项包括安装软件过程中都有哪些组件、组件之间有什么依赖关系等。当然,实际运行时还需要TOSCA运行态环境来对TOSCA文件进行读取(分析文件的语法、语意)和解释执行(进行具体的软件安装、配置工作)。

下面看一个TOSCA描述文件(称为Service Template)示例。该示例包括一个名为my_Server的节点,类型是TOSCA.nodes.Compute,该类型预置了两个capabilities(能力)信息,一个是host,定义了硬件信息;另一个是os,定义了操作系统信息。

该示例代码如下:


TOSCA_definitions_version: TOSCA_simple_YAML_1_0
description: Template for deploying a single Server with predefined properties.
topology_Template:
    node_Templates:
        my_Server:
            type: TOSCA.nodes.Compute
            capabilities:
                host:
                    properties:
                        num_cpus: 1
                        disk_size: 10 GB
                        mem_size: 4096 MB
                os:
                    properties:
                        architecture: x86_64
                        type: Linux 
                        distribution: rhel 
                        version: 6.5

TOSCA脚本还可用于表达对输入、输出的建模。比如,以下代码就定义了一个TOSCA.nodes.DBMS.MySQL新节点类型。该类型允许接收root_password和port的参数。在requirements里定义了MySQL这个节点,该节点需要安装到db_Server节点上,这就是“关系”。


topology_Template:
    inputs:
        # 略
    node_Templates:
        MySQL:
            type: TOSCA.nodes.DBMS.MySQL
            properties:
                root_password: { get_input: my_MySQL_rootpw }
                port: { get_input: my_MySQL_port }
            requirements:
                - host: db_Server
        db_Server:
            type: TOSCA.nodes.Compute
            capabilities:
                # 略