43

[GCP工具集] 省钱小工具:自动启动抢占型机器

 4 years ago
source link: https://www.tuicool.com/articles/3aYzyaj
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

GCP的抢占型(preemptible)机器就类似与AWS的Spot Instance(竞价型机器)。同样的配置,抢占型机器机器能便宜差不多1/3!

但是有一个物理限制:每次开机最长24小时就会被关机。

因此,如果我们有一个小工具能监控这些机器,并且自动启动,岂不美哉?

方式1:使用实例组( Instance Group Manager )

原理:在创建实例组的时候设置 实例数下限 。比如可以设置成 1 . 当这个实例被关闭之后,实例组会 将其删除并重新创建

操作步骤:(因为不是重点, 在此简单写写)

  1. 创建 实例模板

    . 这一步就按照正常的要求创建就好了。

    补充: 如何使用当前实例作为模板?

    回答:先把当前实例做成一个快照(snapshot), 在创建模板的时候, 设置使用相应的快照来创建即可

  2. 创建 实例组

    看了一下相关设定, 正常设置即可。

方式2:自建监控+启动的Python脚本

  1. 安装相应的类库

    pip install -U google-api-python-client

  2. 准备credentials文件

    JZfUby7.png!web

  3. 在你的定时调度任务调用下面的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)
     
    

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK