ساخت image ماشین مجازی باید مسیر ورود، پایان تنظیم و خاموشی را هم مشخص کند. امشب image معتبر Ubuntu را در VM موقت تنظیم و خروجی qcow2 را با بوت مستقل بررسی می‌کنیم.

این جلسه بخشی از دورهٔ لینوکس ۳۰۵ در ۶۰ شب است.

جایگاه در دوره: هدف‌های 353.2، 353.3 آزمون 305-300.

محیط: hv-a با KVM و Packer، image معتبر شب ۱۱ و کلید SSH مستقل؛ بستهٔ xorriso برای ساخت CD seed نصب باشد. خروجی جدید است و پایه را تغییر نمی‌دهیم.

seed مخصوص ساخت#

در ~/lpic305/packer-qemu/seed، الگوی user-data شب ۱۲ را با public key دوره قرار بده. meta-data دارای instance-id: packer305-v1 و local-hostname: packer305-build باشد. حساب student داخل این VM sudo بدون password دارد. هیچ private key داخل seed/ نیست.

فایل lab.pkr.hcl در پوشهٔ بالایی:

packer {
  required_plugins {
    qemu = {
      source  = "github.com/hashicorp/qemu"
      version = "= 1.1.7"
    }
  }
}

variable "base_image" { type = string }
variable "base_checksum" { type = string }
variable "ssh_key" { type = string }

source "qemu" "lab305" {
  iso_url              = var.base_image
  iso_checksum         = var.base_checksum
  disk_image           = true
  output_directory     = "output-lab305-v1"
  vm_name              = "lab305.qcow2"
  accelerator          = "kvm"
  format               = "qcow2"
  disk_size            = "12G"
  memory               = 2048
  cpus                 = 2
  headless             = true
  net_device           = "virtio-net"
  disk_interface       = "virtio"
  cd_files             = ["seed/user-data", "seed/meta-data"]
  cd_label             = "cidata"
  ssh_username         = "student"
  ssh_private_key_file = var.ssh_key
  ssh_timeout          = "15m"
  shutdown_command     = "sudo shutdown -P now"
}

build {
  sources = ["source.qemu.lab305"]
  provisioner "shell" {
    inline = [
      "sudo cloud-init status --wait",
      "printf 'packer-qemu305-v1\\n' | sudo tee /etc/lpic305-build"
    ]
  }
}

disk_image ورودی را disk قابل بوت در نظر می‌گیرد؛ iso_url در این حالت نام گزینه است و الزاماً ISO نصب نیست. CD دارای برچسب cidata دادهٔ NoCloud را ارائه می‌کند. Builder پورت SSH موقت را برای communicator، یعنی مسیر ارتباط provisioner با مهمان، آماده می‌کند؛ listener و log را در شبکهٔ lab بررسی کن.

cd ~/lpic305/packer-qemu
export PKR_VAR_base_image="$BASE_IMAGE"
export PKR_VAR_base_checksum="sha256:$(sha256sum "$BASE_IMAGE" | cut -d ' ' -f 1)"
export PKR_VAR_ssh_key="$HOME/lpic305/keys/id_ed25519"
packer init .
packer fmt .
packer validate .
packer build .
qemu-img info output-lab305-v1/lab305.qcow2

digest بالا از artifact قبلاً تأییدشده محاسبه می‌شود؛ جای بررسی اصالت شب ۱۱ نیست. failure ورود را با user-data، public key، زمان cloud-init و log QEMU بررسی کن؛ password عمومی یا timeout بی‌حد اضافه نکن.

آزمون و بازگشت: خروجی را با disk مستقل و همان هویت ساخت در شبکهٔ isolated بوت کن، marker را بخوان و خاموش کن. این خروجی هنوز template عمومی نیست؛ برای instanceهای تازه، یک کپی را با روش شب‌های ۲۹ و ۵۵ پاک‌سازی کن و با seed تازه دوباره بوت کن. UUID/MAC و host key جدید باید بررسی شوند. در خطا، فقط خروجی build ناموفق را پس از قطع QEMU کنار بگذار؛ image پایه محفوظ است.

منبع: builder QEMU ، communicator ، shell provisioner ، متغیرهای HCL .