ECS の重要な機能の一つがオンデマンドリソースの作成です。 サービスピークタイム中に要求に応じて弾性的にカスタムリソースを作成し、サービスコンピューティングが完了すればカスタムリソースをリリースすることができます。 ここでは、簡単に ECS インスタンスをリリースして弾力性を得る方法について説明します。

以下の API について触れています。

ECS インスタンスがリリースされると、インスタンスに使用された物理リソースがディスクやスナップショットを含め、再利用されます。 そのインスタンスのデータは完全に消失し、二度と復元できません。 データを保持しておきたい場合は、ECS インスタンスをリリースする前に、ディスクのスナップショットを作成しておくことを推奨します。 スナップショットは新規 ECS インスタンスの作成に直接使うことができます。

ECS インスタンスをリリースするためには、最初にインスタンスを停止しなければなりません。 ECS インスタンス停止後に他のアプリケーションが影響を受けた場合、インスタンスを再起動します。

ECS インスタンスの停止

ECS インスタンスを停止させるためには、インスタンスの課金方法に関係なく、"StopInstance" インターフェイスを使用します。 停止コマンドは以下のとおりです。 "ForceStop" パラメーターが "true" に設定されている場合は、ECS インスタンスがすぐに停止します。ただし、停電時と同様、データがディスクに必ずしも書き込まれるわけではありません。 したがって、インスタンスをリリースしたい場合は、"ForceStop" を "true" に設定します。

def stop_instance(instance_id, force_stop=False):
    '''
    stop one ecs instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force_stop: if force stop is true, it will force stop the server and not ensure the data
    write to disk correctly.
    :return:
    '''
    request = StopInstanceRequest()
    request.set_InstanceId(instance_id)
    request.set_ForceStop(force_stop)
    logging.info("Stop %s command submit successfully.", instance_id)
    _send_request(request)

ECS インスタンスのリリース

ECS インスタンスのステータスが "停止" 以外のときにリリースした場合、エラーが発生します。

{"RequestId":"3C6DEAB4-7207-411F-9A31-6ADE54C268BE","HostId":"ecs-cn-hangzhou.aliyuncs.com","Code":"IncorrectInstanceStatus","Message":"The current status of the resource does not support this operation."}

ECS インスタンスのステータスが "停止" であるときに、インスタンスをリリースすることができます。 その API には、2 つのリクエストパラメーターがあります。

  • InstanceId: インスタンス ID
  • Force: このパラメーターが ”true” に設定されている場合、ステータスが "停止" になっていない場合でも、ECS インスタンスは強制的にリリースされます。 このパラメーターを設定するときは、ご注意ください。 誤ってリリースすると、サービスに影響を与える可能性があります。

ECS インスタンスをリリースするためのリクエストは、以下のとおりです。

def release_instance(instance_id, force=False):
    '''
    delete instance according instance id, only support after pay instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force:
    if force is false, you need to make the ecs instance stopped, you can
    execute the delete action.
    If force is true, you can delete the instance even the instance is running.
    :return:
    '''
    request = DeleteInstanceRequest();
    request.set_InstanceId(instance_id)
    request.set_Force(force)
    _send_request(request)

ECS インスタンスが正常にリリースされると、以下のレスポンスが返されます。

{"RequestId":"689E5813-D150-4664-AF6F-2A27BB4986A3"}

ECS インスタンスの自動リリース時間の設定

ECS インスタンスの自動リリース時間を設定することで、インスタンス管理を簡単にすることができます。 設定時間に到達した時に、Alibaba Cloud はお客様の ECS インスタンスを自動的にリリースします。 ECS インスタンスの自動リリース時間を設定するためには ”ModifyInstanceAutoReleaseTime” を使用します。

自動リリース時間は、ISO8601 標準規格の UTC 時間で記述します。 フォーマットは ”yyyy-MM-ddTHH:mm:ssZ” です。 秒 (ss) が 00 でない場合は、現在の分 (mm) から開始するように自動的に設定されます。 自動リリース時間は、現在時刻から少なくとも 30 分以上後であり、現在時刻から 3 年を超えないようにします。
def set_instance_auto_release_time(instance_id, time_to_release = None):
    '''
    setting instance auto delete time
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param time_to_release: if the property is setting, such as '2017-01-30T00:00:00Z'
    it means setting the instance to be release at that time.
    if the property is None, it means cancel the auto delete time.
    :return:
    '''
    request = ModifyInstanceAutoReleaseTimeRequest()
    request.set_InstanceId(instance_id)
    if time_to_release is not None:
        request.set_AutoReleaseTime(time_to_release)
    _send_request(request)

