Java结合cloud-init/cloudbase-init实现底层虚机主机名称和root密码的初始化

齐修贤
2023-12-01


背景:

要求Java代码实现KVM虚机(包括Linux和Windows)新创建后,主机名和root/Administrator密码的初始化。其中,主机名为用户前台传入,root密码需要随机生成一个高复杂度密码。


适用对象:

底层支持安装cloud-init和cloudbase-init,需要自定义主机名和root密码,且完全线上执行。

难点:

按照常规思路,需要服务器先连接到目标主机,然后通过执行目标主机的脚本或者cmd命令实现。Linux虚机按照此思路实现功能的方法较多,不一一赘述。主要难点在Windows,Windows虚机修改密码和主机名称需要连接到目标主机,然后启动cmd,执行cmd命令来修改。但是通过Java代码无法实现这个操作。



解决方案:

采用cloud-init/cloudbase-init工具,结合meta-data/user-data元数据的方式,实现root/Administrator密码和主机名的修改。

先来解释几个名词:

1.cloud-init和cloudbase-init:二者都是OpenStack初始化虚拟机的一种工具,前者是针对Linux系统的,后者是针对windows系统的。使用时,可以把工具提前打到镜像模板里,在虚机创建完启动时,会去按照meta-data/user-data中的内容初始化虚机。

2.meta-data和user-data:二者都可以存放关于虚机的一些元数据,不同的是meta-data采用key-value的形式,user-data多是脚本的形式。

具体实现方式:

主要讲一下Java层面的,底层确保安装了cloud-init和cloudbase-init即可。

1.Linux主机user-data存储修改主机名称、root密码命令行,实现对Linux主机的主机名称密码初始化。需要注意:user-data中的数据需要Base64编码。

String userData = "#!/bin/bash \n hostname " + hostName + "\n  hostnamectl set-hostname "+ hostName+"\n echo "+rootPws+" | passwd root --stdin &> /dev/null";
byte[] userDataEncode = Base64Utils.encode(userData.getBytes());
serverCreateBuilder.userData(userDataEncode );

2.meta-data存储Administrator密码和主机名,实现对Windows主机的主机名密码初始化。

Map<String, String> metaData = new HashMap<String, String>();
metaData.put("admin_pass",rootPassword);
metaData.put("set_hostname",hostname);
serverCreateBuilder.metaData(metaData);

3.根据不同的对接OpenStack底层方式,将user-data和meta-data在虚机创建时传到底层。虚机创建完成,数据到达底层后,虚机会重启以使这些数据生效。

遇到的问题以及排查过程:

1.单用user-data,Windows主机初始化不成功;单用meta-data,Linux主机初始化不成功。本来是想单用meta-data的,但是用完Linux没改成功。去meta-data的服务里边去看,数据没写入成功。怀疑是Linux和Windows对应的元数据key值不一样,但是相关资料太少,没找到元数据列表。最后改成了Linux用user-data,Windows用meta-data。

附元数据存储地址:

curl http://169.254.169.254/openstack/latest/meta_data.json
curl http://169.254.169.254/openstack/latest/password
curl http://169.254.169.254/openstack/latest/user_data

这个地址是元数据服务器,有时候http://169.254.169.254/openstack/目录下会有很多带日期的文件夹,一般是找latest,找不到可以看看其他带日期的文件夹。如果确定数据传到底层了,但是又没有初始化成功,可以从这几个地址入手。

另附一个不知道是不是cloud-init官网的地址:Tutorial — cloud-init 22.2 documentation

 类似资料: