我正在尝试使用 cloudinit 与 terraform 和 libvirt 提供程序在 qemu/kvm 虚拟机管理程序上配置虚拟机。我可以启动机器,但 cloudinit 没有启动。我知道所使用的用户数据可以正常工作,因为我已经在不使用 terraform 的情况下对其进行了测试,而是使用 kvm 来启动带有第二个终端的计算机,该终端运行 Web 服务器来提供用户数据文件。所有这些都在 Ubuntu 18.04 上执行。
我已经尝试过使用 ubuntu 和 centos 的云映像。两者都会创建虚拟机并启动到登录提示符。但两者都不会实际提供用户数据的内容。我也尝试过使用较低版本的 libvirt 提供程序(仍然可用)来获得相同的结果。
我做了一些广泛的搜索,试图看看其他人是否也有类似的问题。我发现的大多数站点/问题都来自 StackExchange 站点,以及 github 问题和错误报告,遗憾的是我没有将其捕获到文档中。所有这些都可能是用户数据中缺失的东西。他们都没有使用我使用的 libvirt 提供程序的版本,但几乎总是使用 0.6.2 版本。我尝试在 main.tf 文件中使用该版本的提供程序,但 init 命令返回错误,指出该版本不存在且无法下载。
main.tf(centos 和 ubuntu 之间的唯一区别是云映像文件/位置和前缀变量)
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.7.0"
}
}
}
# instantiate the provider
provider "libvirt" {
uri = "qemu:///system"
}
variable "prefix" {
default = "terraform_centos"
}
data "template_file" "user_data" {
template = file("${path.module}/cloud_init.cfg")
}
resource "libvirt_cloudinit_disk" "commoninit" {
name = "commoninit.iso"
user_data = data.template_file.user_data.rendered
}
resource "libvirt_volume" "qcow_volume" {
name = "${var.prefix}.img"
source = "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2"
format = "qcow2"
}
resource "libvirt_domain" "centos" {
name = var.prefix
vcpu = 2
memory = 4096
disk {
volume_id = libvirt_volume.qcow_volume.id
}
cloudinit = libvirt_cloudinit_disk.commoninit.id
console {
type = "pty"
target_port = "0"
target_type = "serial"
}
console {
type = "pty"
target_type = "virtio"
target_port = "1"
}
network_interface {
network_name = "default"
}
}
用户数据文件(与 main.tf 一样,正在测试的两个发行版之间唯一的变化是主机名)
#cloud-config
autoinstall:
version: 1
identity:
hostname: terraform_centos
username: vagrant
password: $6$dnWt7N17fTD$8.m3Rgf400iSyxLa/kUtunGUgE3N4foSg/y31HNnsGBUTpoMOmS3O9U/nJFvZjXpQTrLFrAcK5vok5EI0KZA90
locale: en_US
keyboard:
layout: us
ssh:
install-server: true
authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
allow-pw: true
storage:
layout:
name: direct
packages:
- gcc
- build-essential
late-commands:
- "echo 'vagrant ALL=(ALL) NOPASSWD: ALL' >> /target/etc/sudoers.d/vagrant"
- "chmod 440 /target/etc/sudoers.d/vagrant"
最后是真正让 cloudinit 工作的 kvm 命令。这是在另一个 shell 中启动快速 python Web 服务器之后的结果。将 iso 映像安装到 /mnt 中,以便可以访问内核/initrd。
kvm -no-reboot -m 4096 -drive file=focal.img,format=raw,cache=none,if=virtio -cdrom ~/isoImages/ubuntu-20.04.5-live-server-amd64.iso -kernel /mnt/casper/vmlinuz -initrd /mnt/casper/initrd -append 'autoinstall ds=nocloud-net;s=http://_gateway:3003/' -vnc :1
Qemu/kvm 版本信息
$ virsh version
Compiled against library: libvirt 4.0.0
Using library: libvirt 4.0.0
Using API: QEMU 4.0.0
Running hypervisor: QEMU 2.11.1
地形版本信息
$ terraform version
Terraform v1.3.6
on linux_amd64
+ provider registry.terraform.io/dmacvicar/libvirt v0.7.0
+ provider registry.terraform.io/hashicorp/template v2.2.0
由于我在两个发行版中使用云映像,因此没有可以登录以直接检查虚拟机上的日志的默认用户名/密码。我确实可以通过 virt-manager 和 virsh 控制台命令访问控制台。两者都处于登录提示符处,流浪用户返回登录错误消息。
如果需要任何进一步的信息,请告诉我。我愿意接受有关需要采取哪些措施才能使其发挥作用的建议。
答案1
正如 Brett-holman 提到的,问题很可能是您传入的 cloud-init YAML。如果您virsh console --domain your-kvm-domain
使用未修改的云映像监控启动域 ( ) 的控制台(尝试以下之一)来自 Ubuntu 的 QCOW2 映像)正如您base_volume_id
在中 一样libvirt_volume
,您应该看到 cloud-init 的 init 进程的输出。
尝试一下这个 repo 中的 terraform:https://github.com/mattsn0w/terraform_kvm
我用它作为我的家庭实验室以及工作中气隙环境的基础。
我目前正在使用dmacvicar/libvirt
terraform 提供程序的 v0.7.1 成功配置 AL2、CentOS 7、RHEL 8 和 9、Ubuntu 18、20 和 22 LTS。如果云映像安装了 cloud-init,那么您应该能够进行相当多的配置。
值得指出的是,您需要将映像中的 cloud-init 版本与文档相匹配。截至此评论的最新版本是v23.3.3
答案2
澄清
请注意,您yaml
实际上是 Subiquity 的配置,Ubuntu 自动安装程序, 不是云初始化。
Cloud-init 由 Ubuntu 的自动安装程序使用,但 cloud-init 本身不使用autoinstall
yaml 密钥。
我已经尝试过使用 ubuntu 和 centos 的云映像。
注意cloud-init 支持 centos,但我不认为 Ubuntu 的自动安装程序会这样做。如果您想改用 cloud-init,您可能需要查看例子和教程。
建议
仔细查看 .tf 文件中的这些行:
data "template_file" "user_data" {
template = file("${path.module}/cloud_init.cfg")
}
Subiquity 是否期望从 中提取其配置cloud_init.cfg
?我对此表示怀疑。