基于腾讯云自动化助手打造ImageBuilder
1. 制作镜像的痛点
在腾讯云上制作云服务器系统镜像都需要用户手动进行,主要有以下几个步骤:1.创建一台云服务器2.登录到机器上安装软件3.关机制作镜像4.同步镜像到其他地域。这个手动的过程非常繁琐、耗时、容易出错,并且一旦有软件更新就需要重新制作,整个过程又需要重复一次。
那么如何能将这个繁琐的过程自动化呢?
本文利用腾讯云自动化助手这个服务并结合CVM和镜像服务,打造类似AWS ImageBuilder的服务,能够自动化完成镜像创建、管理和多地域部署工作,在腾讯云上实现自动制作和分发镜像的功能,将繁琐耗时的工作交给机器来完成,提高工作效率。
2. 为什么使用腾讯云自动化助手
制作和分发镜像的流程如下图所示:
其中第2步安装软件,需要登录云服务器并执行命令,是最为繁琐和耗时的。而使用腾讯云自动化助手,能够在不登录云服务器的情况下,自动在服务器中执行命令,轻松完成软件安装和系统更新等工作。使得自动化制作和分发镜像这一流程成为可能。
腾讯云自动化助手工作流程如下图所示:
3. 自动化制作与分发镜像
有了腾讯云自动化助手,安装软件的问题解决了,那么打造自动化制作与分发镜像的流水线,还需要工具将整个流程串联起来。这里我们使用Postman,创建BuildImage功能的Collection,通过调用腾讯云API,来完成整个流程。
整体流程如下所示:
在介绍每个步骤的详细过程之前,需要了解一下使用Postman调用腾讯云API的方法和延时重发请求。可以参考下面两篇文章。
1. 使用Postman调用腾讯云API请参考文章https://cloud.tencent.com/developer/article/1551625
2. Postman中实现延时重发请求请参考文章https://cloud.tencent.com/developer/article/1584226
3.1. 创建云服务器并安装腾讯云自动化助手
腾讯云创建的云服务器默认没有安装腾讯云自动化助手,这里我们利用RunInstances接口中的UserData参数,传入安装自动化助手的SHELL命令,完成创建服务器同时安装腾讯云自动化助手的工作。
参考腾讯云自动化助手的《安装文档》可以查看其安装命令如下:
#!/bin/bash
mkdir -p /tmp/tat_agent/install && wget -O /tmp/tat_agent/install/tat_agent.zip https://tat-gz-1258344699.cos.ap-guangzhou.myqcloud.com/tat_agent_linux_x86_64.zip && cd /tmp/tat_agent/install && unzip -o tat_agent.zip && chmod +x install.sh && sudo sh install.sh && cd –
UserData参数的内容需要将命令进行Base64编码,编码后的UserData参数内容如下:
IyEvYmluL2Jhc2gKbWtkaXIgLXAgL3RtcC90YXRfYWdlbnQvaW5zdGFsbCAmJiB3Z2V0IC1PIC90bXAvdGF0X2FnZW50L2luc3RhbGwvdGF0X2FnZW50LnppcCBodHRwczovL3RhdC1nei0xMjU4MzQ0Njk5LmNvcy5hcC1ndWFuZ3pob3UubXlxY2xvdWQuY29tL3RhdF9hZ2VudF9saW51eF94ODZfNjQuemlwICYmIGNkIC90bXAvdGF0X2FnZW50L2luc3RhbGwgJiYgdW56aXAgLW8gdGF0X2FnZW50LnppcCAmJiBjaG1vZCAreCBpbnN0YWxsLnNoICYmIHN1ZG8gc2ggaW5zdGFsbC5zaCAmJiBjZCAt
RunInstances接口中的参数如下:
var action = "RunInstances";
pm.request.headers.add("X-TC-Action:"+action);
var params = {
"Placement": {
"Zone": pm.environment.get("zone"),
},
"ImageId": "img-8toqc6s3",// CentOS 7.4
"InstanceChargeType": "POSTPAID_BY_HOUR",
"InstanceType": "S2.SMALL1",
"SystemDisk": {
"DiskType": "CLOUD_PREMIUM",
"DiskSize": 20
},
"InstanceName": "TATBuildImage",
"LoginSettings": {
"Password": pm.environment.get("password")
},
"VirtualPrivateCloud": {
"VpcId": pm.environment.get("vpc_id"),
"SubnetId": pm.environment.get("subnet_id")
},
"InternetAccessible": {
"InternetMaxBandwidthOut": 10,
"PublicIpAssigned": true,
},
"UserData": "IyEvYmluL2Jhc2gKbWtkaXIgLXAgL3RtcC90YXRfYWdlbnQvaW5zdGFsbCAmJiB3Z2V0IC1PIC90bXAvdGF0X2FnZW50L2luc3RhbGwvdGF0X2FnZW50LnppcCBodHRwczovL3RhdC1nei0xMjU4MzQ0Njk5LmNvcy5hcC1ndWFuZ3pob3UubXlxY2xvdWQuY29tL3RhdF9hZ2VudF9saW51eF94ODZfNjQuemlwICYmIGNkIC90bXAvdGF0X2FnZW50L2luc3RhbGwgJiYgdW56aXAgLW8gdGF0X2FnZW50LnppcCAmJiBjaG1vZCAreCBpbnN0YWxsLnNoICYmIHN1ZG8gc2ggaW5zdGFsbC5zaCAmJiBjZCAt"
};
eval(pm.globals.get('TencentCloudApi')).build_request(params);
3.2. 等待云服务器运行成功
调用DescribeInstances接口,直至回包中的InstanceState=RUNNING。
这里重点介绍一下Postman中TestScript中如何实现请求重试,直至满足InstanceState=RUNNING为止。
pm.test("DescribeInstancesRunning", function () {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("Response");
pm.expect(jsonData.Response).to.not.have.property("Error");
var instanceState = jsonData.Response.InstanceSet[0].InstanceState;
if (instanceState != "RUNNING") {
pm.expect(instanceState).to.not.equal("LAUNCH_FAILED");
var delayTime = 10 * 1000;//ms
setTimeout(()=>{postman.setNextRequest("DescribeInstancesRunning");}, delayTime);
}
});
3.3. 等待腾讯云自动化助手处于Online状态
腾讯云自动化助手在安装完成后,需要处于Online状态,才能下发命令,因此这里要不断调用TAT接口DescribeAutomationAgentStatus,直至AgentStatus=Online为止。这里也是重点介绍TestScript的写法。
pm.test("DescribeAutomationAgentOnline", function () {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("Response");
pm.expect(jsonData.Response).to.not.have.property("Error");
var totalCount = jsonData.Response.TotalCount;
if (totalCount === 0){
var delayTime = 10 * 1000;//ms
setTimeout(()=>{postman.setNextRequest("DescribeAutomationAgentOnline");}, delayTime);
}
else {
var agentStatus = jsonData.Response.AutomationAgentSet[0].AgentStatus;
if (agentStatus != "Online") {
var delayTime = 10 * 1000;//ms
setTimeout(()=>{postman.setNextRequest("DescribeAutomationAgentOnline");}, delayTime);
}
}
});
3.4. 使用腾讯云自动化助手安装软件
调用TAT接口RunCommand,其中参数Content就是安装软件的命令,也需要进行Base64编码。本文中在制作的镜像中安装Docker。
原始命令如下:
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
Base64编码之后:
c3VkbyB5dW0gcmVtb3ZlIGRvY2tlciBkb2NrZXItY2xpZW50IGRvY2tlci1jbGllbnQtbGF0ZXN0IGRvY2tlci1jb21tb24gZG9ja2VyLWxhdGVzdCBkb2NrZXItbGF0ZXN0LWxvZ3JvdGF0ZSBkb2NrZXItbG9ncm90YXRlIGRvY2tlci1lbmdpbmUKc3VkbyB5dW0gaW5zdGFsbCAteSB5dW0tdXRpbHMKc3VkbyB5dW0tY29uZmlnLW1hbmFnZXIgLS1hZGQtcmVwbyBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvY2VudG9zL2RvY2tlci1jZS5yZXBvCnN1ZG8geXVtIGluc3RhbGwgLXkgZG9ja2VyLWNlIGRvY2tlci1jZS1jbGkgY29udGFpbmVyZC5pbw==
在调用RunCommand接口后,会得到执行命令的InvocationId,接下来需要调用DescribeInvocations接口,直至命令执行成功,TestScript可以参考DescribeInstances接口TestScript的写法。
3.5. 制作镜像
在软件安装成功之后,就可以调用CVM接口CreateImage来制作镜像了。
接口的参数如下:
var action = "CreateImage";
pm.request.headers.add("X-TC-Action:"+action);
var timestamp = Math.round(Date.now() / 1000);
var params = {
"ImageName": "docker-image" + timestamp.toString(),
"ImageDescription": "docker-image",
"InstanceId": pm.environment.get("instance_id"),
"ForcePoweroff": "TRUE"
};
eval(pm.globals.get('TencentCloudApi')).build_request(params);
CreateImage接口调用成功后会返回ImageId。
3.6. 等待镜像制作成功
调用CVM接口DescribeImages,直至ImageState=NORMAL,表示镜像制作成功。接口的入参传入ImageId即可。TestScript与DescribeInstances接口的类似,如下所示:
pm.test("DescribeImagesCreateSuccess", function () {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("Response");
pm.expect(jsonData.Response).to.not.have.property("Error");
var imageState = jsonData.Response.ImageSet[0].ImageState;
if (imageState != "NORMAL") {
pm.expect(image_state).to.not.equal("CREATEFAILED");
var delayTime = 10 * 1000;
setTimeout(()=>{postman.setNextRequest("DescribeImagesCreateSuccess");}, delayTime);
}
});
3.7. 销毁云服务器
在镜像制作成功后,我们就可以调用CVM的接口TerminateInstances,销毁服务器,来节省成本。
3.8. 多地域同步镜像
为了在多个地域都能使用制作成功的镜像,我们调用CVM的接口SyncImages,分发到不同的地域,然后调用DescribeImages直至ImageState有SYNCING变成NORMAL即可。
var action = "SyncImages";
pm.request.headers.add("X-TC-Action:"+action);
var params = {
"ImageIds": [pm.environment.get("image_id")],
"DestinationRegions": [
"ap-beijing",
"ap-shanghai",
"ap-nanjing"
]
};
eval(pm.globals.get('TencentCloudApi')).build_request(params);
4. 镜像制作和同步结果
根据上一节的描述,我们可以构建如下的Postman Collection。
下图展示了广州地域镜像的制作结果和北京,南京,上海三个地域镜像分发的结果。
5. 总结
使用腾讯云自动化助手无需连接实例就可以自动批量执行 Shell 命令,完成软件的安装,再结合腾讯云已有的制作镜像和同步镜像的功能。我们现在很容易就能实现自动化制作和分发镜像的功能。让手动制作镜像的过程成为历史,大大地提高的工作效率。在本文的基础上,还可以利用自动化助手执行命令,来验证制作的镜像是否符合预期,加上这个功能后就跟ImageBuilder的功能完全一致了。
6. 参考资料
腾讯云自动化助手:https://cloud.tencent.com/document/product/1340/50752
安装自动化助手:https://cloud.tencent.com/document/product/1340/51945
执行命令RunCommand:https://cloud.tencent.com/document/product/1340/52676
查询自动化助手客户端状态DescribeAutomationAgentStatus:https://cloud.tencent.com/document/product/1340/52682
查询自动化助手执行活动详情DescribeInvocations:https://cloud.tencent.com/document/product/1340/52679
创建云服务器RunInstances:https://cloud.tencent.com/document/product/213/15730
查看实例DescribeInstances:https://cloud.tencent.com/document/product/213/15728
退还实例TerminateInstances:https://cloud.tencent.com/document/product/213/15723
创建镜像CreateImage:https://cloud.tencent.com/document/api/213/16726
同步镜像SyncImages:https://cloud.tencent.com/document/api/213/15711
查询镜像DescribeImages: https://cloud.tencent.com/document/api/213/15715