[GCP工具集] 省钱小工具:自动启动抢占型机器
2015 年 9 月 16 日
前言
GCP的抢占型(preemptible)机器就类似与AWS的Spot Instance(竞价型机器)。同样的配置,抢占型机器机器能便宜差不多1/3!
但是有一个物理限制:每次开机最长24小时就会被关机。
因此,如果我们有一个小工具能监控这些机器,并且自动启动,岂不美哉?
方式1:使用实例组( Instance Group Manager )
原理:在创建实例组的时候设置 实例数下限
。比如可以设置成 1
. 当这个实例被关闭之后,实例组会 将其删除并重新创建 。
操作步骤:(因为不是重点, 在此简单写写)
- 创建
实例模板
. 这一步就按照正常的要求创建就好了。
补充: 如何使用当前实例作为模板?
回答:先把当前实例做成一个快照(snapshot), 在创建模板的时候, 设置使用相应的快照来创建即可
-
创建
实例组
。看了一下相关设定, 正常设置即可。
方式2:自建监控+启动的Python脚本
-
安装相应的类库
pip install -U google-api-python-client
-
准备credentials文件
-
在你的定时调度任务调用下面的python script
def start_instance_if_stopped(name=None, ip=None): """ 如果目标机器(name or ip)关闭了,将其启动 :param name: :param ip: :return: """ credentials = service_account.Credentials.from_service_account_file( 'your-service-account-file.json', ) compute = googleapiclient.discovery.build(serviceName='compute', version='v1', credentials=credentials) project = "your-project-id" avaiable_zones = ["us-east4-c", "us-east4-a", "us-east4-b"] for zone in avaiable_zones: result = compute.instances().list(project=project, zone=zone).execute() instances = result['items'] if 'items' in result else [] for instance in instances: cur_name = instance['name'] cur_ip = instance['networkInterfaces'][0]['networkIP'] status = instance['status'] if (name == cur_name or ip == cur_ip) and status != "RUNNING": print("##################", instance) compute.instances().start(project=project, zone=zone, instance=cur_name).execute() # TODO:可以参考这个实现,等待操作完成 https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/compute/api/create_instance.py#L128 break
注意:在GCP之中, 没有直接列出所有Zone的instance的方法。 zone必须指定。因此如果你的机器在多个zone, 要么简单粗暴直接hardcode, 要么通过下面的参考脚本列出所有的zone
参考: https://cloud.google.com/compute/docs/reference/rest/v1/zones/list
from pprint import pprint from googleapiclient import discovery # 注意:下面这个方式我没有试用成功,credentials的使用方法可以参考上面的脚本 from oauth2client.client import GoogleCredentials credentials = GoogleCredentials.get_application_default() service = discovery.build('compute', 'v1', credentials=credentials) # Project ID for this request. project = 'my-project' # TODO: Update placeholder value. request = service.zones().list(project=project) while request is not None: response = request.execute() for zone in response['items']: # TODO: Change code below to process each `zone` resource: pprint(zone) request = service.zones().list_next(previous_request=request, previous_response=response)