打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
TOSCA简介 | 懒程序员改变世界

TOSCA(Topology and Orchestration Specification for Cloud Applications)是由OASIS组织制定的云应用拓扑编排规范。通俗地说,就是制定了一个标准,用来描述云平台上应用的拓扑结构。目前支持XML和YAML,Cloudiy的蓝图就是基于这个规范而来。这个规范比较庞大,本文尽量浓缩了TOSCA的YAML版前两章,以便用尽量少的时间了解尽量多的规范内容。

简介

TOSCA的基本概念只有两个:节点(node)和关系(relationship)。节点有许多类型,可以是一台服务器,一个网络,一个计算节点等等。关系描述了节点之间是如何连接的。举个栗子:一个nodejs应用(节点)部署在(关系)名为host的主机(节点)上。节点和关系都可以通过程序来扩展和实现。

目前它的开源实现有OpenStack (Heat-Translator,Tacker,Senlin),Alien4Cloud,Cloudify等。

示例

Hello World

首先登场的是广大程序猿和攻城狮们都喜闻乐见的Hello World,但是其实里面并没有Hello World,只是比较简单而已。先看下面这段描述文件:

tosca_definitions_version: tosca_simple_yaml_1_0description: 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_definitions_version和描述信息description以外,就是这个topology_template了。这里我们看到有一个名为my_server的节点,它的类型是tosca.nodes.Compute。这个类型预置了两个capabilities信息,一个是host,定义了硬件信息;另一个是os,定义了操作系统信息。

输入输出

再看看下面这个描述文件:

topology_template:  inputs:    cpus:      type: integer      description: Number of CPUs for the server.      constraints:        - valid_values: [ 1, 2, 4, 8 ]  node_templates:    my_server:      type: tosca.nodes.Compute      capabilities:        host:          properties:            num_cpus: { get_input: cpus }            mem_size: 2048  MB            disk_size: 10 GB  outputs:    server_ip:      description: The private IP address of the provisioned server.      value: { get_attribute: [ my_server, private_address ] }

这里的inputsoutputs分别定义了输入和输出。输入的cpus是在1,2,4和8中的一个整数,而输出的server_ip就是my_server这个节点的private_address也就是私有IP地址。另外一点是TOSCA提供了一些内置函数,在上面这个文件中使用了get_inputget_attribute。输入参数可以通过get_input被使用。

安装软件

第三个描述文件如下:

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:        # 略

我们看到了一个新的节点类型:tosca.nodes.DBMS.MySQL。这个类型允许接收root_passwordport的参数。在requirements里定义了mysql这个节点需要被安装到db_server这个节点上,这就是“关系”。如果只想表明依赖,比如说service_a依赖于service_b,也可以直接用- dependency: service_b来描述。上面文件的拓扑结构如下图:

初始化数据库

第四个描述文件如下:

  node_templates:    my_db:      type: tosca.nodes.Database.MySQL      properties:        name: { get_input: database_name }        user: { get_input: database_user }        password: { get_input: database_password }        port: { get_input: database_port }      artifacts:        db_content:          file: files/my_db_content.txt          type: tosca.artifacts.File      requirements:        - host: mysql      interfaces:        Standard:          create:            implementation: db_create.sh            inputs:              db_data: { get_artifact: [ SELF, db_content ] }    mysql:      type: tosca.nodes.DBMS.MySQL      properties:        root_password: { get_input: mysql_rootpw }        port: { get_input: mysql_port }      requirements:        - host: db_server    db_server:      # 略

这里的tosca.nodes.Database.MySQL表示一个MySQL数据库的实例。在artifactsdb_content里指定了一个文本文件,而这个文件将被interfaces里的Create所用,为db_create.sh脚本提供数据。Standard表示生命周期,可能会包含configurestartstop等各种操作,而db_create.sh本身是对tosca.nodes.Database.MySQL提供的默认create操作的一个重写。如下图:

两层应用

