【转】腾讯云 API 3.0实践分享(下)

2018-07-10 23:04:31 浏览数 (1)

原文来自:腾讯云计算产品团队

原文地址:https://cloud.tencent.com/developer/article/1155254

转载原因:非常不错的实践教程,竟然还有续集,哈哈哈哈


当前腾讯云的产品的 API 陆陆续续都在切换到 3.0了,为了帮助用户快速掌握 API 3.0的用法,上周分享了《腾讯云 API 3.0实践分享》一文,不少用户都说文章帮助很大,然而又提出了一些新的疑问。那么本文将结合实际用户的需求,再继续进行实践例子的分享,希望对大家有帮助。

Offset 和 Limit

以查看实例列表为例分别对Offset 和 Limit 进行例子的分享。

背景说明

已知,调用 DescribeInstances 获取实例列表时,默认是返回 20 条数据。而如果你希望返回更多的实例数量,你可以通过修改 Limit 的值来改变返回数量。然而,Limit 的最大值也只是 100 。当你企业中有超过 100 台的云服务器时,怎么获取所有的云服务器呢?

示例代码

代码语言:javascript复制
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
代码语言:javascript复制
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 的用法,以及为了能够方便用户自主的解决,后面也会列出简单的自我排查方案。

依旧是 创建实例 的 API ,UserData 的说明如下:

UserData说明

示例代码

代码语言:javascript复制
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}
代码语言:javascript复制
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》哈。

验证结果

执行代码

登录服务器验证

自我排错

1、自定义 Shell 脚本必须以 #! 字符以及指向要读取脚本的解释器的路径 (通常为 /bin/bash) 开头(注:很多用户习惯性让首行为空行,这个也是不行的)。

2、执行自定义脚本需要额外的耗时,如果过早的登录有可能脚本还在执行中。请在实例创建出来之后,适当的等几分钟之后再确认脚本是否有被正确的执行。

3、登录实例,手工执行脚本,确认脚本编写的准确性:

代码语言:javascript复制
登录实例
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 名称是 查看实例列表。

示例代码

创建 CVM 的实例代码上面已经有了,我就不重复了,下面是通过实例 ID 获取内网 IP的例子。

代码语言:javascript复制
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 的函数和 这个函数串起来。

代码语言:javascript复制
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 还没那么快分配好,如果立即执行的话,可能会获取不到。

上面的用法仅供参考哈,需要结合实际的场景调整逻辑哈。本次分享到此,希望对大家有帮助。感谢大家的浏览。


广告时间:

腾讯云API代码生成工具:

地址1:http://www.apihelper.cn/

地址2:http://www.apicoder.cn/

腾讯云API官方交流群:711269805

0 人点赞