時間を設定するために "set_instance_auto_release_time('i-1111', '2017-01-30T00:00:00Z')" コマンドを実行します。

その後、自動リリース時間の照会に "DescribeInstances" を使用できます。

def describe_instance_detail(instance_id):
    '''
    describe instance detail
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :return:
    '''
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            return instance_list[0]
def check_auto_release_time_ready(instance_id):
    detail = describe_instance_detail(instance_id=instance_id)
    if detail is not None:
        release_time = detail.get('AutoReleaseTime')
        return release_time

自動リリースのキャンセル

サービスの変更によって自動リリースをキャンセルしたい場合、自動リリース時間を "null" に変更するために以下のコマンドを実行します。

set_instance_auto_release_time('i-1111')

完全なサンプルコード

ECS インスタンスをリリースするときは、注意して進めます。
# coding=utf-8
# if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
# if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
# make sure the sdk version is 2.1.2, you can use command 'pip show aliyun-python-sdk-ecs' to check
import json
import logging
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526. DeleteInstanceRequest import DeleteInstanceRequest
from aliyunsdkecs.request.v20140526. DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526. ModifyInstanceAutoReleaseTimeRequest import \
    ModifyInstanceAutoReleaseTimeRequest
from aliyunsdkecs.request.v20140526. StopInstanceRequest import StopInstanceRequest
# configuration the log output formatter, if you want to save the output to file,
# append ",filename='ecs_invoke.log'" after datefmt.
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S')
clt = client.AcsClient('Your Access Key Id', 'Your Access Key Secrect', 'cn-beijing')
def stop_instance(instance_id, force_stop=False):
    '''
    stop one ecs instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force_stop: if force stop is true, it will force stop the server and not ensure the data
    write to disk correctly.
    :return:
    '''
    request = StopInstanceRequest()
    request.set_InstanceId(instance_id)
    request.set_ForceStop(force_stop)
    logging.info("Stop %s command submit successfully.", instance_id)
    _send_request(request)
def describe_instance_detail(instance_id):
    '''
    describe instance detail
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :return:
    '''
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get('Instances').get('Instance')
        if len(instance_list) > 0:
            return instance_list[0]
def check_auto_release_time_ready(instance_id):
    detail = describe_instance_detail(instance_id=instance_id)
    if detail is not None:
        release_time = detail.get('AutoReleaseTime')
        return release_time
def release_instance(instance_id, force=False):
    '''
    delete instance according instance id, only support after pay instance.
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param force:
    if force is false, you need to make the ecs instance stopped, you can
    execute the delete action.
    If force is true, you can delete the instance even the instance is running.
    :return:
    '''
    request = DeleteInstanceRequest();
    request.set_InstanceId(instance_id)
    request.set_Force(force)
    _send_request(request)
def set_instance_auto_release_time(instance_id, time_to_release = None):
    '''
    setting instance auto delete time
    :param instance_id: instance id of the ecs instance, like 'i-***'.
    :param time_to_release: if the property is setting, such as '2017-01-30T00:00:00Z'
    it means setting the instance to be release at that time.
    if the property is None, it means cancel the auto delete time.
    :return:
    '''
    request = ModifyInstanceAutoReleaseTimeRequest()
    request.set_InstanceId(instance_id)
    if time_to_release is not None:
        request.set_AutoReleaseTime(time_to_release)
    _send_request(request)
    release_time = check_auto_release_time_ready(instance_id)
    logging.info("Check instance %s auto release time setting is %s. ", instance_id, release_time)
def _send_request(request):
    '''
    send open api request
    :param request:
    :return:
    '''
    request.set_accept_format('json')
    try:
        response_str = clt.do_action(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)
if __name__ == '__main__':
    logging.info("Release ecs instance by Aliyun OpenApi!")
    set_instance_auto_release_time('i-1111', '2017-01-28T06:00:00Z')
    # set_instance_auto_release_time('i-1111')
    # stop_instance('i-1111')
    # release_instance('i-1111')
    # release_instance('i-1111', True)

ECS の他の API 操作については、「ECS API の操作」をご参照ください。