Packer Hyper-V构建添加网卡后SSH超时问题求助
我使用Packer的hyperv-iso构建器搭配shell-local provisioner,在Hyper-V平台上构建Debian 11.5镜像。操作系统安装成功后,尝试为虚拟机添加第二块网卡,但过程中出现错误:
Failed to send shutdown command: dial tcp 172.29.48.100:22: i/o timeout
我的Packer配置代码如下:
source "hyperv-iso" "build-debian" { boot_command = ["<wait><wait><wait><esc><wait><wait><wait>", "/install.amd/vmlinuz ", "initrd=/install.amd/initrd.gz ", "auto=true ", "interface=eth0 ", "netcfg/disable_dhcp=true ", "netcfg/confirm_static=true ", "netcfg/get_ipaddress=172.29.48.100 ", "netcfg/get_netmask=255.255.255.0 ", "netcfg/get_gateway=172.29.48.1 ", "netcfg/get_nameservers=8.8.8.8 8.8.4.4 ", "netcfg/get_domain=domain ", "netcfg/get_hostname=hostname ", "url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", "vga=788 noprompt quiet --<enter>"] boot_wait = "10s" configuration_version = "${var.hyperv_version}" cpus = "${var.cpus}" disk_block_size = "${var.hyperv_disk_block_size}" disk_size = "${var.disk_size}" memory = "${var.memory}" generation = "${var.hyperv_generation}" guest_additions_mode = "disable" http_directory = "${local.http_directory}" iso_checksum = "sha256:e307d0e583b4a8f7e5b436f8413d4707dd4242b70aea61eb08591dc0378522f3" iso_url = "http://debian.mirror.vu.lt/debian-cd/11.5.0/amd64/iso-cd/debian-11.5.0-amd64-netinst.iso" output_directory = "${var.build_directory}/packer-${local.template}-${var.git_sha}" shutdown_command = "echo 'vagrant' | sudo -S /sbin/halt -h -p" ssh_host = "${var.ip_address_eth0}" ssh_keep_alive_interval = "-1s" ssh_password = "vagrant" ssh_port = 22 ssh_timeout = "120m" ssh_username = "vagrant" headless = "false" switch_name = "VmNAT" vm_name = "${local.template}-${var.git_sha}" } build { name = "BUILD: Debian v11.5" source "hyperv-iso.build-debian" { } provisioner "shell-local" { execute_command = ["powershell.exe", "{{.Vars}} {{.Script}}"] env_var_format = "$env:%s=\"%s\"; " tempfile_extension = ".ps1" pause_before = "60s" inline =["Import-Module Hyper-V", "Stop-VM -Name ${local.template}-${var.git_sha}", "Timeout /T 20", "Add-VMNetworkAdapter -VMName ${local.template}-${var.git_sha} -SwitchName ${var.hyperv_switch} -Name Static -DeviceNaming Off", "Start-VM -Name ${local.template}-${var.git_sha}" } }
我怀疑问题出在超时上:虚拟机重启后,Packer立刻尝试重新连接,但此时VM仍处于启动阶段,因此出现错误。请问ssh_timeout是否仅在首次启动时生效?希望能得到解决方法。
关于ssh_timeout的作用
ssh_timeout并非仅在首次启动时生效,它是Packer每次尝试建立SSH连接时的单次超时时间。你的场景核心问题是:shell-local脚本启动VM后,Packer立即触发SSH连接尝试,此时VM尚未完全启动、SSH服务未就绪,导致连接超时。
具体解决方案
1. 在shell-local脚本中添加启动后等待
在Start-VM命令后增加足够长的等待时间,确保VM完成启动、SSH服务正常运行后,Packer再尝试连接:
provisioner "shell-local" { # 现有配置... inline =[ "Import-Module Hyper-V", "Stop-VM -Name ${local.template}-${var.git_sha}", "Timeout /T 20", "Add-VMNetworkAdapter -VMName ${local.template}-${var.git_sha} -SwitchName ${var.hyperv_switch} -Name Static -DeviceNaming Off", "Start-VM -Name ${local.template}-${var.git_sha}", "Timeout /T 120" # 等待120秒,可根据VM实际启动时长调整 ] }
2. 使用pause_after参数
在shell-local provisioner中配置pause_after,指定脚本执行完成后等待的时长,给VM足够的启动时间:
provisioner "shell-local" { execute_command = ["powershell.exe", "{{.Vars}} {{.Script}}"] env_var_format = "$env:%s=\"%s\"; " tempfile_extension = ".ps1" pause_before = "60s" pause_after = "120s" # 脚本执行完后等待120秒 inline =[ "Import-Module Hyper-V", "Stop-VM -Name ${local.template}-${var.git_sha}", "Timeout /T 20", "Add-VMNetworkAdapter -VMName ${local.template}-${var.git_sha} -SwitchName ${var.hyperv_switch} -Name Static -DeviceNaming Off", "Start-VM -Name ${local.template}-${var.git_sha}" ] }
3. 调整SSH重试策略
在hyperv-iso source块中增加ssh_max_retries参数,让Packer尝试更多次SSH连接,配合ssh_timeout使用:
source "hyperv-iso" "build-debian" { # 现有配置... ssh_timeout = "5m" # 单次连接超时设为5分钟 ssh_max_retries = 30 # 最多重试30次,总等待时间可达150分钟 # 其他配置... }
4. 优化VM启停逻辑
如果允许的话,可以避免手动执行Stop-VM和Start-VM,改用Packer内置的关机机制(比如通过provisioner执行关机命令),但因为添加网卡必须关机,所以前三种方法更贴合你的场景。
内容的提问来源于stack exchange,提问作者robotiaga