再来看看第五个描述文件:

  node_templates:    wordpress:      type: tosca.nodes.WebApplication.WordPress      properties:        context_root: { get_input: context_root }        admin_user: { get_input: wp_admin_username }        admin_password: { get_input: wp_admin_password }        db_host: { get_attribute: [ db_server, private_address ] }      requirements:        - host: apache        - database_endpoint: wordpress_db      interfaces:        Standard:          inputs:            db_host: { get_attribute: [ db_server, private_address ] }            db_port: { get_property: [ wordpress_db, port ] }            db_name: { get_property: [ wordpress_db, name ] }            db_user: { get_property: [ wordpress_db, user ] }            db_password: { get_property: [ wordpress_db, password ] }      apache:      type: tosca.nodes.WebServer.Apache      properties:        # 略      requirements:        - host: web_server    web_server:      type: tosca.nodes.Compute      # 略    wordpress_db:      type: tosca.nodes.Database.MySQL      # 略    mysql:      type: tosca.nodes.DBMS.MySQL      # 略    db_server:      type: tosca.nodes.Compute      # 略

这个文件描述了一个很常见的拓扑结构:mysql里有一个wordpress_db,运行在db_server上;apache部署了一个wordpress,运行在web_server上。wordpress需要wordpress_db

关系定制化

第六个描述文件:

  node_templates:    wordpress:      type: tosca.nodes.WebApplication.WordPress      properties:        # 略      requirements:        - host: apache        - database_endpoint:            node: wordpress_db            relationship: my.types.WordpressDbConnection    wordpress_db:      type: tosca.nodes.Database.MySQL      properties:        # 略      requirements:        - host: mysql  relationship_templates:    my.types.WordpressDbConnection:      type: ConnectsTo      interfaces:        Configure:          pre_configure_source: scripts/wp_db_configure.sh

这里的关注点是relationship里的my.types.WordpressDbConnection。这是一个自定义的关系,在文件的下半部分描述了详细定义。它实际上是一个ConnectsTo类型,为pre_configure_source操作提供了一个自定义脚本。这个定义也可以单独提出一个文件,就像下面这样:

tosca_definitions_version: tosca_simple_yaml_1_0description: Definition of custom WordpressDbConnection relationship typerelationship_types:  my.types.WordpressDbConnection:    derived_from: tosca.relationships.ConnectsTo    interfaces:      Configure:        pre_configure_source: scripts/wp_db_configure.sh

限定需求资源

再看一个描述文件:

  node_templates:    mysql:      type: tosca.nodes.DBMS.MySQL      properties:        # 略      requirements:        - host:            node_filter:              capabilities:                - host:                    properties:                      - num_cpus: { in_range: [ 1, 4 ] }                      - mem_size: { greater_or_equal: 2 GB }                - os:                    properties:                      - architecture: { equal: x86_64 }                      - type: linux                      - distribution: ubuntu

需要关注的是node_filter。这里并没有指定mysql在哪个节点上启动,但是指定了一些节点信息,只有符合的节点才能够启动它。也可以抽出来做个模板:

  node_templates:    mysql:      type: tosca.nodes.DBMS.MySQL      properties:        # 略      requirements:        - host: mysql_compute    mysql_compute:      type: Compute      node_filter:        capabilities:          - host:              properties:                num_cpus: { equal: 2 }                mem_size: { greater_or_equal: 2 GB }          - os:              properties:                architecture: { equal: x86_64 }                type: linux                distribution: ubuntu

数据库也可以使用:

  node_templates:    my_app:      type: my.types.MyApplication      properties:        admin_user: { get_input: admin_username }        admin_password: { get_input: admin_password }        db_endpoint_url: { get_property: [SELF, database_endpoint, url_path ] }               requirements:        - database_endpoint:            node: my.types.nodes.MyDatabase            node_filter:              properties:                - db_version: { greater_or_equal: 5.5 }

上面指定了数据库的版本。也可以抽出来做个模板:

  node_templates:    my_app:      type: my.types.MyApplication      properties:        admin_user: { get_input: admin_username }        admin_password: { get_input: admin_password }        db_endpoint_url: { get_property: [SELF, database_endpoint, url_path ] }               requirements:        - database_endpoint: my_abstract_database    my_abstract_database:      type: my.types.nodes.MyDatabase      properties:        - db_version: { greater_or_equal: 5.5 }

节点模板替换

再看一个描述文件:

  node_templates:    web_app:      type: tosca.nodes.WebApplication.MyWebApp      requirements:        - host: web_server        - database_endpoint: db    web_server:      type: tosca.nodes.WebServer      requirements:        - host: server    server:      type: tosca.nodes.Compute      # 略    db:      # 这是一个抽象节点      type: tosca.nodes.Database      properties:        user: my_db_user        password: secret        name: my_db_name

