当前腾讯云的产品的 API 陆陆续续都在切换到 3.0 了, 为了帮助用户快速掌握 API 3.0 的用法, 上周分享了腾讯云 API 3.0 实践分享 https://cloud.tencent.com/developer/article/1151836 一文, 不少用户都说文章帮助很大, 然而又提出了一些新的疑问. 那么本文将结合实际用户的需求, 再继续进行实践例子的分享, 希望对大家有帮助.
Offset 和 Limit
以查看实例列表 https://cloud.tencent.com/document/product/213/15728 为例分别对 Offset 和 Limit 进行例子的分享.
背景说明
已知, 调用 DescribeInstances 获取实例列表时, 默认是返回 20 条数据. 而如果你希望返回更多的实例数量, 你可以通过修改 Limit 的值来改变返回数量. 然而, Limit 的最大值也只是 100 . 当你企业中有超过 100 台的云服务器时, 怎么获取所有的云服务器呢?
示例代码
- def DescribeInstance_b(Region, secretId, secretKey):
- cred = credential.Credential(secretId, secretKey)
- client = cvm_client.CvmClient(cred, Region)
- request = models.DescribeInstancesRequest()
- request.Limit = 50
- result = client.DescribeInstances(request)
- result_srt = result.to_json_string()
- result_dic = json.loads(result_srt)
- if "Error" in result_dic.keys():
- return_data = []
- else:
- return_data = result_dic["InstanceSet"]
- TotalCount = int(result_dic['TotalCount'])
- offset = int(TotalCount / 50) if TotalCount % 50 == 0 else int(TotalCount / 50) + 1
- for i in range(2, offset + 1):
- new_keys = (i - 1) * 50
- return_data += DescribeInstance_a(Region, secretId, secretKey, new_keys)
- return return_data
- def DescribeInstance_a(Region, secretId, secretKey, Offset):
- cred = credential.Credential(secretId, secretKey)
- client = cvm_client.CvmClient(cred, Region)
- request = models.DescribeInstancesRequest()
- request.Offset = Offset
- request.Limit = 50
- result = client.DescribeInstances(request)
- result_srt = result.to_json_string()
- result_dic = json.loads(result_srt)
- if "Error" in result_dic.keys():
- return_data = []
- else:
- return_data = result_dic["InstanceSet"]
- return return_data
说明: 由于我的环境中单个区域没有超过 100 台的, 所以我在示例代码中 Limit 就设置为 50 了, 在真实应用场景中, 可以设置最大为 100 哈.
返回结果
返回结果
从上面截图中可以看到, 如果只运行 DescribeInstance_a, 返回的数量只有 50, 因为我在函数中设置了 Limit 为 50. 而运行 DescribeInstance_b 返回的结果为 71 条, 这样也验证了上面函数生效了, 把当前地域的实例都加在一起返回了.
创建 CVM 时注入 UserData
当前我们已支持在创建实例的时候让用户传自定义脚本, 并实现首次开机启动的时候在实例内部执行这个自定义脚本, 这样可方便用户在创建好 CVM 之后用脚本做一些初始化.
然而, 在该功能上线之后, 有陆续收到反馈由于用户对于用法不熟悉以及本身的一些错误操作导致自定义脚本没有被正常的执行, 为了帮助用户快速掌握 UserData 的用法, 以及为了能够方便用户自主的解决, 后面也会列出简单的自我排查方案.
依旧是 创建实例 https://cloud.tencent.com/document/product/213/15730 的 API ,UserData 的说明如下:
UserData 说明
示例代码
- def RunInstance(Region, secretId, secretKey, shell_script):
- cred = credential.Credential(secretId, secretKey)
- client = cvm_client.CvmClient(cred, Region)
- request = models.RunInstancesRequest()
- request.InstanceChargeType = 'POSTPAID_BY_HOUR'
- request.ImageId = "img-8toqc6s3"
- request.InstanceType = 'S2.SMALL1'
- request.SecurityGroupIds = ['sg-33m88gy7']
- request.UserData = base64.b64encode(shell_script)
- request.Placement = {'Zone': 'ap-guangzhou-2'}
- request.VirtualPrivateCloud = {'VpcId': 'vpc-kwpf6vnr',
- 'SubnetId': 'subnet-ojajnp4k',
- }
- result = client.RunInstances(request)
- result_srt = result.to_json_string()
- result_dic = json.loads(result_srt)
- return {'result': True, 'data': result_dic}
- shell_script = """#!/bin/bash
- tf=`mktemp /tmp/userdata.XXXXXX`
- cat> $tf <<- EOF
- # The following lines are added by cloud-init userdata
- nameserver 8.8.8.8
- nameserver 8.8.4.4
- EOF
- cat $tf> /etc/resolv.conf
- rm -f $tf
- """
这个地方要注意一下哈, 首行不能是空行哈.
错误写法
正确写法
补充说明: 该示例仅仅为示例哈, 修改 DNS 会引发很多问题哈. 如果用户真的有需要将 CVM 的 DNS 修改为自定义的 DNS 请参考文章在腾讯云上使用自建 DNS https://cloud.tencent.com/developer/article/1024820 哈.
验证结果
执行代码
登录服务器验证
自我排错
1, 自定义 Shell 脚本必须以 #! 字符以及指向要读取脚本的解释器的路径 (通常为 /bin/bash) 开头 (注: 很多用户习惯性让首行为空行, 这个也是不行的).
2, 执行自定义脚本需要额外的耗时, 如果过早的登录有可能脚本还在执行中. 请在实例创建出来之后, 适当的等几分钟之后再确认脚本是否有被正确的执行.
3, 登录实例, 手工执行脚本, 确认脚本编写的准确性:
登录实例
cd /var/lib/cloud/instance/scripts/
vim part-001 查看脚本内容, 确认脚本首行是否是 #!/bin/bash
sh -x part-001 手工执行脚本, 验证脚本的准确性
userdata 脚本示例
分享的脚本
访问地址为: https://github.com/lilinux/tencentcloud-userdata
使用之前, 请先阅读 README.md 哈.
创建 CVM 后快速拿到 IP
目前创建 CVM 的 API 没有直接返回内网 IP 地址, 而是返回了实例 ID. 实现的思路是通过实例 ID 去获取其内网 IP, 用到的 API 名称是 查看实例列表 https://cloud.tencent.com/document/product/213/15728 .
示例代码
创建 CVM 的实例代码上面已经有了, 我就不重复了, 下面是通过实例 ID 获取内网 IP 的例子.
- def get_instance_ip(Region, secretId, secretKey, instance_id):
- cred = credential.Credential(secretId, secretKey)
- client = cvm_client.CvmClient(cred, Region)
- request = models.DescribeInstancesRequest()
- request.InstanceIds = instance_id
- result = client.DescribeInstances(request)
- result_srt = result.to_json_string()
- result_dic = json.loads(result_srt)
- if "Error" in result_dic.keys():
- return_data = []
- else:
- return_data = result_dic["InstanceSet"]
- return return_data
此外还需要一个函数来将创建 CVM 的函数和 这个函数串起来.
- def create_cvm(Region, secretId, secretKey):
- id = RunInstance(Region, secretId, secretKey, shell_script)
- instance_id = id['data']['InstanceIdSet']
- time.sleep(10)
- result = get_instance_ip(Region, secretId, secretKey, instance_id)
- return result
上面代码中我添加了一句 time.sleep(10), 意思是 10s 钟之后再去获取 IP. 这是因为有可能生产了实例 ID 之后, 内网 IP 还没那么快分配好, 如果立即执行的话, 可能会获取不到.
上面的用法仅供参考哈, 需要结合实际的场景调整逻辑哈. 本次分享到此, 希望对大家有帮助. 感谢大家的浏览.
来源: https://www.qcloud.com/developer/article/1155254