雲伺服器ECS使用OpenAPI管理ECS:使用OpenAPI彈性建立ECS例項

琴瑟發表於2017-08-15

使用OpenAPI彈性建立ECS例項

除了可以在ECS控制檯或售賣頁建立 ECS 外,您還可以使用 OpenAPI 程式碼來彈性地建立和管理ECS。本頁面使用 Python 為例進行說明。

建立 ECS 時需關注以下 API:

  • 建立ECS例項
  • 查詢例項列表
  • 啟動ECS例項
  • 分配公網IP地址

前提條件

開通按量付費產品,您的賬戶餘額不得少於 100 元,更多的需求參見 ECS使用須知。您需要在阿里雲的費用中心確保自己的餘額充足。

建立按量雲伺服器

建立雲伺服器時的必選屬性:

  • SecurityGroupId:安全組 ID。安全組通過防火牆規則實現對一組例項的配置,保護例項的網路出入請求。在設定安全組出入規則時,建議按需開放而不要預設開放所有的出入規則。您也可以通過 ECS 控制檯建立安全組。
  • InstanceType:例項規格。參考 ECS 售賣頁的選項,介面上 1 核 2GB n1.small則入參為 ecs.n1.small。
  • ImageId:映象 ID。參考ECS控制檯的映象列表,您可以過濾系統公共映象或者自定義映象。

建立雲伺服器

如下面的程式碼所示,建立一臺經典網路的ECS,使用系統盤ssd,盤引數為cloud_ssd,選擇io優化例項optimized。

# create one after pay ecs instance.
def create_after_pay_instance(image_id, instance_type, security_group_id):
    request = CreateInstanceRequest();
    request.set_ImageId(image_id)
    request.set_SecurityGroupId(security_group_id)
    request.set_InstanceType(instance_type)
    request.set_IoOptimized(`optimized`)
    request.set_SystemDiskCategory(`cloud_ssd`)
    response = _send_request(request)
    instance_id = response.get(`InstanceId`)
    logging.info("instance %s created task submit successfully.", instance_id)
    return instance_id;

建立成功後將返回相應的例項 ID,失敗的話也會有對應的 ErrorCode。由於引數較多,您可以參考 ECS 的售賣頁進行調整。

{"InstanceId":"i-***","RequestId":"006C1303-BAC5-48E5-BCDF-7FD5C2E6395D"}

雲伺服器生命週期

對於雲伺服器的狀態操作, 請參考雲伺服器例項生命週期。

只有Stopped狀態的例項可以執行 Start 操作。也只有Running狀態的 ECS 可以執行Stop操作。查詢雲伺服器的狀態可以通過查詢例項列表傳入 InstanceId 進行過濾。在DescribeInstancesRequest時可以通過傳入一個 JSON 陣列格式的 String 就可以查詢這個資源的狀態。查詢單個例項的狀態建議使用DescribeInstances而不要使用DescribeInstanceAttribute, 因為前者比後者返回更多的屬性和內容。

下面的程式碼會檢查例項的狀態,只有例項的狀態符合入參才會返回例項的詳情。

# output the instance owned in current region.
def get_instance_detail_by_id(instance_id, status=`Stopped`):
    logging.info("Check instance %s status is %s", instance_id, status)
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    instance_detail = None
    if response is not None:
        instance_list = response.get(`Instances`).get(`Instance`)
        for item in instance_list:
            if item.get(`Status`) == status:
                instance_detail = item
                break;
        return instance_detail;

啟動雲伺服器

建立成功後的 ECS 預設狀態是Stopped。如果要啟動 ECS 例項為Running狀態,只需要傳送啟動指令即可。

def start_instance(instance_id):
    request = StartInstanceRequest()
    request.set_InstanceId(instance_id)
    _send_request(request)

停止雲伺服器

停止雲伺服器只需傳入instanceId即可。

def stop_instance(instance_id):
    request = StopInstanceRequest()
    request.set_InstanceId(instance_id)
    _send_request(request)

建立時啟動“自動啟動雲伺服器”

伺服器的啟動和停止都是一個非同步操作,您可以在指令碼建立並同時檢測雲伺服器符合狀態時執行相應操作。

建立資源後得到例項ID,首先判斷例項是否處於Stopped的狀態,如果處於Stopped狀態,下發Start伺服器的指令,然後等待伺服器的狀態變成Running。

def check_instance_running(instance_id):
    detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING)
    index = 0
    while detail is None and index < 60:
        detail = get_instance_detail_by_id(instance_id=instance_id);
        time.sleep(10)
    if detail and detail.get(`Status`) == `Stopped`:
        logging.info("instance %s is stopped now.")
        start_instance(instance_id=instance_id)
        logging.info("start instance %s job submit.")
    detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING)
    while detail is None and index < 60:
        detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING);
        time.sleep(10)
    logging.info("instance %s is running now.", instance_id)
    return instance_id;

