本文介绍如何在计算巢创建容器应用+RDS数据库的场景的服务。
前提条件
已创建ACK集群。更多信息,请参见创建ACK集群。
操作流程
本示例使用一个基本的容器镜像,并在该镜像中预置了数据库初始化脚本,在服务创建的过程中自动初始化数据库并在数据库初始化完成后,向数据库中插入一条包含ComputeNest名字的数据。服务实例创建完成后,可以使用API名称查询数据库并返回结果Hello ComputeNest
。步骤如下:
步骤一:准备容器镜像
创建服务前,您需要先准备容器镜像并将已准备好的容器镜像上传至计算巢用于服务商托管镜像的私有镜像仓库中。
准备容器镜像。
使用以下任一方法准备本地容器镜像。
直接使用阿里云提供的容器镜像。
docker pull compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/bestpractice/springboot-demo:demo
重新编写源代码创建容器镜像。
获取镜像源代码,根据业务需求完成编写。
在源代码根目录(即pom.xml所在目录)下,使用Maven将程序打包为Jar包,Jar包会自动生成到target目录中。
mvn install
构建镜像。
完成构建后,镜像会自动下载到您本地电脑。
docker build --build-arg JAR_FILE=target/\*.jar -t <your-image-tag> .
上传容器镜像至计算巢镜像仓库。
获取计算巢镜像仓库访问凭证、打标镜像和推送镜像Docker命令。
登录计算巢控制台。
在左侧导航栏中选择服务部署物,然后单击创建部署物。
在创建部署物界面的部署物类型下,单击获取访问凭证。在弹出的界面中获取登录镜像仓库、打标镜像和推送镜像的命令。
在Docker命令行工具,登录镜像仓库、打标镜像和推送镜像。
步骤二:创建容器镜像部署物
创建服务前,需要先完成容器镜像部署物的创建和发布。
登录计算巢控制台。
在左侧导航栏中,单击服务部署物。然后在部署物管理界面,单击创建部署物。
在创建部署物界面,填写部署物信息、部署物内容和设置分发的信息。
配置项
配置示例
部署物名称
springboot容器部署
部署物版本名称
springboot容器部署版本1
部署物描述
springboot镜像容器部署物
部署物类型
容器镜像
选择镜像
部署物名称:springbootdemo
部署物版本:latest
单击发布部署物。
单击发布部署物后,可在部署物管理页面,单击部署物名称,进入部署物详情界面,查看部署物的部署进度。
当部署物状态为可用时,表示部署物发布成功。
步骤三:创建服务
登录计算巢控制台。
在左侧导航栏中,单击我的服务,并在我的服务页面中选择我创建的服务,然后单击创建新服务。
在创建新服务界面,根据需求配置相关参数。
此处只列举创建服务需要特别配置的参数,其他参数配置,请参见创建私有部署服务。
在录入模板区域的模板内容处,填写服务模板内容。此处描述模板内容中特别配置的参数,详细的模板内容,请参见模板示例。
在容器部署时,需要拉取计算巢私有镜像仓库中的镜像。ACK集群需要具备访问计算巢私有镜像仓库的能力。因此在模板中定义了一个dockerconfigjson类型的Secret,并使用计算巢标识符{{ computenest::acr::dockerconfigjson }}。
ClusterApplication: DependsOn: Database Type: ALIYUN::CS::ClusterApplication Properties: ClusterId: Ref: ClusterId YamlContent: Fn::Sub: - | # 省略... apiVersion: v1 data: .dockerconfigjson: {{ computenest::acr::dockerconfigjson }} kind: Secret metadata: name: computenestrepo namespace: ${NameSpace} type: kubernetes.io/dockerconfigjson # 省略...
在模板中通过{{ computenest::acrimage::springbootdemo }}标识符将模板中的image关联至计算巢部署物。
ClusterApplication: DependsOn: Database Type: ALIYUN::CS::ClusterApplication Properties: ClusterId: Ref: ClusterId YamlContent: Fn::Sub: - | # 省略... apiVersion: apps/v1 kind: Deployment metadata: labels: app: springboot-demo-deployment name: springboot-demo-deployment namespace: ${NameSpace} spec: progressDeadlineSeconds: 600 replicas: 2 revisionHistoryLimit: 10 selector: matchLabels: app: springboot-demo-pod template: metadata: labels: app: springboot-demo-pod spec: containers: - env: - name: DB_HOST value: ${RdsConnectString} - name: DB_USER value: ${DbUser} - name: DB_PASSWORD value: ${DbPassword} image: {{ computenest::acrimage::springbootdemo }} imagePullPolicy: Always name: springboot-demo-container ports: - containerPort: 8080 protocol: TCP imagePullSecrets: - name: computenestrepo restartPolicy: Always # 省略...
在部署应用区域的容器镜像关联处,关联已创建的镜像部署物,并选择部署物的版本。
单击保存服务。
测试服务。
服务保存后,您需要对创建的服务实例进行测试,保证其正常可用。更多信息,请参见测试服务功能。
发布服务。
服务测试通过后,再提交审核,审核通过后即可发布上线。更多信息,请参见上线服务。
步骤四:创建服务实例并查询数据库
该步骤是服务商以用户的身份验证服务中配置的容器镜像是否能够在服务实例中正确部署。
创建服务实例。
更多信息,请参考创建私有部署服务实例。
服务实例部署成功,则表示镜像部署物也已经在服务实例中部署成功。
查询数据库。
使用kubectl命令行工具查询LoadBalancer访问端点,并使用获取到的公网IP访问应用,并查看返回结果。
模板示例
您可以通过如下内容,查看本场景中必须的ROS资源和函数。
本场景详细的模板示例如下。
ROSTemplateFormatVersion: '2015-09-01'
Description:
en: A simple demo that deploys a RDS instance and a container-base app into ack. The app use RDS instance as a persistence storage.
zh-cn: 新建一个RDS实例并向ACK中部署容器应用。容器应用使用RDS实例作为数据库。
Parameters:
ZoneId:
Type: String
AssociationProperty: ALIYUN::ECS::Instance:ZoneId
Description:
en: Availability zone ID,<br><b>note: <font color='blue'>Before selecting, please confirm that the Availability Zone supports the specification of creating ECS resources</font></b>
zh-cn: 可用区ID
Label:
en: VSwitch Available Zone
zh-cn: 可用区
VpcId:
Type: String
AssociationProperty: ALIYUN::ECS::VPC::VPCId
VSwitchId:
Type: String
AssociationProperty: ALIYUN::ECS::VSwitch::VSwitchId
AssociationPropertyMetadata:
VpcId: ${VpcId}
ZoneId: ${ZoneId}
PayType:
AssociationProperty: ChargeType
Type: String
Label:
en: ECS Instance Charge Type
zh-cn: 付费类型
Default: PostPaid
AllowedValues:
- PostPaid
- PrePaid
PayPeriod:
Type: Number
Description:
en: The subscription period. Unit is months.
zh-cn: 购买时长,单位(月)
Label:
en: The subscription period. Unit is months.
zh-cn: 购买时长,单位(月)
Default: 1
AllowedValues:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 12
- 24
- 36
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Or:
- Fn::Equals:
- ${PayType}
- PrePaid
- Fn::Equals:
- ${PayType}
- undefined
RdsInstanceClass:
Label: MySQL 实例规格
Type: String
Description:
zh-cn: 根据数据库引擎的类型和可用的区域支持选择实例规格
en: 'Select the instance specification based on the type of database engine and the available area support'
Default: rds.mysql.s2.large
RdsInstanceStorage:
Label: 磁盘大小
Type: Number
Description:
zh-cn: RDS 实例大小,范围为 20 - 2000,每 5 个增量,单位为 GB
en: The size range of RDS instances is 20 - 2000, Incrementing in every 5, unit GB
MinValue: 20
MaxValue: 2000
ConstraintDescription: The size range of RDS instances is 20 - 2000, Incrementing in every 5, unit GB
Default: 30
RdsAccountName:
Type: String
Label:
zh-cn: 用户名称
en: Account Name
Description:
zh-cn: MySQL 管理员用户名称
en: Account Name
Default: db_root
RdsAccountPassword:
Type: String
NoEcho: true
Label:
zh-cn: 用户密码
en: DB Account Password
Description:
zh-cn: |-
长度为8~32个字符。由大写英文字母、小写英文字母、数字、特殊字符中的任意三种组成。支持的特殊字符如下:
!@#$&%^*()_+-= 。
en: |-
The length is 8 ~ 32 characters. It is composed of uppercase English letters, lowercase English letters, numbers and special characters. The special characters supported are as follows:
!@#$& amp;%^* ()_+-= .
ClusterId:
Type: String
Description:
en: >-
The ID of Kubernetes ClusterId in which application deployed.
zh-cn: >-
部署应用程序的K8s集群ID
AllowedPattern: '[0-9a-z]+$'
Label:
en: Kubernetes ClusterId
zh-cn: K8s集群ID
AssociationProperty: ALIYUN::CS::Cluster::ClusterId
ConstraintDescription:
en: >-
must be lowercase letters or numbers
zh-cn: '集群ID必须由小写字母或者数字组成'
NameSpace:
Type: String
Description:
en: >-
The NameSpace in which application deployed.
zh-cn: >-
部署应用程序的K8s命名空间
Resources:
EcsSecurityGroup:
Type: ALIYUN::ECS::SecurityGroup
Properties:
VpcId:
Ref: VpcId
SecurityGroupIngress:
- PortRange: '-1/-1'
Priority: 1
SourceCidrIp: 0.0.0.0/0
IpProtocol: all
NicType: intranet
SecurityGroupEgress:
- PortRange: '-1/-1'
Priority: 1
IpProtocol: all
DestCidrIp: 0.0.0.0/0
NicType: intranet
DBInstance:
Type: ALIYUN::RDS::DBInstance
Properties:
ZoneId:
Ref: ZoneId
VPCId:
Ref: VpcId
VSwitchId:
Ref: VSwitchId
Engine: MySQL
EngineVersion: "5.7"
DBInstanceClass:
Ref: RdsInstanceClass
DBInstanceStorage:
Ref: RdsInstanceStorage
PayType:
Ref: PayType
PeriodType: Month
Period:
Ref: PayPeriod
SecurityIPList: '0.0.0.0/0'
RdsAccount:
DependsOn: DBInstance
Type: ALIYUN::RDS::Account
Properties:
DBInstanceId:
Ref: DBInstance
AccountType: Super
AccountName:
Ref: RdsAccountName
AccountPassword:
Ref: RdsAccountPassword
RdsParameter:
Type: ALIYUN::RDS::DBInstanceParameterGroup
Properties:
DBInstanceId:
Ref: DBInstance
Parameters:
- Key: innodb_large_prefix
Value: 'ON'
- Key: innodb_adaptive_flushing_lwm
Value: '10'
Database:
Type: ALIYUN::RDS::Database
Properties:
CharacterSetName: UTF8
DBInstanceId:
Ref: DBInstance
DBName: springboot_demo
DependsOn:
- DBInstance
ClusterApplication:
DependsOn: Database
Type: ALIYUN::CS::ClusterApplication
Properties:
ClusterId:
Ref: ClusterId
YamlContent:
Fn::Sub:
- |
apiVersion: v1
kind: Namespace
metadata:
name: ${NameSpace}
---
apiVersion: v1
data:
.dockerconfigjson: {{ computenest::acr::dockerconfigjson }}
kind: Secret
metadata:
name: computenestrepo
namespace: ${NameSpace}
type: kubernetes.io/dockerconfigjson
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: springboot-demo-deployment
name: springboot-demo-deployment
namespace: ${NameSpace}
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: springboot-demo-pod
template:
metadata:
labels:
app: springboot-demo-pod
spec:
containers:
- env:
- name: DB_HOST
value: ${RdsConnectString}
- name: DB_USER
value: ${DbUser}
- name: DB_PASSWORD
value: ${DbPassword}
image: {{ computenest::acrimage::springbootdemo }}
imagePullPolicy: Always
name: springboot-demo-container
ports:
- containerPort: 8080
protocol: TCP
imagePullSecrets:
- name: computenestrepo
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
labels:
app: springboot-demo-svc
name: springboot-demo-svc
namespace: ${NameSpace}
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: springboot-demo-pod
type: LoadBalancer
- NameSpace:
Ref: NameSpace
DbUser:
Ref: RdsAccountName
DbPassword:
Ref: RdsAccountPassword
RdsConnectString:
Fn::GetAtt:
- DBInstance
- InnerConnectionString
AppExternalIp:
Type: DATASOURCE::CS::ClusterApplicationResources
Properties:
Kind: Service
Name: springboot-demo-svc
ClusterId:
Ref: ClusterApplication
Namespace:
Ref: NameSpace
JsonPath: $.status.loadBalancer.ingress
FirstMatch: true
DependsOn: ClusterApplication
Outputs:
ExternalIp:
Value:
Ref: AppExternalIp
Metadata:
ALIYUN::ROS::Interface:
ParameterGroups:
- Parameters:
- VpcId
- ZoneId
- VSwitchId
Label:
en: Network Configuration
zh-cn: 网络参数配置
- Parameters:
- ClusterId
- NameSpace
Label:
en: ACK Configuration
zh-cn: ACK参数配置
- Parameters:
- RdsInstanceClass
- RdsInstanceStorage
- RdsAccountName
- RdsAccountPassword
Label:
en: Database Configuration
zh-cn: 数据库参数配置
- Parameters:
- PayType
- PayPeriod
Label:
en: Payment Configuration
zh-cn: 支付配置