如何通过GCP Python SDK判断Compute Engine实例是Linux还是Windows
判断GCP Compute Engine实例的操作系统(Linux/Windows)
GCE实例本身的返回字段不直接包含操作系统类型,但可以通过以下两种可靠方式判断:
方案1:通过实例绑定的许可证快速判断
Windows实例会绑定微软专属的付费许可证,许可证URL中包含windows关键词;Linux实例一般使用开源许可证或无额外付费许可证,可直接通过检查实例的licenses字段判断,无需额外API调用。
方案2:通过引导磁盘关联的镜像信息判断
如果许可证无法判断(比如自定义镜像),可以从实例的引导磁盘追溯到关联的镜像,通过镜像名称、family或官方提供的os_distribution字段确定OS类型。
修改后的完整代码
import sys import json from google.oauth2 import service_account from google.cloud import compute_v1 class VM: def __init__(self, cred_json_path): self.cred_json_path = cred_json_path self.credentials = self.create_credentials() self.page_size = 500 def create_credentials(self): return service_account.Credentials.from_service_account_file(self.cred_json_path) def list_instance(self): compute_client = compute_v1.InstancesClient(credentials=self.credentials) disk_client = compute_v1.DisksClient(credentials=self.credentials) results = [] project_id = self.credentials.project_id for _, instances in compute_client.aggregated_list(request={"project": project_id, "max_results": self.page_size}): if not instances.instances: continue for instance in instances.instances: os_type = "Unknown" # 优先通过许可证判断Windows if instance.licenses: for license_url in instance.licenses: if "windows" in license_url.lower(): os_type = "Windows" break # 许可证未命中时,通过引导磁盘的镜像判断 if os_type == "Unknown" and instance.disks: boot_disk = instance.disks[0] if boot_disk.source: # 解析磁盘资源路径的各个部分 path_parts = boot_disk.source.split('/') disk_name = path_parts[-1] # 处理跨项目磁盘的情况 disk_project = path_parts[6] if len(path_parts) > 6 else project_id disk_zone = path_parts[8] if len(path_parts) > 8 else instance.zone.split('/')[-1] try: # 获取磁盘详情,提取关联镜像 disk = disk_client.get(project=disk_project, zone=disk_zone, disk=disk_name) if disk.source_image: image_path_parts = disk.source_image.split('/') image_name = image_path_parts[-1] # 通过镜像名称关键词判断OS if "windows" in image_name.lower(): os_type = "Windows" elif any(key in image_name.lower() for key in ["ubuntu", "debian", "centos", "rhel", "suse", "linux"]): os_type = "Linux" # 可选:调用ImagesClient获取官方镜像的os_distribution字段 # image_client = compute_v1.ImagesClient(credentials=self.credentials) # image = image_client.get(project=image_path_parts[6], image=image_name) # os_type = image.os_distribution or "Unknown" except Exception as e: print(f"无法获取实例 {instance.name} 的磁盘信息: {str(e)}") # 给实例对象添加OS类型属性 setattr(instance, 'os_type', os_type) results.append(instance) return results def show(self): instance_list = self.list_instance() for instance in instance_list: # 将proto对象转为字典并追加os_type instance_data = json.loads(json.dumps(instance)) instance_data['os_type'] = instance.os_type print(json.dumps(instance_data, indent=2, ensure_ascii=False)) def main(cred_json_path): vm = VM(cred_json_path) vm.show() if __name__ == '__main__': main(sys.argv[1])
注意事项
- 权限要求:需要为服务账号添加
compute.disks.get权限(如果使用方案2),以及基础的compute.instances.list权限。 - 自定义镜像:如果使用自定义镜像,建议在创建镜像时添加包含OS类型的标签,或维护一份镜像名称与OS的映射表,避免关键词匹配失效。
- 性能优化:优先使用许可证判断,避免额外的API调用;如果需要批量处理大量实例,可以考虑批量获取磁盘/镜像信息,减少请求次数。
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