分配公網IP

如果在建立雲伺服器的過程中,指定了公網頻寬,若需要公網的訪問許可權還要呼叫API來分配公網IP。詳情請參考:分配公網 IP 地址。

包年包月的資源建立

除了建立按量服務的雲伺服器,您的API還支援建立包年包月的伺服器。包年包月的建立和官網的建立流程不同,使用的是自動扣費的模式,也就是說您需要在建立伺服器之前確保賬號有足夠的餘額或者信用額度,在建立的時候將直接扣費。

和按量付費的 ECS 相比,只需要指定付費型別和時長即可,下面的時長為1個月。

  request.set_Period(1)    request.set_InstanceChargeType(‘PrePaid’)

建立包年包月例項的整體的程式碼如下:

# create one prepay ecs instance.
def create_prepay_instance(image_id, instance_type, security_group_id):
    request = CreateInstanceRequest();
    request.set_ImageId(image_id)
    request.set_SecurityGroupId(security_group_id)
    request.set_InstanceType(instance_type)
    request.set_IoOptimized(`optimized`)
    request.set_SystemDiskCategory(`cloud_ssd`)
    request.set_Period(1)
    request.set_InstanceChargeType(`PrePaid`)
    response = _send_request(request)
    instance_id = response.get(`InstanceId`)
    logging.info("instance %s created task submit successfully.", instance_id)
    return instance_id;

完整的程式碼

完整的程式碼如下,您可以按照自己的資源引數進行設定。

#  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
import time
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.CreateInstanceRequest import CreateInstanceRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
# 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`)
IMAGE_ID = `ubuntu1404_64_40G_cloudinit_20160727.raw`
INSTANCE_TYPE = `ecs.s2.large`  # 2c4g generation 1
SECURITY_GROUP_ID = `sg-****`
INSTANCE_RUNNING = `Running`
def create_instance_action():
    instance_id = create_after_pay_instance(image_id=IMAGE_ID, instance_type=INSTANCE_TYPE,
                                            security_group_id=SECURITY_GROUP_ID)
    check_instance_running(instance_id=instance_id)
def create_prepay_instance_action():
    instance_id = create_prepay_instance(image_id=IMAGE_ID, instance_type=INSTANCE_TYPE,
                                         security_group_id=SECURITY_GROUP_ID)
    check_instance_running(instance_id=instance_id)
# create one after pay ecs instance.
def create_after_pay_instance(image_id, instance_type, security_group_id):
    request = CreateInstanceRequest();
    request.set_ImageId(image_id)
    request.set_SecurityGroupId(security_group_id)
    request.set_InstanceType(instance_type)
    request.set_IoOptimized(`optimized`)
    request.set_SystemDiskCategory(`cloud_ssd`)
    response = _send_request(request)
    instance_id = response.get(`InstanceId`)
    logging.info("instance %s created task submit successfully.", instance_id)
    return instance_id;
# create one prepay ecs instance.
def create_prepay_instance(image_id, instance_type, security_group_id):
    request = CreateInstanceRequest();
    request.set_ImageId(image_id)
    request.set_SecurityGroupId(security_group_id)
    request.set_InstanceType(instance_type)
    request.set_IoOptimized(`optimized`)
    request.set_SystemDiskCategory(`cloud_ssd`)
    request.set_Period(1)
    request.set_InstanceChargeType(`PrePaid`)
    response = _send_request(request)
    instance_id = response.get(`InstanceId`)
    logging.info("instance %s created task submit successfully.", instance_id)
    return instance_id;
def check_instance_running(instance_id):
    detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING)
    index = 0
    while detail is None and index < 60:
        detail = get_instance_detail_by_id(instance_id=instance_id);
        time.sleep(10)
    if detail and detail.get(`Status`) == `Stopped`:
        logging.info("instance %s is stopped now.")
        start_instance(instance_id=instance_id)
        logging.info("start instance %s job submit.")
    detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING)
    while detail is None and index < 60:
        detail = get_instance_detail_by_id(instance_id=instance_id, status=INSTANCE_RUNNING);
        time.sleep(10)
    logging.info("instance %s is running now.", instance_id)
    return instance_id;
def start_instance(instance_id):
    request = StartInstanceRequest()
    request.set_InstanceId(instance_id)
    _send_request(request)
# output the instance owned in current region.
def get_instance_detail_by_id(instance_id, status=`Stopped`):
    logging.info("Check instance %s status is %s", instance_id, status)
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    instance_detail = None
    if response is not None:
        instance_list = response.get(`Instances`).get(`Instance`)
        for item in instance_list:
            if item.get(`Status`) == status:
                instance_detail = item
                break;
        return instance_detail;
# send open api request
def _send_request(request):
    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("Create ECS by OpenApi!")
    create_instance_action()
    # create_prepay_instance_action()

原文連結


相關文章