VMware vRealize Automaton 8 是最新的企业云平台,拥有诸多特性。但在使用静态IP地址时候,出现了vSphere Customization和Cloud-init冲突的问题,导致vRA8置备的虚拟机无法正确获得iP地址,Cloud-init也无法正常工作。
虽然VMware官方文档已经更新了解决办法,但需要额外等待的时间超过2分30秒,并且只有Ubuntu环境的,但对于DevOps的自动化来讲,2分30秒非常珍贵。
今天我找到更好的解决办法,可以实现vSphere Customization和Cloud-init一同工作,并且几乎无需额外的等待时间。
工作原理
下面是一个标准的vRA8蓝图,其中 assignment: static 是分配静态地址的配置。 整体流程如下:
- vRA8会创建动态的vSphere Customization,并在系统第一次启动时进行操作系统定制化,包括IP地址和主机名等;
- 此时应预先在模版中禁用Cloud-init,以避免两个定制化冲突,待vSphere Customization完成,并重启后再执行Cloud-init;
- VM Customization完成后,会立即重新启动;
- VM重新启动后cloud-init-local服务会先执行,由于cloud-init已经禁用,无任何动作;
- 系统启动runonce服务,该服务会延迟10s执行runonce.sh脚本;
- runonce.sh脚本会开启cloud-init,并重启cloud-init.service、cloud-config.service和cloud-final.service;
- cloud-init会按顺序执行模块;
- 最终,完成系统定制化和Cloud-init定制化。
CentOS7模版一键修改脚本
Ubuntu18.04模版一键修改脚本
CentOS7模版手工准备步骤
[CentOS7]更新系统和安装Cloud-init
CentOS7默认没有Cloud-init组件,通过以下命令安装Cloud-init和更新系统补丁。
yum install cloud-init -y
yum update -y
[CentOS7]修改/etc/cloud/cloud.cfg配置
vRA8采用挂在OVF光盘模式传递定制化配置文件,所以在配置文件中指定数据源为OVF,可以加快Cloud-init初始化时间。另外需要禁用vmware customization。
disable_vmware_customization: true
datasource_list: [OVF]
[CentOS7]配置/etc/cloud/cloud.cfg,禁用cloud-init配置网络
添加如下代码,禁用Cloud-init配置网络,因为vSphere Customization被用于网络配置
network:
config: disabled
[CentOS7]配置/usr/lib/tmpfiles.d/tmp.conf,不清除临时目录
使用#注释掉此行,保留临时文件
#v /tmp 1777 root root 10d
[CentOS7]配置/etc/lib/systemd/system/vmtoolsd.service
添加以下内容到[Unit]内,用于解决随机性定制化失败的问题。
After=dbus.service
[CentOS7]创建/etc/cloud/cloud-init.disabled文件,使模版中禁用Cloud-init
当存在cloud-init.disabled文件时,cloud-init不工作,包括cloud-init-local.service、cloud-init.service、cloud-config.service和cloud-final.service,此配置保证第一次系统启动时cloud-init不会工作,而是由vSphere Customization执行系统定制化。
touch /etc/cloud/cloud-init.disabled
[CentOS7]创建runonce.sh文件,用于重启后触发cloud-init执行
此脚本文件由runonce.service自动调用,其会判断/tmp目录下是否有guest.customization.stderr文件,如果有说明vSphere Customization定制化已经执行完成,并执行Cloud-init的三个过程(init/config/final),执行完成后禁用runonce服务。这就是为什么第一次系统启动不会执行cloud-init的原因。
cat <<EOF > /etc/cloud/runonce.sh
#!/bin/bash
if [ -e /tmp/guest.customization.stderr ]
then
sudo rm -rf /etc/cloud/cloud-init.disabled
sudo systemctl restart cloud-init.service
sudo systemctl restart cloud-config.service
sudo systemctl restart cloud-final.service
sudo systemctl disable runonce
sudo touch /tmp/cloud-init.success
fi
exit
EOF
[CentOS7]创建runonce.service文件,用于通过服务调用runonce.sh脚本
为提高效率,这次采用Service触发脚本,为了避免runonce.service早于cloud-init-local.service启动,指定了 Requires=cloud-init-local.sevice参数和sleep 10s,保证第一次启动时不会触发此服务。
cat <<EOF > /etc/systemd/system/runonce.service
[Unit]
Description=Run once
Requires=network-online.target
Requires=cloud-init-local.sevice
After=network-online.target
After=cloud-init-local.service
[Service]
###wait for vmware customization to complete, avoid executing cloud-init at the first startup.###
ExecStartPre=/bin/sleep 10
ExecStart=/etc/cloud/runonce.sh
[Install]
WantedBy=multi-user.target
EOF
[CentOS7]创建clean.sh文件,用于清理模版
在实际使用中需要不断修改模版,此脚本用于清理系统,应该每次模版调整后执行。
提示:虽然模版中不会存在 /tmp/guest.customization.stderr文件,也就不会触发runonce.sh的执行,但是其他的清理还是建议做的。
cat <<EOF > /etc/cloud/clean.sh
#!/bin/bash
#clear audit logs
if [ -f /var/log/audit/audit.log ]; then
cat /dev/null > /var/log/audit/audit.log
fi
if [ -f /var/log/wtmp ]; then
cat /dev/null > /var/log/wtmp
fi
if [ -f /var/log/lastlog ]; then
cat /dev/null > /var/log/lastlog
fi
#cleanup persistent udev rules
if [ -f /etc/udev/rules.d/70-persistent-net.rules ]; then
rm /etc/udev/rules.d/70-persistent-net.rules
fi
#cleanup /tmp directories
rm -rf /tmp/*
rm -rf /var/tmp/*
#cleanup current ssh keys
#rm -f /etc/ssh/ssh_host_*
#cat /dev/null > /etc/hostname
#cleanup apt
yum clean all
#Clean Machine ID
truncate -s 0 /etc/machine-id
rm /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id
#Clean Cloud-init
cloud-init clean --logs --seed
#Disabled Cloud-init
touch /etc/cloud/cloud-init.disabled
systemctl enable runonce
#cleanup shell history
history -cw
EOF
[CentOS7]更改脚本执行权限
下面赋予脚本执行权限。
chmod +x /etc/cloud/runonce.sh /etc/cloud/clean.sh
[CentOS7]打开runonce.service
重新加载和打开runonce服务,保证系统启动时,此服务自动启动。
systemctl daemon-reload
systemctl enable runonce.service
[CentOS7]执行/etc/cloud/clean.sh,清理模版
执行模版清理。
/etc/cloud/clean.sh
[CentOS7]关闭系统,转换为VM模版
shutdown -h now
Ubuntu 18.04模版手工准备步骤:
[Ubuntu 18.04]更新系统和安装Cloud-init
CentOS7默认没有Cloud-init组件,通过以下命令安装Cloud-init和更新系统补丁。
sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get -y install cloud-init
[Ubuntu 18.04]修改/etc/cloud/cloud.cfg配置
在cloud-init中禁用vmware customization,并指定OVF作为数据源。
disable_vmware_customization: true
datasource_list: [OVF]
[Ubuntu 18.04]配置/etc/cloud/cloud.cfg,禁用cloud-init配置网络
添加如下代码,禁用Cloud-init配置网络,因为vSphere Customization被用于网络配置
network:
config: disabled
[Ubuntu 18.04]配置/usr/lib/tmpfiles.d/tmp.conf,不清除临时目录
使用#注释掉此行,保留临时文件
#D /tmp 1777 root root –
[Ubuntu 18.04]配置/lib/systemd/system/open-vmtools.service
添加以下内容到[Unit]内,用于解决随机性定制化失败的问题。
After=dbus.service
[Ubuntu 18.04]创建/etc/cloud/cloud-init.disabled文件,使模版中禁用Cloud-init
当存在cloud-init.disabled文件时,cloud-init不工作,包括cloud-init-local.service、cloud-init.service、cloud-config.service和cloud-final.service,此配置保证第一次系统启动时cloud-init不会工作,而是由vSphere Customization执行系统定制化。
sudo touch /etc/cloud/cloud-init.disabled
[Ubuntu 18.04]创建/etc/cloud/runonce.sh文件,用于重启后触发cloud-init执行
此脚本文件由runonce.service自动调用,其会判断/tmp目录下是否有guest.customization.stderr文件,如果有说明vSphere Customization定制化已经执行完成,并执行Cloud-init的三个过程(init/config/final),执行完成后禁用runonce服务。这就是为什么第一次系统启动不会执行cloud-init的原因。
sudo cat <<EOF > /etc/cloud/runonce.sh
#!/bin/bash
if [ -e /tmp/guest.customization.stderr ]
then
sudo rm -rf /etc/cloud/cloud-init.disabled
sudo systemctl restart cloud-init.service
sudo systemctl restart cloud-config.service
sudo systemctl restart cloud-final.service
sudo systemctl disable runonce
sudo touch /tmp/cloud-init.success
fi
exit
EOF
[Ubuntu 18.04]创建runonce.service文件,用于通过服务调用runonce.sh脚本
为提高效率,这次采用Service触发脚本,为了避免runonce.service早于cloud-init-local.service启动,指定了 Requires=cloud-init-local.sevice参数和sleep 10s,保证第一次启动时不会触发此服务。
sudo cat <<EOF > /etc/systemd/system/runonce.service
[Unit]
Description=Run once
Requires=network-online.target
Requires=cloud-init-local.sevice
After=network-online.target
After=cloud-init-local.service
[Service]
###wait for vmware customization to complete, avoid executing cloud-init at the first startup.###
ExecStartPre=/bin/sleep 10
ExecStart=/etc/cloud/runonce.sh
[Install]
WantedBy=multi-user.target
EOF
[Ubuntu 18.04]创建/etc/cloud/clean.sh文件,用于清理模版
在实际使用中需要不断修改模版,此脚本用于清理系统,应该每次模版调整后执行。
提示:虽然模版中不会存在 /tmp/guest.customization.stderr文件,也就不会触发runonce.sh的执行,但是其他的清理还是建议做的。
cat <<EOF > /etc/cloud/clean.sh
#!/bin/bash
#clear audit logs
if [ -f /var/log/audit/audit.log ]; then
cat /dev/null > /var/log/audit/audit.log
fi
if [ -f /var/log/wtmp ]; then
cat /dev/null > /var/log/wtmp
fi
if [ -f /var/log/lastlog ]; then
cat /dev/null > /var/log/lastlog
fi
#cleanup persistent udev rules
if [ -f /etc/udev/rules.d/70-persistent-net.rules ]; then
rm /etc/udev/rules.d/70-persistent-net.rules
fi
#cleanup /tmp directories
rm -rf /tmp/*
rm -rf /var/tmp/*
#cleanup current ssh keys
#rm -f /etc/ssh/ssh_host_*
#cat /dev/null > /etc/hostname
#cleanup apt
apt-get clean
#Clean Machine ID
truncate -s 0 /etc/machine-id
rm /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id
#Clean Cloud-init
cloud-init clean --logs --seed
#Disabled Cloud-init
touch /etc/cloud/cloud-init.disabled
#cleanup shell history
history -cw
EOF
[Ubuntu 18.04]更改脚本执行权限
下面赋予脚本执行权限。
sudo chmod +x /etc/cloud/runonce.sh /etc/cloud/clean.sh
[Ubuntu 18.04]打开runonce.service
重新加载和打开runonce服务,保证系统启动时,此服务自动启动。
sudo systemctl daemon-reload
sudo systemctl enable runonce.service
[Ubuntu 18.04]执行/etc/cloud/clean.sh,清理模版
执行模版清理。
/etc/cloud/clean.sh
[Ubuntu 18.04]关闭系统,转换为VM模版
shutdown -h now
完成
至此我们通过对Linux系统进行定制化,解决了vRA8在vSphere环境中无法同时使用静态IP和Cloud-init的问题。