谷歌云如何在使用 Python api 创建实例时启动服务?
Posted
技术标签:
【中文标题】谷歌云如何在使用 Python api 创建实例时启动服务?【英文标题】:Google cloud how to start service when creating instance using Python api? 【发布时间】:2021-10-06 14:58:42 【问题描述】:我在创建实例并使用 Python Google Cloud 的 api 启动它们时遇到了很多麻烦。
基本上,我首先创建了所有虚拟机并设置了服务。然后,一旦一切正常,我停止了虚拟机并创建了Image
,这样我就可以使用图像轻松创建实例了。
[编辑] 我觉得很高兴补充一下:
前端实例:nextjs 后端实例:nodejs 数据库实例:postgresql这是我的 Python 脚本:
import googleapiclient.discovery
import argparse
import os
import time
backend_script = """
#! /bin/bash
cd /mse-tsm-cloudsys-lab1/api/
sudo npm install
sudo npx knex migrate:latest
sudo npx knex seed:run
sudo npm run start
"""
frontend_script = """
#! /bin/bash
cd /mse-tsm-cloudsys-lab1/app/
sudo npm install
sudo npm run build
sudo npm run start
"""
def create_instance(compute, project, zone, name, image, machine, ip, ip_public, tags=[], metadata=[]):
config =
'name': name,
'machineType': "zones/%s/machineTypes/%s" % (zone, machine),
'disks': [
'initializeParams':
"sourceImage": image
,
"boot": True
],
'tags':
"items": tags
,
"networkInterfaces": [
'network': 'global/networks/default',
'networkIP': ip,
'accessConfigs': [
'type': 'ONE_TO_ONE_NAT',
'name': 'External NAT',
'natIP': ip_public
]
],
"metadata":
"items": metadata
return compute.instances().insert(
project=project,
zone=zone,
body=config).execute()
def delete_instance(compute, project, zone, name):
return compute.instances().delete(
project=project,
zone=zone,
instance=name).execute()
def list_instances(compute, project, zone):
result = compute.instances().list(project=project, zone=zone).execute()
return result['items'] if 'items' in result else None
def wait_for_operation(compute, project, zone, operation):
print('Waiting for operation to finish...')
while True:
result = compute.zoneOperations().get(
project=project,
zone=zone,
operation=operation).execute()
if result['status'] == 'DONE':
print("done.")
if 'error' in result:
raise Exception(result['error'])
return result
time.sleep(1)
def main(mode, project, zone, wait=True):
compute = googleapiclient.discovery.build('compute', 'v1')
if(mode == 'list'):
instances = list_instances(compute, project, zone)
print('Instances in project %s and zone %s:' % (project, zone))
for instance in instances:
print(' - ' + instance['name'])
return
print("Creating Database")
instance_name = "postgres-lab1"
image = "projects/tsm-cloudsys-vial/global/images/image-postgres-lab1"
machine = "e2-micro"
ip = "10.132.0.2"
ip_public = "34.79.195.77"
tags = ["postgres-lab1"]
operation1 = create_instance(compute, project, zone, instance_name, image, machine, ip, ip_public)
print("Creating Backend")
instance_name = "backend-lab1"
image = "projects/tsm-cloudsys-vial/global/images/image-backend-lab1"
machine = "e2-micro"
ip = "10.132.0.4"
ip_public = "34.79.111.217"
metadata = [
"key": "startup-script",
"value": backend_script
]
tags = ["backend-lab1","http-server","https-server"]
operation2 = create_instance(compute, project, zone, instance_name, image, machine, ip, ip_public, metadata=metadata)
print("Creating Frontend")
instance_name = "frontend-lab1"
image = "projects/tsm-cloudsys-vial/global/images/image-frontend-lab1"
machine = "e2-micro"
ip = "10.132.0.3"
ip_public = "35.187.109.153"
metadata = [
"key": "startup-script",
"value": frontend_script
]
tags = ["frontend-lab1","http-server","https-server"]
operation3 = create_instance(compute, project, zone, instance_name, image, machine, ip, ip_public, tags, metadata=metadata)
print("Waiting for VMs to come online")
wait_for_operation(compute, project, zone, operation1['name'])
wait_for_operation(compute, project, zone, operation2['name'])
wait_for_operation(compute, project, zone, operation3['name'])
instances = list_instances(compute, project, zone)
print('Instances in project %s and zone %s:' % (project, zone))
for instance in instances:
print(' - ' + instance['name'])
if wait:
input()
print("Deleting DB")
operation1 = delete_instance(compute, project, zone, "postgres-lab1")
print("Deleting Backend")
operation2 = delete_instance(compute, project, zone, "backend-lab1")
print("Deleting Frontend")
operation3 = delete_instance(compute, project, zone, "frontend-lab1")
wait_for_operation(compute, project, zone, operation1['name'])
wait_for_operation(compute, project, zone, operation2['name'])
wait_for_operation(compute, project, zone, operation3['name'])
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--mode', help='Wanted mode', default='list')
parser.add_argument('project_id', help='Your Google Cloud project ID.')
parser.add_argument(
'--zone',
default='europe-west1-b',
help='Compute Engine zone to deploy to.')
args = parser.parse_args()
main(args.mode, args.project_id, args.zone)
3 个实例已创建并正在运行,我可以 ping 通所有实例。 (是的,一个已关闭,因为我正在尝试重新启动它) 但我有两个主要问题:
-
在 Google Cloud 仪表板上使用 SSH 连接到实例是不可能的,这需要很长时间...
我觉得我的
startup-script
不正确,因为即使 3 个实例正在运行,我也无法像以前手动创建它们时那样访问它们。例如frontend-lab1
应该在端口 3000 上响应,但不是在我使用脚本创建它时
我主要关心的是第 2 个问题,因为我认为它会解决第 1 个问题。有人可以帮我解决我的startup-script
吗?
[编辑2] 这是日志:
ct 6 19:24:23 frontend-lab1 systemd[1]: Starting Google Compute Engine Startup Scripts...
Oct 6 19:24:23 frontend-lab1 google_metadata_script_runner[795]: 2021/10/06 19:24:23 logging client: rpc error: code = Unauthenticated desc = transport: metadata: GCE metadata "instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.write" not defined
Oct 6 19:24:37 frontend-lab1 systemd[1]: systemd-fsckd.service: Succeeded.
Oct 6 19:24:51 frontend-lab1 systemd[1]: systemd-hostnamed.service: Succeeded.
Oct 6 19:25:21 frontend-lab1 GCEGuestAgent[539]: 2021-10-06T19:25:21.4654Z GCEGuestAgent Info: Removing user jeromevialhes.
Oct 6 19:25:22 frontend-lab1 google_guest_agent[539]: 2021/10/06 19:25:22 logging client: rpc error: code = Unauthenticated desc = transport: metadata: GCE metadata "instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.write" not defined
Oct 6 19:25:22 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:22 GCEMetadataScripts: startup-script: /tmp/metadata-scripts111777770/startup-script: line 3: cd: /mse-tsm-cloudsys-lab1/app/: No such file or directory
Oct 6 19:25:23 frontend-lab1 google_metadata_script_runner[795]: 2021/10/06 19:25:23 logging client: rpc error: code = Unauthenticated desc = transport: metadata: GCE metadata "instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.write" not defined
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN saveError ENOENT: no such file or directory, open '/package.json'
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN enoent ENOENT: no such file or directory, open '/package.json'
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN !invalid#2 No description
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN !invalid#2 No repository field.
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN !invalid#2 No README data
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: npm WARN !invalid#2 No license field.
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script:
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: up to date in 0.489s
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script: found 0 vulnerabilities
Oct 6 19:25:27 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:27 GCEMetadataScripts: startup-script:
Oct 6 19:25:27 frontend-lab1 google_metadata_script_runner[795]: 2021/10/06 19:25:27 logging client: rpc error: code = Unauthenticated desc = transport: metadata: GCE metadata "instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.write" not defined
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! code ENOENT
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! syscall open
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! path /package.json
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! errno -2
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! enoent ENOENT: no such file or directory, open '/package.json'
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! enoent This is related to npm not being able to find a file.
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! enoent
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script:
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! A complete log of this run can be found in:
Oct 6 19:25:28 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:28 GCEMetadataScripts: startup-script: npm ERR! /root/.npm/_logs/2021-10-06T19_25_28_453Z-debug.log
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! code ENOENT
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! syscall open
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! path /package.json
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! errno -2
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! enoent ENOENT: no such file or directory, open '/package.json'
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! enoent This is related to npm not being able to find a file.
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! enoent
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script:
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! A complete log of this run can be found in:
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script: npm ERR! /root/.npm/_logs/2021-10-06T19_25_29_171Z-debug.log
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: startup-script exit status 254
Oct 6 19:25:29 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:29 GCEMetadataScripts: Finished running startup scripts.
Oct 6 19:25:29 frontend-lab1 systemd[1]: google-startup-scripts.service: Succeeded.
Oct 6 19:25:29 frontend-lab1 systemd[1]: Finished Google Compute Engine Startup Scripts.
但是你可以看到仓库是存在的:
jeromevialhes@frontend-lab1:~$ ls
mse-tsm-cloudsys-lab1
【问题讨论】:
您是否在端口 22 (SSH) 上创建了防火墙规则,以便您可以连接到实例?在 VPC 网络 API 上? @razimbres 是的,我为我需要的所有端口创建了我需要的所有规则(这就是我手动创建 VM 实例时它起作用的原因)但我真的认为问题来自我的startup-script
这也可能对您有所帮助:cloud.google.com/compute/docs/instance-templates/…,而不是图像或快照
我写了一篇关于如何计算启动时间的文章。这也将帮助您了解在哪里查找启动脚本问题:jhanley.com/google-compute-startup-script-total-execution-time 我不确定您使用的是哪个操作系统,了解要查看哪些日志文件很重要。 2) 安装 npm/node 需要时间,有时五分钟或更长时间。当您说您可以访问时,请准确定义其含义(测试和错误)。
@JohnHanley 我会看看你的文章!基本上,当我手动进行设置时,我打开浏览器并执行http://ipfrontend:3000
并且我可以访问前端,但是当我执行上面的脚本时,实例正在运行(如图所示)但是当我尝试访问时http://ipfrontend:3000
我的浏览器出现错误,因为前端没有运行 --> 这就是为什么我认为我的 script-frontend
写得不正确
【参考方案1】:
查看您在问题中包含的日志,您的custom 图像可能存在问题。在日志文件的第 7 行,它警告说找不到目录“/mse-tsm-cloudsys-labl1/app/”:
Oct 6 19:25:22 frontend-lab1 GCEMetadataScripts[795]: 2021/10/06 19:25:22 GCEMetadataScripts: startup-script: /tmp/metadata-scripts111777770/startup-script: line 3: cd: /mse-tsm-cloudsys-lab1/app/: No such file or directory
如果此目录用于包含您的应用程序文件,这将导致与 NPM 无法找到诸如 package.json
等文件和其他属于您的应用程序的文件相关的后续错误。
您应该确认应用程序路径是否正确或图像是否正确创建。您可以按照 this 指南从现有 VM 实例创建自定义映像,并使用 Node.js 和 Python 指南确保您遵循正确的步骤。
【讨论】:
以上是关于谷歌云如何在使用 Python api 创建实例时启动服务?的主要内容,如果未能解决你的问题,请参考以下文章
如何在谷歌云平台中使用私有 IP 从我的电脑连接到 sql 实例