记一次饱经挫折的ROS部署经历

本文涉及的产品
云服务器 ECS,u1 4核8GB 1个月
云服务器 ECS,u1 4核16GB 1个月
云服务器ECS,u1 2核4GB 1个月
简介: 阿里云资源编排服务ROS(Resource Orchestration Service)是一个基础设施即代码(IaC)工具,用于自动化部署和管理阿里云上的多种资源。ROS通过JSON或YAML格式的模板来定义资源栈,模板中包括资源类型、参数、依赖关系等,简化了云资源的创建和更新流程。

前言

最近在参加的几个项目测评里,我发现“一键部署”这功能真心好用,省下了不少宝贵时间和力气,再加上看到阿里云现在有个开源上云的活动。趁着这波热潮,今天就聊聊怎么从头开始,一步步搞定阿里云的资源编排服务(ROS),希望能对刚接触这块的朋友有点帮助。咱们一块儿边学边实践,让云上的项目部署变得更简单高效。

资源编排

阿里云的资源编排服务(Resource Orchestration Service,简称ROS)是一种基础设施即代码(IaC)服务,它允许用户通过编写模板来定义和管理云上的各种资源。这些资源包括但不限于ECS( Elastic Compute Service)实例、RDS(Relational Database Service)数据库实例、SLB(Server Load Balancer)负载均衡器等。ROS的核心价值在于自动化部署及运维,它能自动处理资源的创建、配置及之间的依赖关系,从而极大地简化了云计算资源的管理过程。

在ROS中,用户根据ROS提供的模板规范,使用JSON或YAML格式编写资源栈模板。模板中不仅定义了所需的资源类型和数量,还明确了资源之间的逻辑依赖,确保资源按正确的顺序被创建和配置。这样,无论是新建环境、更新配置还是进行大规模的架构调整,都可通过执行模板脚本来实现,保证了操作的一致性和可重复性。

资源编排地址如下:https://ros.console.aliyun.com/cn-hangzhou/welcome

image.png

下面我们还是以实战为导向,从最基础的ROS脚本开始看起,一步步拆解。

ROS模板

首先我们先看一下ROS模板结构及参数说明。

{
   
  "ROSTemplateFormatVersion" : "2015-09-01",

  "Description" : "模板描述信息,可用于说明模板的适用场景、架构说明等。",
  "Metadata" : {
   
    // 关于模板的元数据信息,例如存放用于可视化的布局信息。
  },
  "Parameters" : {
   
    // 定义创建资源栈时,用户可以定制化的参数。
  },

  "Mappings" : {
   
    // 定义映射信息表,映射信息是一种多层的Map结构。
  },

  "Conditions": {
   
    // 使用内部条件函数定义条件。这些条件确定何时创建关联的资源。
  },

  "Resources" : {
   
    // 所需资源的详细定义,包括资源间的依赖关系、配置细节等。
  },

  "Outputs" : {
   
    // 用于输出一些资源属性等有用信息。可以通过API或控制台获取输出的内容。
  }
}

【参数说明】:

  • ROSTemplateFormatVersion必选,ROS支持的模板版本号,当前版本号:2015-09-01。

  • Description:可选,模板的描述信息。可用于说明模板的适用场景、架构说明等。通常情况下,对模板进行详细描述,有利于用户理解模板的内容。

  • Metadata:可选,模板编写者可以使用Metadata来存放与模板相关的元数据信息,内容可以为JSON格式。

  • Parameters:可选,定义创建资源栈时,模板用户可以定制化的参数。通常,模板的编辑者会把ECS的规格设计成一个参数。参数支持默认值。使用参数可以增强模板的灵活性,提高复用性。使用模板创建资源栈时,可以根据实际的评估结果来选择合适的规格。更多详细信息,请参见参数(Parameters)。

  • Mappings:可选,Mappings定义了一个多层的映射表,可以通过Fn::FindInMap函数来选择Key对应的值,或根据不同的输入参数值作为Key来查找映射表。例如,您可以根据Region不同,自动查找Region-镜像映射表,从而找到适用的镜像。更多详细信息,请参见映射(Mappings)。

  • Conditions:可选,Conditions使用Fn::And、Fn::Or、Fn::Not、Fn::Equals定义条件。多个条件之间使用半角逗号(,)隔开。在创建或更新资源栈时,系统先计算模板中的所有条件,然后再创建资源。创建与true条件关联的所有资源,忽略与false条件关联的所有资源。更多详细信息,请参见条件(Conditions)。

  • Resources:可选,用于详细定义使用该模板创建的资源栈所包含的资源,包括资源间的依赖关系、配置细节等。更多详细信息,请参见资源(Resources)。

  • Outputs:可选,用于输出一些资源属性等有用信息。可以通过API或控制台获取输出的内容。更多详细信息,请参见输出(Outputs)。

