国际网站怎么做优化,微信商城小程序搭建教程,哪个行业必须做网站,成都住建局官网住建扬尘监测前言
最近在参加的几个项目测评里#xff0c;我发现**“一键部署”这功能真心好用#xff0c;省下了不少宝贵时间和力气#xff0c;再加上看到阿里云现在有个开源上云**的活动。趁着这波热潮#xff0c;今天就聊聊怎么从头开始#xff0c;一步步搞定阿里云的资源编排服务…前言
最近在参加的几个项目测评里我发现**“一键部署”这功能真心好用省下了不少宝贵时间和力气再加上看到阿里云现在有个开源上云**的活动。趁着这波热潮今天就聊聊怎么从头开始一步步搞定阿里云的资源编排服务(ROS)希望能对刚接触这块的朋友有点帮助。咱们一块儿边学边实践让云上的项目部署变得更简单高效。
资源编排
阿里云的资源编排服务Resource Orchestration Service简称ROS是一种基础设施即代码IaC服务它允许用户通过编写模板来定义和管理云上的各种资源。这些资源包括但不限于ECS Elastic Compute Service实例、RDSRelational Database Service数据库实例、SLBServer Load Balancer负载均衡器等。ROS的核心价值在于自动化部署及运维它能自动处理资源的创建、配置及之间的依赖关系从而极大地简化了云计算资源的管理过程。
在ROS中用户根据ROS提供的模板规范使用JSON或YAML格式编写资源栈模板。模板中不仅定义了所需的资源类型和数量还明确了资源之间的逻辑依赖确保资源按正确的顺序被创建和配置。这样无论是新建环境、更新配置还是进行大规模的架构调整都可通过执行模板脚本来实现保证了操作的一致性和可重复性。
资源编排地址如下https://ros.console.aliyun.com/cn-hangzhou/welcome 下面我们还是以实战为导向从最基础的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。
通过上面可以看出最核心、最关键的部分其实是Parameters、Resources 因为这两个决定了模板设计者定义一系列可配置的参数和将要创建或管理的所有云资源及其配置是直接涉及资源创建和配置的核心逻辑参数。
下面我们来创建第一个案例。
基于ROS模板创建VPC
在创建之前我们需要先知道ROS支持的所有资源类型这里需要查看资源类型索引。 如果在这个列表中没有出现的产品就是暂时不支持采用ROS来创建的这是需要明确的第一点。
如上图我们看到VPC是支持使用ROS来创建的接下来我们再开展第二步点击这个蓝色链接位置查看它的详细语法、属性及返回值。 到这里我们基本就明白它的语法格式及书写方式了下面第三步上手开写。
回到资源编排界面点击【我的模板】→【创建模板】进去ROS在线编辑界面开始编辑。 初始的模板如下我们选择为yaml格式来进行编写。 下面咱们一行行的分析
ROSTemplateFormatVersion
默认版本号这里不用修改直接过
ROSTemplateFormatVersion: 2015-09-01Description
这里不是必填不过也可以填一下暂且起名为my first VPC-test。
Description: my first VPC-test
Parameters
这里到重头戏了几乎所有的可定制化参数都是在这里修改的在比较复杂的ROS脚本中几乎都会用到但是这里为了方便演示也选择暂时不填写等下后面测试时再填写后对比。
Parameters: {}
Resources
这里是用来详细定义使用该模板创建的资源栈所包含的资源包括资源间的依赖关系、配置细节等是必填项。
而其具体的格式可以看到如下 这里我们沿用该格式并且剔除一些不需要的参数最终命令如下 VPC:Type: ALIYUN::ECS::VPCProperties:VpcName: VPC-testCidrBlock: 192.168.0.0/24
这里面就只包含了最基础的CidrBlock专有网络网段和VpcName专有网络名称。
Mappings、Metadata、Conditions
这里也暂时不涉及可以直接删除掉。
Outputs
这里用于输出一些资源属性等有用信息这里我们可以尝试输出一下VPC的ID和关联的虚拟路由器ID。
Outputs:VPCId:Value:Fn::GetAtt:- VPC- VRouterIdVRouterId:Value:Fn::GetAtt:- VPC- VRouterId参照返回示例如下 最终ROS的整体脚本如下
ROSTemplateFormatVersion: 2015-09-01
Description: my first VPC-test
Resources:VPC:Type: ALIYUN::ECS::VPCProperties:VpcName: VPC-testCidrBlock: 192.168.0.0/24
Outputs:VPCId:Value:Fn::GetAtt:- VPC- VRouterIdVRouterId:Value:Fn::GetAtt:- VPC- VRouterId
点击预览查看资源架构我们可以看到如图所示的架构 确定之后点击保存模板命名后可在模板空间中查看和直接创建栈 选择失败时回滚点击创建 此时可以看到开始创建资源栈等待一段时间 创建成功后如下图所示 点击输出我们可以看到outputs中设定的输出的关键字 而假如我们不需要使用了也可以直接点击删除资源栈 以上是手动编写脚本的流程了在实际调试中还是有一些复杂的下面我们就来结合案例完成这次参赛的ROS部署作品。
基于ROS部署MaxKB
MaxKB
MaxKB是基于LLM大语言模型的知识库问答系统旨在成为企业的最强大脑。它支持开箱即用无缝嵌入到第三方业务系统并提供多模型支持包括主流大模型和本地私有大模型为用户提供智能问答交互体验和灵活性。 另外说一句我的关于知识库侧测评的文章也已经快写完了这几个月参加护网有点太累了几乎没时间来写抱歉抱歉 编写ROS 模板
这里我们还是一步步的来逐步解析。 ROSTemplateFormatVersion
老规矩不变。
ROSTemplateFormatVersion: 2015-09-01Description
因为是参赛的作品所以我这里也写的详细一点吧下面也是带上了中英的描述。
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的语法下面详细查看。
说实话有点吓人居然这么多 我们按照下面这个表格来一一排查 ZoneId
这里首先申明ZoneId , 至于为什么先申明ZoneId呢这是因为区域Zone的选择对创建的云资源如ECS实例、RDS数据库等有着直接的影响且下面在申明实例规格时会用到。
ZoneId:Type: StringLabel:en: Availability Zonezh-cn: 可用区IDAssociationProperty: ALIYUN::ECS::Instance:ZoneIdAssociationProperty 说明ZoneId参数与ECS实例的ZoneId属性关联。这意味着在模板中使用此参数的地方我们所选择的值将会直接应用于创建ECS实例时的可用区选择。这样的设计确保了模板的逻辑与阿里云ECS服务的实际属性紧密集成提高了模板的准确性和易用性。
InstanceType
ECS实例规格 必填项 这里需要参考实例规格族。 InstanceType:Type: StringLabel:en: Instance Typezh-cn: 实例类型AssociationProperty: ALIYUN::ECS::Instance::InstanceTypeAssociationPropertyMetadata:ZoneId: ${ZoneId}DefaultValueStrategy: recent
同样这里的 AssociationProperty 是指明参数与ECS实例的InstanceType属性关联而 AssociationPropertyMetadata 则是表示实例类型的可用性依赖于ZoneId中选择的区域ID且当用户没有明确指定实例类型时系统会选择最近常用或推荐的实例类型作为默认选项。
SystemDiskCategory
下面定义ECS实例系统盘的类型其中AssociationPropertyMetadata 里面包含了一些元数据来指导和约束系统盘类型的选择
SystemDiskCategory:Type: StringLabel:en: System Disk Typezh-cn: 系统盘类型AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategoryAssociationPropertyMetadata:LocaleKey: DiskCategoryZoneId: ${ZoneId}InstanceType: ${InstanceType}AutoSelectFirst: trueAutoChangeType: falseDefault: cloud_essdInstancePassword
下面定义了用于登录ECS实例的密码规则确保了安全性的同时也提供了一定的灵活性
InstancePassword:Type: StringLabel:en: Instance Passwordzh-cn: 实例密码Description:en: Server login password, Length 8-30, must contain three(Capital letters,lowercase letters, numbers, ()~!#$%^*_-|{}[]:;,.?/ Special symbolin).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}- falseDefault:AllowedPattern: [0-9A-Za-z\_\-\:;,%~!#\(\)\$\^\*\\|\{\}\[\]\.\?\/]$MinLength: 8MaxLength: 30NoEcho: true
所以Parameters此处的完整脚本如下
Parameters:ZoneId:Type: StringLabel:en: Availability Zonezh-cn: 可用区IDAssociationProperty: ALIYUN::ECS::Instance:ZoneIdInstanceType:Type: StringLabel:en: Instance Typezh-cn: 实例类型AssociationProperty: ALIYUN::ECS::Instance::InstanceTypeAssociationPropertyMetadata:ZoneId: ${ZoneId}DefaultValueStrategy: recentSystemDiskCategory:Type: StringLabel:en: System Disk Typezh-cn: 系统盘类型AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategoryAssociationPropertyMetadata:LocaleKey: DiskCategoryZoneId: ${ZoneId}InstanceType: ${InstanceType}AutoSelectFirst: trueAutoChangeType: falseDefault: cloud_essdInstancePassword:Type: StringLabel:en: Instance Passwordzh-cn: 实例密码Description:en: Server login password, Length 8-30, must contain three(Capital letters,lowercase letters, numbers, ()~!#$%^*_-|{}[]:;,.?/ Special symbolin).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}- falseDefault:AllowedPattern: [0-9A-Za-z\_\-\:;,%~!#\(\)\$\^\*\\|\{\}\[\]\.\?\/]$MinLength: 8MaxLength: 30NoEcho: true Resources
这里开始创建资源分析架构所需涉及产品如下
VPC
定义一个虚拟私有云(VPC)资源192.168.0.0/16 指定了VPC的IP地址范围。
Vpc:Type: ALIYUN::ECS::VPCProperties:CidrBlock: 192.168.0.0/16VSwitch
定义一个虚拟交换机(VSwitch)的配置Ref: ZoneId 表示虚拟交换机将被创建在指定的可用区(Zone)中这里的ZoneId是一个引用其实际值需要在模板的参数或映射部分提前定义或通过外部参数传入Ref: Vpc 指明该虚拟交换机隶属于哪个VPC。这里同样使用了引用意味着VSwitch将与之前定义的VPC关联。确保在模板中已经定义了VPC资源或者通过参数传递了正确的VPC ID192.168.0.0/24 定义了虚拟交换机的IP地址范围。 VSwitch:Type: ALIYUN::ECS::VSwitchProperties:ZoneId:Ref: ZoneIdVpcId:Ref: VpcCidrBlock: 192.168.0.0/24
SecurityGroup
创建安全组Ref: Vpc 指定该安全组将被创建在哪个VPC中这里通过引用之前定义的VPC资源Vpc确保安全组与目标VPC正确关联。这一步是必要的因为每个安全组都必须绑定到一个特定的VPC。
SecurityGroup:Type: ALIYUN::ECS::SecurityGroupProperties:VpcId:Ref: VpcSecurityGroupIngress_80
定义了入站规则Ref: SecurityGroup 引用了之前定义的安全组ID这条入站规则将被添加到该安全组中0.0.0.0/0 指定任何IP地址全网段都可以作为流量的来源这意味着对于这条规则不限制访问的来源IP地址**tcp **指定了该规则适用的协议类型这里是TCPintranet 表示这条规则仅适用于VPC内部的通信80/80 定义了允许访问的端口范围这里只开放了TCP 80端口通常用于HTTP服务。
SecurityGroupIngress_80:Type: ALIYUN::ECS::SecurityGroupIngressProperties:SecurityGroupId:Ref: SecurityGroupSourceCidrIp: 0.0.0.0/0IpProtocol: tcpNicType: intranetPortRange: 80/80InstanceGroup
定义实例群组引用上面创建的Vpc、VSwitch和SecurityGroupId实例指定使用CentOS 7.9的镜像设置了实例的名称为MaxKB后面继续引入实例类型、系统盘的类别和密码。
InstanceGroup:Type: ALIYUN::ECS::InstanceGroupProperties:VpcId:Ref: VpcVSwitchId:Ref: VSwitchSecurityGroupId:Ref: SecurityGroupImageId: centos_7_9InstanceName: MaxKBInstanceType:Ref: InstanceTypeSystemDiskCategory:Ref: SystemDiskCategoryPassword:Ref: InstancePasswordIoOptimized: optimizedMaxAmount: 1DS_Instances
通过DS_Instances数据源来获取通过InstanceGroup创建的ECS实例列表。 DS_Instances:Type: DATASOURCE::ECS::InstancesProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsInstallMaxKB
这里使用到Formation模板中的ALIYUN::ECS::RunCommand资源类型配置用于在特定的ECS实例上执行一系列Shell脚本命令。
InstallMaxKB:
Type: ALIYUN::ECS::RunCommandProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsType: RunShellScriptSync: trueTimeout: 1800CommandContent: |#!/bin/bashecho #########################echo # Install Dockerecho #########################wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-cesystemctl start dockersystemctl enable dockerecho #########################echo # Install MaxKBecho #########################yum -y install jqDOCKER_DAEMON_JSON/etc/docker/daemon.jsonsudo 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_JSONsudo systemctl daemon-reloadsudo systemctl restart dockerdocker run -d --namemaxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data 1panel/maxkb最终Resources下脚本如下
Resources:Vpc:Type: ALIYUN::ECS::VPCProperties:CidrBlock: 192.168.0.0/16VSwitch:Type: ALIYUN::ECS::VSwitchProperties:ZoneId:Ref: ZoneIdVpcId:Ref: VpcCidrBlock: 192.168.0.0/24SecurityGroup:Type: ALIYUN::ECS::SecurityGroupProperties:VpcId:Ref: VpcSecurityGroupIngress_80:Type: ALIYUN::ECS::SecurityGroupIngressProperties:SecurityGroupId:Ref: SecurityGroupSourceCidrIp: 0.0.0.0/0IpProtocol: tcpNicType: intranetPortRange: 80/80InstanceGroup:Type: ALIYUN::ECS::InstanceGroupProperties:VpcId:Ref: VpcVSwitchId:Ref: VSwitchSecurityGroupId:Ref: SecurityGroupImageId: centos_7_9InstanceName: difyInstanceType:Ref: InstanceTypeSystemDiskCategory:Ref: SystemDiskCategoryPassword:Ref: InstancePasswordIoOptimized: optimizedMaxAmount: 1DS_Instances:Type: DATASOURCE::ECS::InstancesProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIds
InstallMaxKB:
Type: ALIYUN::ECS::RunCommandProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsType: RunShellScriptSync: trueTimeout: 1800CommandContent: |#!/bin/bashecho #########################echo # Install Dockerecho #########################wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-cesystemctl start dockersystemctl enable dockerecho #########################echo # Install MaxKBecho #########################yum -y install jqDOCKER_DAEMON_JSON/etc/docker/daemon.jsonsudo 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_JSONsudo systemctl daemon-reloadsudo systemctl restart dockerdocker run -d --namemaxkb -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.IpAddressend- Fn::GetAtt:- DS_Instances- InstancesMetadata
添加了一个标签来描述此模板的功能和背景按照比赛要求是需要采用“手机尾号-模板用途”来编写。
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: StringLabel:en: Availability Zonezh-cn: 可用区IDAssociationProperty: ALIYUN::ECS::Instance:ZoneIdInstanceType:Type: StringLabel:en: Instance Typezh-cn: 实例类型AssociationProperty: ALIYUN::ECS::Instance::InstanceTypeAssociationPropertyMetadata:ZoneId: ${ZoneId}DefaultValueStrategy: recentSystemDiskCategory:Type: StringLabel:en: System Disk Typezh-cn: 系统盘类型AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategoryAssociationPropertyMetadata:LocaleKey: DiskCategoryZoneId: ${ZoneId}InstanceType: ${InstanceType}AutoSelectFirst: trueAutoChangeType: falseDefault: cloud_essdInstancePassword:Type: StringLabel:en: Instance Passwordzh-cn: 实例密码Description:en: Server login password, Length 8-30, must contain three(Capital letters,lowercase letters, numbers, ()~!#$%^*_-|{}[]:;,.?/ Special symbolin).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}- falseDefault:AllowedPattern: [0-9A-Za-z\_\-\:;,%~!#\(\)\$\^\*\\|\{\}\[\]\.\?\/]$MinLength: 8MaxLength: 30NoEcho: true
Resources:Vpc:Type: ALIYUN::ECS::VPCProperties:CidrBlock: 192.168.0.0/16VSwitch:Type: ALIYUN::ECS::VSwitchProperties:ZoneId:Ref: ZoneIdVpcId:Ref: VpcCidrBlock: 192.168.0.0/24SecurityGroup:Type: ALIYUN::ECS::SecurityGroupProperties:VpcId:Ref: VpcSecurityGroupIngress_80:Type: ALIYUN::ECS::SecurityGroupIngressProperties:SecurityGroupId:Ref: SecurityGroupSourceCidrIp: 0.0.0.0/0IpProtocol: tcpNicType: intranetPortRange: 80/80InstanceGroup:Type: ALIYUN::ECS::InstanceGroupProperties:VpcId:Ref: VpcVSwitchId:Ref: VSwitchSecurityGroupId:Ref: SecurityGroupImageId: centos_7_9InstanceName: MaxKBInstanceType:Ref: InstanceTypeSystemDiskCategory:Ref: SystemDiskCategoryPassword:Ref: InstancePasswordIoOptimized: optimizedMaxAmount: 1DS_Instances:Type: DATASOURCE::ECS::InstancesProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsInstallMaxKB:Type: ALIYUN::ECS::RunCommandProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsType: RunShellScriptSync: trueTimeout: 1800CommandContent: |#!/bin/bashecho #########################echo # Install Dockerecho #########################wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-cesystemctl start dockersystemctl enable dockerecho #########################echo # Install MaxKBecho #########################yum -y install jqDOCKER_DAEMON_JSON/etc/docker/daemon.jsonsudo 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_JSONsudo systemctl daemon-reloadsudo systemctl restart dockerdocker run -d --namemaxkb -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data 1panel/maxkbOutputs:MaxKBUrl:Description: MaxKB default address.Value:Fn::Sub:- http://${IP}- IP:Fn::Jq:- First- if .[0].PublicIpAddress ! [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddressend- Fn::GetAtt:- DS_Instances- Instances
Metadata:ALIYUN::ROS::Interface:TemplateTags:- acs:developer:gitee:0147-在ECS实例上搭建大语言模型的知识库问答系统MaxKB
部署测试
回到我的模板中点击我的模板查看对应的资源框架确认基本无误后点击保存。 命名为MaxKB。 点击创建栈 由于我在上述ROS脚本中申明了可用区、CPU内存配置、系统盘类型等所以这里都需要进行选择 选择失败时回滚点击创建需保证账户余额大于100元 在创建界面的资源处可以看到ROS中定义的实例正在逐一被创建 构建MaxKB需要花费一些时间创建完成后如下图所示 但是意外的是事件里面出现执行失败了。
进入事件点击前面的实例链接。 查看实例的日志发现是docker超时了。 于是我增加了一个测试下载的hello-world的案例发现是正常的
sudo docker run hello-world 于是乎我换到我自己的电脑上尝试很奇怪的是即使添加了一堆镜像源依然下载报错。。。 感觉有点不对劲了开始尝试用git方式部署对照着文档学习了一下采用git本地编译部署对环境要求极为苛刻。。。转化成一键部署的脚本更是麻烦。 最后尝试了半天无果还是放弃MaxKB的搭建吧。。。没事咱们换个别的反正这次重点在于ROS编写上。
既然上面我们把基本框架都搭建完了那么理论上只需要找个能跑的脚本就可以了思来想去考虑到综合使用频率和实用性我这里还是决定来试一试部署Dify。
这里在查安装方法的时候突然看到阿里的ROS官方已经发过一篇了。。。。流汗黄豆。。。
整体的内容也是大差不差区别就在于Dify的本地编译很方便而MaxKB需要规定版本的python环境很麻烦。
ROSTemplateFormatVersion: 2015-09-01
Description:en: Build the large language model (LLM) application development platform Dify onthe ECS instance (CentOS 7).zh-cn: 在ECS实例CentOS 7上搭建大语言模型(LLM) 应用开发平台Dify。
Parameters:ZoneId:Type: StringLabel:en: Availability Zonezh-cn: 可用区IDAssociationProperty: ALIYUN::ECS::Instance:ZoneIdInstanceType:Type: StringLabel:en: Instance Typezh-cn: 实例类型AssociationProperty: ALIYUN::ECS::Instance::InstanceTypeAssociationPropertyMetadata:ZoneId: ${ZoneId}DefaultValueStrategy: recentSystemDiskCategory:Type: StringLabel:en: System Disk Typezh-cn: 系统盘类型AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategoryAssociationPropertyMetadata:LocaleKey: DiskCategoryZoneId: ${ZoneId}InstanceType: ${InstanceType}AutoSelectFirst: trueAutoChangeType: falseDefault: cloud_essdInstancePassword:Type: StringLabel:en: Instance Passwordzh-cn: 实例密码Description:en: Server login password, Length 8-30, must contain three(Capital letters,lowercase letters, numbers, ()~!#$%^*_-|{}[]:;,.?/ Special symbolin).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}- falseDefault:AllowedPattern: [0-9A-Za-z\_\-\:;,%~!#\(\)\$\^\*\\|\{\}\[\]\.\?\/]$MinLength: 8MaxLength: 30NoEcho: true
Resources:Vpc:Type: ALIYUN::ECS::VPCProperties:CidrBlock: 192.168.0.0/16VSwitch:Type: ALIYUN::ECS::VSwitchProperties:ZoneId:Ref: ZoneIdVpcId:Ref: VpcCidrBlock: 192.168.0.0/24SecurityGroup:Type: ALIYUN::ECS::SecurityGroupProperties:VpcId:Ref: VpcSecurityGroupIngress_80:Type: ALIYUN::ECS::SecurityGroupIngressProperties:SecurityGroupId:Ref: SecurityGroupSourceCidrIp: 0.0.0.0/0IpProtocol: tcpNicType: intranetPortRange: 80/80InstanceGroup:Type: ALIYUN::ECS::InstanceGroupProperties:VpcId:Ref: VpcVSwitchId:Ref: VSwitchSecurityGroupId:Ref: SecurityGroupImageId: centos_7_9InstanceName: difyInstanceType:Ref: InstanceTypeSystemDiskCategory:Ref: SystemDiskCategoryPassword:Ref: InstancePasswordIoOptimized: optimizedMaxAmount: 1DS_Instances:Type: DATASOURCE::ECS::InstancesProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsInstallDify:Type: ALIYUN::ECS::RunCommandProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsType: RunShellScriptSync: trueTimeout: 1800CommandContent: |#!/bin/bashecho #########################echo # Install Dockerecho #########################wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-cesystemctl start dockersystemctl enable dockerecho #########################echo # Install Difyecho #########################yum -y install gitgit clone --depth 1 https://github.com/langgenius/dify.git /opt/difycd /opt/dify/dockerdocker compose up -ddocker 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.IpAddressend- Fn::GetAtt:- DS_Instances- Instances
Metadata:ALIYUN::ROS::Interface:TemplateTags:- acs:developer:gitee:0147-在ECS实例上搭建大语言模型的知识库问答系统MaxKB
最后结果是创建成功了但是网站打不开我一查日志给我看笑了。 官方文档给出的部署方式同样出现了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/ --userwww --groupwww --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-port80/tcp --permanent
systemctl reload firewalld.service 直接丢里面执行部署完了如下所示 这里可以看到nginx还是部署成功了的看来只是docker存在一些莫名奇妙的问题罢了。将这里的nginx脚本替换之前的MaxKB或者Dify的shell脚本处勉强算是制作出第一个ROS脚本了虽然一点用处都没有。。。
总结
如果不是这次亲手尝试来写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: StringLabel:en: Availability Zonezh-cn: 可用区IDAssociationProperty: ALIYUN::ECS::Instance:ZoneIdInstanceType:Type: StringLabel:en: Instance Typezh-cn: 实例类型AssociationProperty: ALIYUN::ECS::Instance::InstanceTypeAssociationPropertyMetadata:ZoneId: ${ZoneId}DefaultValueStrategy: ecs.e-c1m2.large
Resources:Vpc:Type: ALIYUN::ECS::VPCProperties:CidrBlock: 192.168.0.0/16VSwitch:Type: ALIYUN::ECS::VSwitchProperties:ZoneId:Ref: ZoneIdVpcId:Ref: VpcCidrBlock: 192.168.0.0/24SecurityGroup:Type: ALIYUN::ECS::SecurityGroupProperties:VpcId:Ref: VpcSecurityGroupIngress_80:Type: ALIYUN::ECS::SecurityGroupIngressProperties:SecurityGroupId:Ref: SecurityGroupSourceCidrIp: 0.0.0.0/0IpProtocol: tcpNicType: intranetPortRange: 80/80InstanceGroup:Type: ALIYUN::ECS::InstanceGroupProperties:VpcId:Ref: VpcVSwitchId:Ref: VSwitchSecurityGroupId:Ref: SecurityGroupImageId: centos_7_9InstanceName: GAMEInstanceType:Ref: InstanceTypeSystemDiskCategory : cloud_essdIoOptimized: optimizedMaxAmount: 2DS_Instances:Type: DATASOURCE::ECS::InstancesProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsInstallGAME:Type: ALIYUN::ECS::RunCommandProperties:InstanceIds:Fn::GetAtt:- InstanceGroup- InstanceIdsType: RunShellScriptSync: trueTimeout: 1800CommandContent: |#!/bin/bashyum install -y httpd wgetsystemctl start httpdwget https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz -O 2048.tgztar xvf 2048.tgzmv 2048/* /var/www/html rm -rf 2048Outputs:GAMEUrl:Description: GAME default address.Value:Fn::Sub:- http://${IP}- IP:Fn::Jq:- First- if .[0].PublicIpAddress ! [] then .[0].PublicIpAddress[0] else .[0].EipAddress.IpAddressend- Fn::GetAtt:- DS_Instances- Instances
Metadata:ALIYUN::ROS::Interface:TemplateTags:- acs:developer:gitee:0147-在ECS实例上搭建2048小游戏
这里实测是完全没有任何问题的。 下面我把脚本上传到我的gitee中,新建一个仓库命名为阿里云ROS 由于只有一个脚本所以直接创建文件然后复制进去就可以了 最终地址如下 我们来尝试直接一键部署前面引入ROS的部署的链接地址
https://ros.console.aliyun.com/region/stacks/create?hideStepRowtruehideStackConfigtruedisableRollbackfalseisSimplifiedtruedisableNarueproductNavBardisabledtemplateUrl
后面拼接自己的gitee地址
https://gitee.com/a156da16/aliyunros/blob/master/GAME.yaml
所以最终一键部署链接如下
https://ros.console.aliyun.com/cn-hangzhou/stacks/create?hideStepRowtruehideStackConfigtruedisableRollbackfalseisSimplifiedtruedisableNarueproductNavBardisabledtemplateUrlhttps://gitee.com/a156da16/aliyunros/blob/master/GAME.yaml
尝试了一下有个很逆天的地方一直显示访问被拒绝。具体原因也一直没找到在群里找专家问了 为了避免版本不一致我直接复制gitee里上传的那个版本进入ROS中进行创建是能够识别模板参数的 但是通过官方给的链接就是一直报错。。。
这篇就这样吧反正总之把脚本也是写出来了刚开始接触不是很熟悉只能从简单的开始了。