Packer结合Terraform在VMware Ubuntu22.04上二次执行cloud-init异常
工作流合理性判定
这套Packer构建基础模板、Terraform基于模板克隆传参触发cloud-init二次配置的工作流完全合理,是VMware私有云场景下批量交付虚机的标准落地模式,不存在架构设计层面的问题,你遇到的配置不生效属于模板预处理、cloud-init数据源配置类的细节问题。
第二份cloud-init配置未执行的排查方向
- 先查模板侧cloud-init清理是否到位
你当前在late-commands阶段只执行了sudo cloud-init clean,默认参数不会清理实例唯一标识、初始化完成标记、machine-id等关键状态,cloud-init启动时检测到残留的实例ID,会直接判定该机器已经完成初始化,不会重新拉取新的配置。
模板关机前必须执行的清理命令为:
额外注意Ubuntu 22.04用subiquity安装器跑完自动安装后,会生成sudo cloud-init clean --logs --seed --machine-id sudo truncate -s 0 /etc/machine-id sudo rm -f /etc/cloud/cloud-init.disabled /var/lib/cloud/instance/boot-finished/etc/cloud/cloud.cfg.d/99-installer.cfg文件,强制锁定数据源为安装阶段用的NoCloud源,必须在late-commands阶段删掉这个文件,不然cloud-init不会主动探测VMware的guestinfo数据源。 - 再查VMware数据源是否被cloud-init识别
登录基础模板虚机,检查/etc/cloud/cloud.cfg.d/下的数据源配置,确保VMware数据源在探测列表的最前面,示例配置:
如果列表里没有VMware项,cloud-init根本不会读取ESXi侧写入的guestinfo参数,自然拿不到你传入的第二份配置。datasource_list: [ VMware, NoCloud, ConfigDrive ] datasource: VMware: allow_raw_data: true vmware_cust_file_max_wait: 15 - 校验guestinfo参数配置的完整性
不要只校验guestinfo.userdata解码后的内容正确性,必须同时确认两个容易漏的配置:- 必须额外传入
guestinfo.userdata.encoding = "gzip+base64"参数,否则cloud-init会默认按纯base64格式解码,遇到gzip压缩的内容会直接判定格式错误跳过 - 必须同时传入合法的
guestinfo.metadata内容,哪怕只是包含新实例ID的最简配置,缺少metadata时VMware数据源会初始化失败,不会加载user-data
- 必须额外传入
- 开机后手动调试定位具体报错
克隆后的虚机如果能通过SSH登录,直接执行sudo cloud-init init --debug,看控制台输出的数据源探测流程,会明确打印出是找不到VMware数据源、读不到guestinfo参数、还是配置格式校验失败,比直接翻历史日志定位效率高很多。
场景配置最佳实践
- 模板构建阶段固定基础配置
autoinstall阶段直接安装apt源的open-vm-tools,不要装snap版本,snap版的服务权限不足,经常出现读不到guestinfo参数的问题;模板构建时不要留存任何SSH主机密钥,clean阶段一起删掉,克隆后第一次开机会自动生成新的密钥,避免多虚机密钥重复的安全问题。 - 多网卡配置规避顺序漂移问题
你规划配置7块vmxnet3网卡,不要靠eth0、eth1这类名称匹配网卡配置,cloud-init传入的network-config段直接用MAC地址做网卡匹配规则,避免VMware克隆后网卡枚举顺序错乱导致配置配错网卡。 - Terraform侧减少手动编码逻辑
不要自己写shell逻辑做user-data的gzip+base64编码,直接用Terraform官方的cloudinit provider渲染生成编码后的user-data、metadata内容,避免手动编码出现头信息缺失、换行符错误这类隐蔽问题;生产环境优先用全量克隆,链接克隆虽然快,但依赖基础模板文件,基础模板损坏会导致所有关联链接克隆虚机无法启动。 - 和Ansible的职责做清晰拆分
主机名、网卡配置、基础软件源、系统安全基线这类实例级的初始化配置交给cloud-init完成,不要让Ansible跨层修改这类配置;Terraform侧加null_resource做Ansible触发逻辑,等虚机22端口连通、且/var/lib/cloud/instance/boot-finished文件存在后再启动Ansible playbook,避免在cloud-init还在跑配置的时候并发改系统导致冲突。 - 做模板版本化管理
每次构建新的基础模板(打补丁、更新内置软件)时,在模板内的/etc/image-version文件写入版本号、构建时间,Terraform克隆时把对应模板版本写到虚机标签里,后续批量排查、升级存量虚机的时候可以直接筛选,不用逐台登录核对系统版本。
内容的提问来源于stack exchange,提问作者abestic9
相关产品推荐
相关产品推荐

