前言
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
1234567891011121314151617181920212223242526272829def 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#L128break注意:在GCP之中, 没有直接列出所有Zone的instance的方法。 zone必须指定。因此如果你的机器在多个zone, 要么简单粗暴直接hardcode, 要么通过下面的参考脚本列出所有的zone
参考:https://cloud.google.com/compute/docs/reference/rest/v1/zones/list
1234567891011121314151617181920212223from pprint import pprintfrom googleapiclient import discovery# 注意:下面这个方式我没有试用成功,credentials的使用方法可以参考上面的脚本from oauth2client.client import GoogleCredentialscredentials = 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)

文章评论