如何确保Google Cloud Compute实例正常运行?

7

我通过shell脚本创建了Google Cloud Compute实例,然后通过ssh在该实例上启动了几个命令。

如何确保实例中的操作系统正在运行?

例如:

gcloud compute instances create "$my_name" \ --tags "http-server" \ --image container-vm \ --metadata-from-file google-container-manifest="container.yml" \ --zone "$my_zone" \ --machine-type g1-small

然后我希望运行以下命令之一

gcloud compute ssh \ "$my_name" --zone "$my_zone" \ --command 'sudo docker stop $(sudo docker ps -q -a)'

或者

gcloud compute copy-files \ some.conf root@"$my_name":/existing_dir/ \ --zone "$my_zone"

据我所知,如果实例未启动,则第二个命令可能会出现连接拒绝的情况。

如何确保实例已启动并准备好接受ssh连接?

6个回答

6

在发送命令之前,请检查SSH端口是否打开。只有当实例操作系统启动后,SSH服务器才会启动:

IP=$(gcloud compute instances list | awk '/'$my_name'/ {print $5}')
if nc -w 1 -z $IP 22; then
    echo "OK! Ready for heavy metal"
    : Do your heavy metal work
else
    echo "Maybe later?"
fi

说明:

  1. 获取实例$my_name的IP地址
  2. 检查端口22是否接受传入连接。

-w:连接超时(1秒应该足够)

-z:仅检查端口是否打开并立即退出


似乎虚拟机启动可能需要超过5秒的时间。 - Evgeny Timoshenko
1
在循环内检查实例是否可用。实例引导时间取决于实例引导配置 :) - Antxon
3
这是一个好方法。但需要注意的是,gcloud的默认表格格式旨在方便人类阅读,而不是长期稳定的,因此未来可能会添加新字段并破坏awk的解析。我建议调用 gcloud compute instances list instance-name --format json 以获得更稳定的输出格式。您可以使用jq来解析json输出。(其他稳定的输出格式包括文本和yaml。) - Jeffrey Vaughan
--format文本更适合Unix过滤,而且在我看来不需要像jq这样的外部工具。一旦你有一个基本的方法,剩下的只是细节。 - Antxon
您可以通过搜索响应中的IPv4地址来使其更加健壮:$( gcloud compute instances list --format text |sed -rn 's/.*([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/p' ) - chrishmorris

4

如果您需要确保SSH可用,有一个脚本可以实现。

#!/usr/bin/env bash

function wait_vm_up {
  local counter=0

  local readonly project=${1:?"project required"}
  local readonly instance=${2:?"instance required"}
  local readonly zone=${3:?"zone required"}
  local readonly user=${4:?"user required"}
  local readonly maxRetry=${5:-100}

  echo "Project: $project"
  echo "Instance: $instance"
  echo "MaxRetry: $maxRetry"

  while true ; do
    if (( $counter == $maxRetry )) ; then
      echo "Reach the retry upper limit $counter"
      exit 1
    fi

    gcloud compute ssh --quiet --zone "$zone" "$user@$instance" --tunnel-through-iap --project "$project" --command="true" 2> /dev/null

    if (( $? == 0 )) ;then
      echo "The machine is UP !!!"
      exit 0
    else
      echo "Maybe later? $counter"
      ((counter++))
      sleep 1
    fi
  done
}

wait_vm_up $@

我以前从未见过${1:?"project required"}这个表达式,它叫什么名字?我在https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html中搜索`${1:?`,但没有找到任何内容。 - mbigras
Shell参数扩展中搜索${parameter:?word} - mbigras

2

简单的跨平台解决方案:

gcloud compute --verbosity error --project "MYPROJECT" ssh "MYINSTANCE" -- "echo instance now up" -o StrictHostKeyChecking=no

循环执行以上命令,直到 errorLevel 的值为 0。


如果虚拟机没有运行,这会导致错误非常严重,同时输出Python的堆栈跟踪信息。 - chrishmorris

0

REST API 的方式需要授权,从 shell 的角度来看似乎过于复杂。 - Evgeny Timoshenko
我猜container-vm镜像已经定义了启动脚本。启动脚本能在container-vm镜像上工作吗? - Evgeny Timoshenko
如果你想在shell中使用python调用gapi,简单的方法是:创建一个python脚本来完成任务,并从sh中调用。关于预定义图像脚本,我认为它可以工作:尝试一下并让我知道结果! - aqquadro
1
为什么你们给最佳答案点了踩?API是与谷歌通信的正确方式。其他所有东西都是每天都在变化的垃圾 ¯_(ツ)_/¯ - DGoiko

0
你可以使用以下命令:gcloud compute instances describe '实例名称' --zone '区域名称' | grep "status: RUNNING"
如果你得到了确切的输出status: RUNNING,那么它将表示该实例正在运行。

2
它不起作用。根据文档: 运行中 - 实例正在启动或运行。在实例进入此状态后不久,您可以连接到该实例。 - Jimmy

-1

简单的命令行或别名。

alias gcp_status_MY_MACHINE='gcloud compute instances describe salesforce --zone "ZONE" --project "PROJECT" | grep status'

如果您只有一个项目并且没有指定区域,它仍然可以工作,这只是冗长版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接