通过上面可以看出最核心、最关键的部分其实是ParametersResources , 因为这两个决定了模板设计者定义一系列可配置的参数和将要创建或管理的所有云资源及其配置,是直接涉及资源创建和配置的核心逻辑参数。

下面我们来创建第一个案例。

基于ROS模板创建VPC

在创建之前,我们需要先知道ROS支持的所有资源类型,这里需要查看资源类型索引

image.png

如果在这个列表中没有出现的产品,就是暂时不支持采用ROS来创建的,这是需要明确的第一点。

如上图,我们看到VPC是支持使用ROS来创建的,接下来我们再开展第二步,点击这个蓝色链接位置,查看它的详细语法、属性及返回值。

image.png

到这里,我们基本就明白它的语法格式及书写方式了,下面第三步,上手开写。

回到资源编排界面,点击【我的模板】→【创建模板】,进去ROS在线编辑界面开始编辑。

image.png

初始的模板如下,我们选择为yaml格式来进行编写。

image.png

下面咱们一行行的分析:

ROSTemplateFormatVersion

默认版本号,这里不用修改,直接过

ROSTemplateFormatVersion: '2015-09-01'

Description

这里不是必填,不过也可以填一下,暂且起名为my first VPC-test

Description: my first VPC-test

Parameters

这里到重头戏了,几乎所有的可定制化参数都是在这里修改的,在比较复杂的ROS脚本中几乎都会用到,但是这里为了方便演示,也选择暂时不填写,等下后面测试时再填写后对比。

Parameters: {
   }

Resources

这里是用来详细定义使用该模板创建的资源栈所包含的资源,包括资源间的依赖关系、配置细节等,是必填项

而其具体的格式,可以看到如下:

image.png

这里我们沿用该格式,并且剔除一些不需要的参数,最终命令如下:

 VPC:
    Type: ALIYUN::ECS::VPC
    Properties:
      VpcName: VPC-test
      CidrBlock: 192.168.0.0/24

这里面就只包含了最基础的CidrBlock(专有网络网段)和VpcName(专有网络名称)。

Mappings、Metadata、Conditions

这里也暂时不涉及,可以直接删除掉。

Outputs

这里用于输出一些资源属性等有用信息,这里我们可以尝试输出一下VPC的ID和关联的虚拟路由器ID

Outputs:
  VPCId:
    Value:
       Fn::GetAtt:
        - VPC
        - VRouterId
  VRouterId:
    Value:
      Fn::GetAtt:
        - VPC
        - VRouterId

参照返回示例如下

image.png

最终ROS的整体脚本如下:

ROSTemplateFormatVersion: '2015-09-01'
Description: my first VPC-test
Resources:
  VPC:
    Type: ALIYUN::ECS::VPC
    Properties:
      VpcName: VPC-test
      CidrBlock: 192.168.0.0/24
Outputs:
  VPCId:
    Value:
       Fn::GetAtt:
        - VPC
        - VRouterId
  VRouterId:
    Value:
      Fn::GetAtt:
        - VPC
        - VRouterId

点击预览,查看资源架构,我们可以看到如图所示的架构:

image.png

确定之后点击保存模板,命名后可在模板空间中查看和直接创建栈:

image.png
image.png

选择失败时回滚,点击创建:

image.png

此时可以看到开始创建资源栈,等待一段时间:

image.png

创建成功后如下图所示:

image.png

点击输出,我们可以看到outputs中设定的输出的关键字

image.png

而假如我们不需要使用了,也可以直接点击删除资源栈:

image.png

以上是手动编写脚本的流程了,在实际调试中还是有一些复杂的,下面我们就来结合案例,完成这次参赛的ROS部署作品。

基于ROS部署MaxKB

MaxKB

MaxKB是基于LLM大语言模型的知识库问答系统,旨在成为企业的最强大脑。它支持开箱即用,无缝嵌入到第三方业务系统,并提供多模型支持,包括主流大模型和本地私有大模型,为用户提供智能问答交互体验和灵活性。

image.png

另外说一句,我的关于知识库侧测评的文章也已经快写完了,这几个月参加护网有点太累了,几乎没时间来写,抱歉抱歉!

编写ROS 模板

这里我们还是一步步的来,逐步解析。

ROSTemplateFormatVersion

老规矩,不变。

ROSTemplateFormatVersion: '2015-09-01'

Description

因为是参赛的作品,所以我这里也写的详细一点吧,下面也是带上了中英的描述。

