This topic describes how to create a service in Compute Nest that combines a container application with ApsaraDB RDS.
Prerequisites
You have an existing Container Service for Kubernetes (ACK) cluster. For more information, see Create an ACK cluster.
Procedure
This example uses a basic container image with a preset database initialization script. During service instance creation, the database is automatically initialized, and a record containing the name ComputeNest is inserted. After the service instance is created, you can query the application to get the result Hello ComputeNest. The procedure includes the following steps:
Step 1: Prepare a container image
Before you create the service, prepare a container image and upload it to the private image repository in Compute Nest for service providers.
-
Prepare a container image.
Use one of the following methods to prepare a local container image.
-
Use a container image provided by Alibaba Cloud.
docker pull compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/bestpractice/springboot-demo:demo -
Create a container image from source code.
-
Get the image source code and modify it based on your business requirements.
-
In the root directory of the source code, where the
pom.xmlfile is located, use Maven to package the application into a JAR file. The JAR file is automatically generated in thetargetdirectory.mvn install -
Build the image.
After the build is complete, the image is available on your local machine.
docker build --build-arg JAR_FILE=target/\*.jar -t <your-image-tag> .
-
-
-
Upload the container image to the Compute Nest image repository.
-
Obtain the access credentials for the Compute Nest image repository and the Docker commands to tag and push the image.
-
Log on to the Compute Nest console.
-
In the left-side navigation pane, choose Service Deployment Package, and then click Create Deployment Package.
-
On the Create deployment package page, under Deployment Package Type, click Obtain Access Credential. In the dialog box that appears, copy the commands to log on to the image repository, tag the image, and push it.
-
In your Docker CLI, log on to the image repository, tag the image, and push the image.
docker login compute-nest-registry.cn-hangzhou.cr.aliyuncs.com --username=cr_temp_user --password=eyJhdXRoVG9rZW5JZGVudGlmaWVyIjoiMTY3MDkzODgyMjU4xxx WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded docker tag computenest/springbootdemo compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/1563457855xxx/springbootdemo:latest docker push compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/1563457855xxx/springbootdemo:latest The push refers to repository [compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/1563457855xxx/springbootdemo] 3a3d2d6d0277: Layer already exists ceaf9e1ebef5: Layer already exists 9b9b7f3d56a0: Layer already exists f1b5933fe4b5: Layer already exists latest: digest: sha256:1eff431284561801f5d3e88f84a68c99c338e5d2122a9ebe096c2d1128e5f913 size: 1159
-
-
Step 2: Create a container image deployment package
Before you create the service, you must create and publish the container image deployment package.
Log on to the Compute Nest console.
-
In the left-side navigation pane, choose Service Deployment Package. On the Packages page, click Create Deployment Package.
-
On the Create deployment package page, configure the parameters in the Basic Information, Deployment Package Content, and Distribution Settings sections.
Parameter
Example
Deployment package name
springboot-container-deployment
Deployment package version name
springboot-container-deployment-v1
Deployment package description
Springboot container image deployment package
Deployment package type
Container image
Select image
-
Image Name: springbootdemo
-
Image Version: latest
-
-
Click Publish Deployment Package.
After you click Publish Deployment Package, you can go to the Packages page. Click the name of the deployment package to view its deployment progress on the details page.
When the status changes to Available, the deployment package is published.
Step 3: Create a service
Log on to the Compute Nest console.
-
In the left-side navigation pane, click My Services. On the My Services page, click the Created Services tab, and then click Create Service.
-
On the Create Service page, configure the parameters as required.
This section describes only the key parameters for this example. For details on other parameters, see Create a private service.
-
In the Template section, enter the service template in the Template Content field. The following snippets highlight key configurations in the template. For the complete template, see Template example.
-
To deploy the container, the ACK cluster must pull the image from the private Compute Nest image repository. To enable this, the template defines a Kubernetes Secret of the type
dockerconfigjsonand populates it using the Compute Nest identifier {{ computenest::acr::dockerconfigjson }}.ClusterApplication: DependsOn: Database Type: ALIYUN::CS::ClusterApplication Properties: ClusterId: Ref: ClusterId YamlContent: Fn::Sub: - | # Omitted for brevity... apiVersion: v1 data: .dockerconfigjson: {{ computenest::acr::dockerconfigjson }} kind: Secret metadata: name: computenestrepo namespace: ${NameSpace} type: kubernetes.io/dockerconfigjson # Omitted for brevity... -
The template uses the {{ computenest::acrimage::springbootdemo }} identifier to associate the
imageproperty with the Compute Nest deployment package.ClusterApplication: DependsOn: Database Type: ALIYUN::CS::ClusterApplication Properties: ClusterId: Ref: ClusterId YamlContent: Fn::Sub: - | # Omitted for brevity... 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 # Omitted for brevity...
-
-
In the Deploy Application section, click Associate Container Image to link the created image deployment package. In the Associate container image dialog box, the identifier field is automatically populated with
{{ computenest::acrimage::springbootdemo }}from the template. From the Select deployment package drop-down list, select springboot-container-deployment. From the version drop-down list, select v1. Click Save, and then click OK.
-
-
Click Save Service.
-
Test the service.
After you save the service, you must test the service instance to ensure it works correctly. For more information, see Test a service.
-
Publish the service.
After the service passes all tests, submit it for review. Once approved, you can publish the service. For more information, see Publish a service.
Step 4: Create an instance and query the database
In this step, the service provider, acting as a user, validates that the container image configured in the service deploys correctly to the service instance.
-
Create a service instance.
For more information, see Create a private service instance.
A successful deployment of the service instance confirms that the deployment package was also deployed successfully.
-
Query the database.
Use the kubectl CLI to find the LoadBalancer service endpoint. Then, use the public IP address to access the application and view the result.
~ % kubectl get svc -n springboot-demo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE springboot-demo-svc LoadBalancer 10.xxx 47.xxx 80:31171/TCP 26m ~ % wget -cq http://47.xxx -O - Hello ComputeNest
Template example
The following sections list the required Resource Orchestration Service (ROS) resources and functions for this scenario.
The following is the complete template for this example.
ROSTemplateFormatVersion: '2015-09-01'
Description:
en: Deploys an ApsaraDB RDS instance and a container-based application to an ACK cluster. The application uses the RDS instance for persistent storage.
zh-cn: 新建一个RDS实例并向ACK中部署容器应用。容器应用使用RDS实例作为数据库。
Parameters:
ZoneId:
Type: String
AssociationProperty: ALIYUN::ECS::Instance:ZoneId
Description:
en: The ID of the availability zone.<br><b>Note: <font color='blue'>Before you make a selection, confirm that the availability zone has the required instance types.</font></b>
zh-cn: 可用区ID
Label:
en: VSwitch availability 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, in months.
zh-cn: 购买时长,单位(月)
Label:
en: The subscription period, in 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 instance specification
Type: String
Description:
zh-cn: 根据数据库引擎的类型和可用的区域支持选择实例规格
en: 'Select an instance specification that is supported by the database engine and availability zone.'
Default: rds.mysql.s2.large
RdsInstanceStorage:
Label: Disk size
Type: Number
Description:
zh-cn: RDS 实例大小,范围为 20 - 2000,每 5 个增量,单位为 GB
en: The disk size for the RDS instance, in GB. The value must be between 20 and 2000, in increments of 5.
MinValue: 20
MaxValue: 2000
ConstraintDescription: The disk size for the RDS instance, in GB. The value must be between 20 and 2000, in increments of 5.
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 password must be 8 to 32 characters in length and contain at least three of the following character types: uppercase letters, lowercase letters, digits, and special characters. The supported special characters are: !@#$&%^*()_+-= .
ClusterId:
Type: String
Description:
en: >-
The ID of the ACK cluster where the application is deployed.
zh-cn: >-
部署应用程序的K8s集群ID
AllowedPattern: '[0-9a-z]+$'
Label:
en: Kubernetes cluster ID
zh-cn: K8s集群ID
AssociationProperty: ALIYUN::CS::Cluster::ClusterId
ConstraintDescription:
en: >-
Must contain only lowercase letters and digits.
zh-cn: '集群ID必须由小写字母或者数字组成'
NameSpace:
Type: String
Description:
en: >-
The namespace in the ACK cluster where the application is 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: 支付配置