这里的db是一个抽象节点,可以被下面的描述文件所替换:

topology_template:  inputs:    db_user:      type: string    # 略  substitution_mappings:    node_type: tosca.nodes.Database    capabilities:      database_endpoint: [ database, database_endpoint ]  node_templates:    database:      type: tosca.nodes.Database      properties:        user: { get_input: db_user }        # 略      requirements:        - host: dbms    dbms:      type: tosca.nodes.DBMS      # 略    server:      type: tosca.nodes.Compute      # 略

这里的database_endpoint是由database节点提供的database_endpoint。两个文件联系起来看,表明了上面的web_app不需要管db是什么样子的,有什么拓扑结构,它关心的只是database_endpoint。而下面由databasedbmsserver三个节点组成的模板正好可以提供database_endpoint,从而替换掉db这个抽象节点。另外,这样的替换也支持嵌套。

节点模板组

再看一个描述文件:

  node_templates:    apache:      type: tosca.nodes.WebServer.Apache      properties:        # 略      requirements:        - host: server    server:      type: tosca.nodes.Compute        # 略  groups:    webserver_group:      type: tosca.groups.Root      members: [ apache, server ]  policies:    - my_anti_collocation_policy:        type: my.policies.anticolocateion        targets: [ webserver_group ]        # 可以一起处理

这个例子表明了apacheserver应该是一组的关系。这样它们就可以一起被处理,比如说伸缩。

YAML宏

下面这个描述文件使用了宏来避免重复:

dsl_definitions:  my_compute_node_props: &my_compute_node_props    disk_size: 10 GB    num_cpus: 1    mem_size: 2 GBtopology_template:  node_templates:    my_server:      type: Compute      capabilities:        - host:            properties: *my_compute_node_props    my_database:      type: Compute      capabilities:        - host:            properties: *my_compute_node_props

传参

先看一个描述文件:

  node_templates:     wordpress:      type: tosca.nodes.WebApplication.WordPress      requirements:        - database_endpoint: mysql_database      interfaces:        Standard:          inputs:            wp_db_port: { get_property: [ SELF, database_endpoint, port ] }          configure:            implementation: wordpress_configure.sh                       inputs:              wp_db_port: { get_property: [ SELF, database_endpoint, port ] }

这个例子有两个inputs,前者指的是为所有操作都声明一个变量,后者指的是为configure这个操作声明一个变量。再看下一个文件:

  node_templates:     frontend:       type: MyTypes.SomeNodeType          attributes:         url: { get_operation_output: [ SELF, Standard, create, generated_url ] }       interfaces:         Standard:           create:             implementation: scripts/frontend/create.sh          configure:             implementation: scripts/frontend/configure.sh             inputs:               data_dir: { get_operation_output: [ SELF, Standard, create, data_dir ] }

在这个例子里有两个get_operation_output,前者指的是将create操作的环境变量generated_url设置到url里,后者是将data_dir传递给configure操作。

取动态值

最后一个描述文件:

node_types:  ServerNode:    derived_from: SoftwareComponent    properties:      notification_port:        type: integer    capabilities:      # 略  ClientNode:    derived_from: SoftwareComponent    properties:      # 略    requirements:      - server:          capability: Endpoint          node: ServerNode           relationship: ConnectsTotopology_template:            node_templates:    my_server:      type: ServerNode       properties:        notification_port: 8000    my_client:      type: ClientNode      requirements:        - server:            node: my_server            relationship: my_connection  relationship_templates:    my_connection:      type: ConnectsTo      interfaces:        Configure:          inputs:            targ_notify_port: { get_attribute: [ TARGET, notification_port ] }            # 略

这个例子里,类型为ClientNodemy_clientmy_connection关系的Configure操作上需要notification_port变量。这样的话,当类型为ServerNodemy_server连接过来时,就能取到它的notification_port变量,并设置到targ_notify_port环境变量里。有一点值得注意的是,真实的notification_port可能是8000,也可能不是。所以在这种情况下,不用get_property,而用get_attribute函数。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
本地XAMPP搭建和安装Wordpress | 帕兰映像
10 个实用 Shell 脚本,珍藏版
Wordpress数据库结构全解析
在GodaddyMF赠送的Win空间上面安装WordPress – AspxHtml学习分享网
MySQL5.6与MySQL5.7安装的区别
推荐一款开源的接口测试练手实战项目!
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服