Description:
  en: Setting up the large language model-based knowledge base question and answer system, MaxKB, on an ECS (Elastic Compute Service) instance.
  zh-cn: 在ECS实例上搭建大语言模型的知识库问答系统MaxKB。

Parameters

这里涉及到的就比较复杂了,因为此处是必须要进行一些自定义参数设置的,我们进到ECS的语法下面详细查看

说实话,有点吓人,居然这么多!

image.png

我们按照下面这个表格来一一排查:

image.png

ZoneId

这里首先申明ZoneId , 至于为什么先申明ZoneId呢?这是因为区域(Zone)的选择对创建的云资源(如ECS实例、RDS数据库等)有着直接的影响,且下面在申明实例规格时会用到。

ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId

AssociationProperty 说明ZoneId参数与ECS实例的ZoneId属性关联。这意味着在模板中使用此参数的地方,我们所选择的值将会直接应用于创建ECS实例时的可用区选择。这样的设计确保了模板的逻辑与阿里云ECS服务的实际属性紧密集成,提高了模板的准确性和易用性。

InstanceType

ECS实例规格 ,必填项 ,这里需要参考实例规格族。

 InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: recent

同样,这里的 AssociationProperty 是指明参数与ECS实例的InstanceType属性关联;而 AssociationPropertyMetadata 则是表示实例类型的可用性依赖于ZoneId中选择的区域ID,且当用户没有明确指定实例类型时,系统会选择最近常用或推荐的实例类型作为默认选项。

SystemDiskCategory

下面定义ECS实例系统盘的类型,其中,AssociationPropertyMetadata 里面包含了一些元数据来指导和约束系统盘类型的选择:

SystemDiskCategory:
    Type: String
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      LocaleKey: DiskCategory
      ZoneId: ${
   ZoneId}
      InstanceType: ${
   InstanceType}
      AutoSelectFirst: true
      AutoChangeType: false
    Default: cloud_essd

InstancePassword

下面定义了用于登录ECS实例的密码规则,确保了安全性的同时也提供了一定的灵活性:

InstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol
        in).
      zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers,
        ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
          - ${
   SelectInstance}
          - false
    Default:
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true

所以Parameters此处的完整脚本如下:

Parameters:
  ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: recent
  SystemDiskCategory:
    Type: String
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      LocaleKey: DiskCategory
      ZoneId: ${
   ZoneId}
      InstanceType: ${
   InstanceType}
      AutoSelectFirst: true
      AutoChangeType: false
    Default: cloud_essd
  InstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol
        in).
      zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers,
        ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
          - ${
   SelectInstance}
          - false
    Default:
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true

Resources

这里开始创建资源,分析架构所需,涉及产品如下:

VPC

定义一个虚拟私有云(VPC)资源,192.168.0.0/16 指定了VPC的IP地址范围。

Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16

VSwitch

定义一个虚拟交换机(VSwitch)的配置:Ref: ZoneId 表示虚拟交换机将被创建在指定的可用区(Zone)中,这里的ZoneId是一个引用,其实际值需要在模板的参数或映射部分提前定义或通过外部参数传入;Ref: Vpc 指明该虚拟交换机隶属于哪个VPC。这里同样使用了引用,意味着VSwitch将与之前定义的VPC关联。确保在模板中已经定义了VPC资源或者通过参数传递了正确的VPC ID;192.168.0.0/24 定义了虚拟交换机的IP地址范围。

 VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24

SecurityGroup

创建安全组:Ref: Vpc 指定该安全组将被创建在哪个VPC中,这里通过引用之前定义的VPC资源(Vpc),确保安全组与目标VPC正确关联。这一步是必要的,因为每个安全组都必须绑定到一个特定的VPC。

SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc

SecurityGroupIngress_80

定义了入站规则:Ref: SecurityGroup 引用了之前定义的安全组ID,这条入站规则将被添加到该安全组中;0.0.0.0/0 指定任何IP地址(全网段)都可以作为流量的来源,这意味着对于这条规则,不限制访问的来源IP地址;tcp 指定了该规则适用的协议类型,这里是TCP;intranet 表示这条规则仅适用于VPC内部的通信;80/80 定义了允许访问的端口范围,这里只开放了TCP 80端口,通常用于HTTP服务。

SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 80/80

InstanceGroup

定义实例群组:引用上面创建的Vpc、VSwitch和SecurityGroupId实例;指定使用CentOS 7.9的镜像;设置了实例的名称为MaxKB;后面继续引入实例类型、系统盘的类别和密码

InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: centos_7_9
      InstanceName: MaxKB
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory:
        Ref: SystemDiskCategory
      Password:
        Ref: InstancePassword
      IoOptimized: optimized
      MaxAmount: 1

DS_Instances

通过DS_Instances数据源来获取通过InstanceGroup创建的ECS实例列表。

 DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds

