Terraform实例模板模块MIG虚拟机启动脚本执行异常问题
我创建了包含3台VM的托管实例组(MIG),同时部署了一台同子网的独立VM,两者使用完全相同的启动脚本(安装Docker并运行监听80端口的服务)。独立VM上sudo docker ps能正常返回运行中的容器,但MIG内的VM执行相同命令时提示docker命令未找到,已确认instance_template模块使用的是startup_script属性而非metadata_startup_script。
核心排查步骤
首先登录MIG内的VM,查看启动脚本执行日志定位问题:
# 查看cloud-init启动脚本输出日志 cat /var/log/cloud-init-output.log # 过滤snap安装相关日志 grep "snap install docker" /var/log/syslog
日志会直接显示snap安装Docker是否成功、是否有报错(如网络超时、权限问题等)。
针对性解决办法
1. 环境变量PATH未包含Docker路径
snap安装的Docker默认路径为/snap/bin/docker,启动脚本执行时的系统PATH可能未包含该路径,导致后续命令找不到docker。
解决:
修改脚本,使用Docker的绝对路径调用:
#!/bin/bash sudo snap install docker sudo /snap/bin/docker version > docker_version.txt sleep 10 sudo /snap/bin/docker run -d --rm -p ${var.server_port}:${var.server_port} \ busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; \ echo 'yo'; } | nc -l -p ${var.server_port}; done"
或在脚本开头手动添加PATH:
#!/bin/bash export PATH=$PATH:/snap/bin sudo snap install docker sudo docker version > docker_version.txt # 后续命令不变
2. Docker安装未完成就执行后续命令
抢占式VM(preemptible)资源有限,snap install docker的耗时可能超过脚本中设置的5秒,导致后续命令执行时Docker还未安装完成。
解决:
替换固定sleep为循环等待Docker可用:
#!/bin/bash sudo snap install docker # 最多等待60秒,直到Docker命令可用 timeout=60 while [ $timeout -gt 0 ]; do if sudo /snap/bin/docker --version >/dev/null 2>&1; then break fi sleep 2 timeout=$((timeout-2)) done # 超时则记录错误并退出 if [ $timeout -le 0 ]; then echo "Docker installation timed out" >> /var/log/docker_install_error.log exit 1 fi sudo /snap/bin/docker version > docker_version.txt sudo /snap/bin/docker run -d --rm -p ${var.server_port}:${var.server_port} \ busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; \ echo 'yo'; } | nc -l -p ${var.server_port}; done"
3. 启动脚本缩进/语法错误
instance_template中的脚本缩进与独立VM不一致,可能导致脚本被截断或语法错误(<<-EOF仅忽略开头制表符,空格缩进会引发问题)。
解决:
确保脚本内容与EOF顶格书写:
startup_script = <<-EOF #!/bin/bash sudo snap install docker sudo /snap/bin/docker version > docker_version.txt sleep 10 sudo /snap/bin/docker run -d --rm -p ${var.server_port}:${var.server_port} \ busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; \ echo 'yo'; } | nc -l -p ${var.server_port}; done" EOF
4. 服务账号权限限制
MIG的VM使用自定义服务账号,可能存在本地操作权限限制(虽然snap安装Docker为本地操作,但极端情况下权限配置会影响)。
解决:
临时切换为默认服务账号测试,若问题消失,再排查自定义服务账号的权限配置是否遗漏必要的本地操作权限。
内容的提问来源于stack exchange,提问作者SkogensKonung