InstallMaxKB

这里使用到Formation模板中的ALIYUN::ECS::RunCommand资源类型配置,用于在特定的ECS实例上执行一系列Shell脚本命令。

InstallMaxKB:
Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
          #!/bin/bash
        echo "#########################"
        echo "# Install Docker"
        echo "#########################"
        wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum -y install docker-ce
        systemctl start docker
        systemctl enable docker

        echo "#########################"
        echo "# Install MaxKB"
        echo "#########################"

        yum -y install jq
        DOCKER_DAEMON_JSON="/etc/docker/daemon.json"
        sudo jq --arg registry "$NEW_REGISTRY" '. + { "registry-mirrors": [https://0jt38sli.mirror.aliyuncs.com] }' $DOCKER_DAEMON_JSON > ${
   DOCKER_DAEMON_JSON}.temp && sudo mv ${
   DOCKER_DAEMON_JSON}.temp $DOCKER_DAEMON_JSON
        sudo systemctl daemon-reload
        sudo systemctl restart docker
        docker run -d --name=maxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data 1panel/maxkb

最终,Resources下脚本如下:

Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
  SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 80/80
  InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: centos_7_9
      InstanceName: dify
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory:
        Ref: SystemDiskCategory
      Password:
        Ref: InstancePassword
      IoOptimized: optimized
      MaxAmount: 1
  DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
InstallMaxKB:
Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
       #!/bin/bash
        echo "#########################"
        echo "# Install Docker"
        echo "#########################"
        wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum -y install docker-ce
        systemctl start docker
        systemctl enable docker

        echo "#########################"
        echo "# Install MaxKB"
        echo "#########################"

        yum -y install jq
        DOCKER_DAEMON_JSON="/etc/docker/daemon.json"
        sudo jq --arg registry "$NEW_REGISTRY" '. + { "registry-mirrors": [https://0jt38sli.mirror.aliyuncs.com] }' $DOCKER_DAEMON_JSON > ${
   DOCKER_DAEMON_JSON}.temp && sudo mv ${
   DOCKER_DAEMON_JSON}.temp $DOCKER_DAEMON_JSON
        sudo systemctl daemon-reload
        sudo systemctl restart docker
        docker run -d --name=maxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data 1panel/maxkb

Outputs

定义了名为 MaxKBUrl 的输出项,用于提供MaxKB服务的默认访问地址:

Outputs:
  MaxKBUrl:
    Description: MaxKB default address.
    Value:
      Fn::Sub:
      - http://${
   IP}
      - IP:
          Fn::Jq:
          - First
          - if .[0].PublicIpAddress != [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddress
            end
          - Fn::GetAtt:
            - DS_Instances
            - Instances

Metadata

添加了一个标签来描述此模板的功能和背景,按照比赛要求是需要采用“手机尾号-模板用途”来编写。

Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
    - acs:developer:gitee:0147-在ECS实例上搭建大语言模型的知识库问答系统MaxKB。

整体脚本

ROSTemplateFormatVersion: '2015-09-01'
Description:
  en: Setting up the large language model-based knowledge base question and answer system, MaxKB, on an ECS (Elastic Compute Service) instance.
  zh-cn: 在ECS实例上搭建大语言模型的知识库问答系统MaxKB。
Parameters:
  ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: recent
  SystemDiskCategory:
    Type: String
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      LocaleKey: DiskCategory
      ZoneId: ${
   ZoneId}
      InstanceType: ${
   InstanceType}
      AutoSelectFirst: true
      AutoChangeType: false
    Default: cloud_essd
  InstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol
        in).
      zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers,
        ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
          - ${
   SelectInstance}
          - false
    Default:
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
  SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 80/80
  InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: centos_7_9
      InstanceName: MaxKB
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory:
        Ref: SystemDiskCategory
      Password:
        Ref: InstancePassword
      IoOptimized: optimized
      MaxAmount: 1
  DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
  InstallMaxKB:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
       #!/bin/bash
        echo "#########################"
        echo "# Install Docker"
        echo "#########################"
        wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum -y install docker-ce
        systemctl start docker
        systemctl enable docker

        echo "#########################"
        echo "# Install MaxKB"
        echo "#########################"

        yum -y install jq
        DOCKER_DAEMON_JSON="/etc/docker/daemon.json"
        sudo jq --arg registry "$NEW_REGISTRY" '. + { "registry-mirrors": [https://0jt38sli.mirror.aliyuncs.com] }' $DOCKER_DAEMON_JSON > ${
   DOCKER_DAEMON_JSON}.temp && sudo mv ${
   DOCKER_DAEMON_JSON}.temp $DOCKER_DAEMON_JSON
        sudo systemctl daemon-reload
        sudo systemctl restart docker
        docker run -d --name=maxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data 1panel/maxkb

Outputs:
  MaxKBUrl:
    Description: MaxKB default address.
    Value:
      Fn::Sub:
      - http://${
   IP}
      - IP:
          Fn::Jq:
          - First
          - if .[0].PublicIpAddress != [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddress
            end
          - Fn::GetAtt:
            - DS_Instances
            - Instances
Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
    - acs:developer:gitee:0147-在ECS实例上搭建大语言模型的知识库问答系统MaxKB

部署测试

回到我的模板中,点击我的模板,查看对应的资源框架,确认基本无误后点击保存。

image.png

命名为MaxKB。

image.png

点击创建栈:

image.png

由于我在上述ROS脚本中申明了可用区、CPU内存配置、系统盘类型等,所以这里都需要进行选择:

image.png

选择失败时回滚,点击创建,需保证账户余额大于100元

image.png

在创建界面的资源处,可以看到ROS中定义的实例正在逐一被创建:

image.png

构建MaxKB需要花费一些时间,创建完成后如下图所示:

image.png

但是意外的是,事件里面出现执行失败了。

进入事件,点击前面的实例链接。

image.png

查看实例的日志,发现是docker超时了。

image.png

于是我增加了一个测试下载的hello-world的案例,发现是正常的:

sudo docker run hello-world

image.png

于是乎,我换到我自己的电脑上尝试,很奇怪的是,即使添加了一堆镜像源依然下载报错。。。

image.png

感觉有点不对劲了,开始尝试用git方式部署,对照着文档学习了一下,采用git本地编译部署对环境要求极为苛刻。。。转化成一键部署的脚本更是麻烦。

image.png

最后尝试了半天无果,还是放弃MaxKB的搭建吧。。。没事,咱们换个别的,反正这次重点在于ROS编写上。

既然上面我们把基本框架都搭建完了,那么理论上只需要找个能跑的脚本就可以了,思来想去,考虑到综合使用频率和实用性,我这里还是决定来试一试部署Dify。

这里在查安装方法的时候,突然看到阿里的ROS官方已经发过一篇了。。。。流汗黄豆。。。

整体的内容也是大差不差,区别就在于Dify的本地编译很方便,而MaxKB需要规定版本的python环境,很麻烦。

ROSTemplateFormatVersion: '2015-09-01'
Description:
  en: Build the large language model (LLM) application development platform Dify on
    the ECS instance (CentOS 7).
  zh-cn: 在ECS实例(CentOS 7)上搭建大语言模型(LLM) 应用开发平台Dify。
Parameters:
  ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: recent
  SystemDiskCategory:
    Type: String
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      LocaleKey: DiskCategory
      ZoneId: ${
   ZoneId}
      InstanceType: ${
   InstanceType}
      AutoSelectFirst: true
      AutoChangeType: false
    Default: cloud_essd
  InstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol
        in).
      zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers,
        ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
          - ${
   SelectInstance}
          - false
    Default:
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
  SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 80/80
  InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: centos_7_9
      InstanceName: dify
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory:
        Ref: SystemDiskCategory
      Password:
        Ref: InstancePassword
      IoOptimized: optimized
      MaxAmount: 1
  DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
  InstallDify:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
        #!/bin/bash
        echo "#########################"
        echo "# Install Docker"
        echo "#########################"
        wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum -y install docker-ce
        systemctl start docker
        systemctl enable docker

        echo "#########################"
        echo "# Install Dify"
        echo "#########################"
        yum -y install git
        git clone --depth 1 https://github.com/langgenius/dify.git /opt/dify
        cd /opt/dify/docker
        docker compose up -d
        docker compose ps
Outputs:
  DifyUrl:
    Description: Dify default address.
    Value:
      Fn::Sub:
      - http://${
   IP}
      - IP:
          Fn::Jq:
          - First
          - if .[0].PublicIpAddress != [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddress
            end
          - Fn::GetAtt:
            - DS_Instances
            - Instances
Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
    - acs:developer:gitee:0147-在ECS实例上搭建大语言模型的知识库问答系统MaxKB

最后结果是创建成功了,但是网站打不开,我一查日志,给我看笑了。

image.png

官方文档给出的部署方式同样出现了docker超时的情况,这下估计docker真指望不到了。

离了个大谱,还是自己来吧。

先写了个部署nginx的脚本:

#!/bin/bash
#提前解决编译时所需的依赖环境、库文件;
yum install -y wget gzip gcc tar make
yum install -y pcre pcre-devel zlib-devel
#下载Nginx软件包;
wget -c http://nginx.org/download/nginx-1.24.0.tar.gz -P /usr/src/
#Cd切换/usr/src/;
cd /usr/src/
ls -l nginx-1.24.0.tar.gz
#通过Tar工具对其解压;
tar -xzvf nginx-1.24.0.tar.gz
#Cd切换至Nginx源代码目录;
cd nginx-1.24.0/
#提前创建www用户和组;
useradd -s /sbin/nologin www -M
#预编译;
./configure --prefix=/usr/local/nginx/ --user=www --group=www --with-http_stub_status_module
#编译;
make -j4
#安装;
make -j4 install
#查看Nginx软件服务是否部署成功;
ls -l /usr/local/nginx/
#启动Nginx服务进程;
/usr/local/nginx/sbin/nginx
#查看Nginx进程状态;
ps -ef|grep -aiE nginx
#Firewalld防火墙对外开放80端口;
firewall-cmd --add-port=80/tcp --permanent
systemctl reload firewalld.service

直接丢里面执行,部署完了如下所示:

image.png
image.png

这里可以看到nginx还是部署成功了的,看来只是docker存在一些莫名奇妙的问题罢了。将这里的nginx脚本替换之前的MaxKB或者Dify的shell脚本处,勉强算是制作出第一个ROS脚本了,虽然一点用处都没有。。。

基于ROS部署ChatTTS

ROSTemplateFormatVersion: '2015-09-01'
Description:
  en: Build text-to-speech system ChatTTS on the ECS instance (Ubuntu 22.04).
  zh-cn: 在ECS实例(Ubuntu 22.04)上搭建文本转语音系统ChatTTS。
Parameters:
  ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: recent
  SystemDiskCategory:
    Type: String
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      LocaleKey: DiskCategory
      ZoneId: ${
   ZoneId}
      InstanceType: ${
   InstanceType}
      AutoSelectFirst: true
      AutoChangeType: false
    Default: cloud_essd
  InstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol
        in).
      zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers,
        ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{
   }[]:;'<>,.?/ 中的特殊符号)。
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
          - ${
   SelectInstance}
          - false
    Default:
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
  SecurityGroupIngress_9966:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 9966/9966
  InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: ubuntu_22_04
      InstanceName: ChatTTS
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory:
        Ref: SystemDiskCategory
      Password:
        Ref: InstancePassword
      IoOptimized: optimized
      MaxAmount: 1
  DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
  InstallChatTTS:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
        #!/bin/bash
        echo "#########################"
        echo "# Install ChatTTS Web UI"
        echo "#########################"
        apt-get update
        apt-get install -y python3-venv

        git clone --depth 1 https://gitclone.com/github.com/jianchang512/ChatTTS-ui.git /opt/chat-tts-ui && cd /opt/chat-tts-ui
        ret_code=$?
        if [ $ret_code -ne 0 ]; then
          echo "Git clone https://gitclone.com/github.com/jianchang512/ChatTTS-ui.git failed. Exiting."
          exit $ret_code
        fi

        python3 -m venv venv
        source ./venv/bin/activate
        pip3 install -r requirements.txt
        export WEB_ADDRESS=0.0.0.0:9966
        nohup python3 app.py > app.log 2>&1 &
Outputs:
  ChatTTSUrl:
    Description: ChatTTS default address.
    Value:
      Fn::Sub:
      - http://${
   IP}:9966
      - IP:
          Fn::Jq:
          - First
          - if .[0].PublicIpAddress != [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddress
            end
          - Fn::GetAtt:
            - DS_Instances
            - Instances
Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
    - acs:developer:gitee:0147-在ECS实例(Ubuntu 22.04)上搭建文本转语音系统ChatTTS

image.png

image.png

终于有一个能跑起来了,一直试到凌晨五点了。。。

总结

如果不是这次亲手尝试来写ROS脚本也没想到会碰到那么多问题,本来其实听起来很简单的,整个逻辑也能理解,但是实际上手后,由于不熟悉,搞得这也是问题那也是问题,反反复复折腾。

第二点就是,官网上给的脚本居然也会出现执行错误的情况,这是我没想到的。

不过,也正是这些问题和挑战,让我深刻体会到了理论与实践之间的差距,也促使我更加深入地学习和探索。每解决一个问题,都是对云计算领域理解的一次深化,对ROS及背后资源编排理念的掌握也愈发熟练。

过程充满挑战,但每一次解决问题都是一次宝贵的学习机会,让我的技术栈更加坚实,也让我在云原生和DevOps的道路上迈出了坚实的一步。这种从实战中获得的经验,是任何教科书或理论学习都无法替代的。


2024年7月13日更新

昨晚研究了一晚,又写了一个部署2048游戏的ROS脚本。

ROSTemplateFormatVersion: '2015-09-01'
Description:
  en: Set up the 2048 game on an ECS instance..
  zh-cn: 在ECS实例上搭建2048小游戏。
Parameters:
  ZoneId:
    Type: String
    Label:
      en: Availability Zone
      zh-cn: 可用区ID
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  InstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${
   ZoneId}
      DefaultValueStrategy: ecs.e-c1m2.large
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
  SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      SecurityGroupId:
        Ref: SecurityGroup
      SourceCidrIp: 0.0.0.0/0
      IpProtocol: tcp
      NicType: intranet
      PortRange: 80/80
  InstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: centos_7_9
      InstanceName: GAME
      InstanceType:
       Ref: InstanceType
      SystemDiskCategory : cloud_essd
      IoOptimized: optimized
      MaxAmount: 2
  DS_Instances:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
  InstallGAME:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        Fn::GetAtt:
        - InstanceGroup
        - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 1800
      CommandContent: |
       #!/bin/bash
       yum install -y httpd wget
       systemctl start httpd
       wget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz
       tar xvf 2048.tgz
       mv 2048/* /var/www/html && rm -rf 2048

Outputs:
  GAMEUrl:
    Description: GAME default address.
    Value:
      Fn::Sub:
      - http://${IP}
      - IP:
          Fn::Jq:
          - First
          - if .[0].PublicIpAddress != [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddress
            end
          - Fn::GetAtt:
            - DS_Instances
            - Instances
Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
    - acs:developer:gitee:0147-在ECS实例上搭建2048小游戏

这里实测是完全没有任何问题的。

image.png

image.png

image.png

下面我把脚本上传到我的gitee中,新建一个仓库,命名为阿里云ROS:

image.png

由于只有一个脚本,所以直接创建文件然后复制进去就可以了:

image.png

最终地址如下

image.png

我们来尝试直接一键部署,前面引入ROS的部署的链接地址:

https://ros.console.aliyun.com/region/stacks/create?hideStepRow=true&hideStackConfig=true&disableRollback=false&isSimplified=true&disableNarue&productNavBar=disabled&templateUrl=

后面拼接自己的gitee地址:

https://gitee.com/a156da16/aliyunros/blob/master/GAME.yaml

所以最终一键部署链接如下:

https://ros.console.aliyun.com/cn-hangzhou/stacks/create?hideStepRow=true&hideStackConfig=true&disableRollback=false&isSimplified=true&disableNarue&productNavBar=disabled&templateUrl=https://gitee.com/a156da16/aliyunros/blob/master/GAME.yaml

尝试了一下,有个很逆天的地方,一直显示访问被拒绝。具体原因也一直没找到,在群里找专家问了:

image.png

为了避免版本不一致,我直接复制gitee里上传的那个版本,进入ROS中进行创建,是能够识别模板参数的:

image.png

但是通过官方给的链接就是一直报错。。。

这篇就这样吧,反正总之把脚本也是写出来了,刚开始接触不是很熟悉,只能从简单的开始了。


2024年7月15日更新

搞了半天自己的gitee地址复制错了,尴尬。。。

需要查看原始数据:

image.png

即:https://gitee.com/a156da16/aliyunros/raw/master/GAME.yaml

然后再拼接就可以了:

https://ros.console.aliyun.com/cn-hangzhou/stacks/create?hideStepRow=true&hideStackConfig=true&disableRollback=false&isSimplified=true&disableNarue&productNavBar=disabled&templateUrl=https://gitee.com/a156da16/aliyunros/raw/master/GAME.yaml

image.png

感谢专家的支持!另外,docker容器拉取失败的原因是因为国内网络问题,专家说过段时间会专门做个仓库的。

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
相关文章
|
弹性计算 运维 关系型数据库
云上部署环境(基础设施)的正确姿势——使用资源编排ROS进行基础设施的部署
![image.png](https://ata2-img.cn-hangzhou.oss-pub.aliyun-inc.com/66daa0b176da97de1dc8e66580fc0384.png) # 常见的部署问题 1. 多环境部署。根据实际开发的需要,一般至少需要准备3个环境:日常测试环境,部署预发环境,部署生产环境。 2. 多地域部署。对于云产品还需要支持多地域部署
1767 0
|
29天前
|
弹性计算 关系型数据库 MySQL
使用资源编排 ROS 轻松部署单点网站——以 WordPress 为例
WordPress 是流行的开源CMS,阿里云的ROS(Resource Orchestration Service)提供模板化部署服务,简化云上环境如VPC、ECS、MySQL的创建。用户可通过ROS控制台选择模板一键部署WordPress,配置包括实例区、类型、系统盘及密码等参数。ROS模板定义了资源、参数和输出,自动处理依赖关系,实现云资源和应用的自动化部署。通过ROS,用户可以高效管理和更新整个资源栈,实现快速、可靠的云服务部署。
165 1
使用资源编排 ROS 轻松部署单点网站——以 WordPress 为例
|
2月前
|
弹性计算 API 持续交付
基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS
基于 IaC 的理念,通过定义一个模板,使用 ROS 提供的 Terraform 托管服务进行自动化部署,可以非常高效快捷地部署任意云资源和应用(比如 ChatTTS 服务)。相比于手动部署或者通过 API、SDK 的部署方式,有着高效、稳定等诸多优势,也是服务上云的最佳实践。
35 1
基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS
|
2月前
|
弹性计算 JSON API
一键云部署:资源编排 ROS 轻松部署文本转语音系统 ChatTTS
ChatTTS是一款针对对话场景的文本转语音模型,支持英中两种语言,训练数据超过10万小时。ChatTTS可通过WebUI和API访问。阿里云的资源编排服务(ROS)提供了一键部署ChatTTS到云端的方案,用户只需在ROS控制台配置模板参数,如区域和实例类型,即可完成部署。部署后,从资源栈输出获取ChatTTS服务地址。ROS利用IaC理念自动化部署云资源和应用,提高了部署效率和稳定性。
598 5
一键云部署:资源编排 ROS 轻松部署文本转语音系统 ChatTTS
|
2月前
|
弹性计算 人工智能 JSON
一键云部署:资源编排 ROS 轻松部署 LLM 流程编排服务 Flowise
Flowise 是一个开源低代码平台,用于构建定制化的 LLM 流程和 AI 代理。阿里云的 Resource Orchestration Service (ROS) 提供了一键部署 Flowise 到 ECS 实例的方案。用户只需在 ROS 控制台配置模板参数,如可用区和实例类型,即可完成部署。部署后,从资源栈输出获取 Flowise 服务地址以开始使用。ROS 模板定义了 VPC、ECS 实例等资源,并通过 ROS 自动化部署,简化了云上资源和应用的管理。
195 1
一键云部署:资源编排 ROS 轻松部署 LLM 流程编排服务 Flowise
|
3月前
|
弹性计算 人工智能 JSON
一键云部署:资源编排 ROS 轻松部署 LLM 应用开发平台 Dify
Dify是一款开源的LLM应用开发平台,融合BaaS和LLMOps理念,助力开发者快速构建生产级AI应用。阿里云的ROS提供IaC自动化部署服务,通过JSON/YAML/Terraform模板轻松部署Dify环境。以下是简化的部署步骤: 1. 登录ROS控制台的Dify部署页面。 2. 配置ECS实例参数。 3. 创建资源栈,完成部署后从输出获取Dify服务地址。 ROS模板定义了VPC、VSwitch、ECS实例等资源,通过ROS控制台创建资源栈实现自动化部署。这种方式高效、稳定,体现了IaC的最佳实践。
493 1
|
3月前
|
弹性计算 持续交付 数据中心
一键云部署:ROS的Terraform托管服务助你轻松上线2048经典游戏
阿里云的资源编排服务ROS提供了Terraform托管能力,用户可以直接在ROS控制台上部署Terraform脚本,本文将详细介绍如何使用ROS的Terraform托管服务一键部署经典的2048小游戏到云端,让全世界的玩家都能在线体验。
212 1
|
9月前
|
存储 Serverless 对象存储
通过计算巢轻松部署ROS自定义资源
阿里云资源编排服务ROS可以帮助您简化云计算资源的管理。 通过编写和使用模板,ROS可以实现自动化部署和运维。ROS不仅能够编排阿里云资源,还支持自定义资源。 使用自定义资源,您可以在模板中编写自定义配置逻辑。 计算巢“ROS自定义资源”服务可以把GitHub代码仓库(Python语言)构建和部署为ROS自定义资源,并输出ROS模块,方便后续使用。
170 1
|
11月前
|
弹性计算 关系型数据库 MySQL
基于ROS快速部署LNMP环境(CentOS 7)
本教程提供在阿里云云服务器ECS上基于CentOS 7.9操作系统搭建LNMP环境的指引。LNMP是应用广泛的网站服务系统,由四种免费的开源软件Linux、Nginx、MySQL和PHP组成。搭建好LNMP环境后,您可以在该ECS实例上搭建网站、访问网站
444 0
|
弹性计算 JSON 分布式计算
通过资源编排批量部署 Hadoop 开发环境|学习笔记
快速学习通过资源编排批量部署 Hadoop 开发环境
116 0
通过资源编排批量部署 Hadoop 开发环境|学习笔记

推荐镜像

更多