Packer를 사용하여 VM 골든 이미지 빌드

KubeVirt Blog를 보다가 관심 가는 글이 보여서 AI번역+약간 교정해 보았습니다.
출처: https://kubevirt.io/2025/Building-VM-golden-image-with-Packer.html

소개

VM 골든 이미지를 생성하고 유지하는 데는 시간이 많이 소요될 수 있으며, 로컬 가상화 도구와 수동 설정이 필요한 경우가 많습니다. 쿠버네티스 클러스터 내에서 KubeVirt를 실행하면 컨테이너와 함께 가상 머신을 관리할 수 있지만, 일관되고 재사용 가능한 VM 이미지를 생성하는 자동화 기능이 부족합니다.

여기서 Packer 와 새로운 KubeVirt 플러그인이 등장합니다. 이 플러그인을 사용하면 Kubernetes에서 직접 VM 이미지를 빌드하여 ISO에서 OS 설치를 자동화하고, 빌드 중에 VM을 사용자 지정하고, 재사용 가능한 부팅 볼륨을 생성할 수 있으며, 이 모든 작업이 클러스터를 벗어나지 않고도 가능합니다.

필수 조건

시작하기 전에 다음이 설치되어 있는지 확인하세요.

플러그인 기능

KubeVirt용 Packer 플러그인은 VM 골든 이미지 생성 프로세스를 단순화하는 다양한 기능을 제공합니다.

  • HCL Template : HCL 템플릿을 사용하여 인프라를 코드로 정의하여 버전 관리와 재사용을 쉽게 할 수 있습니다 .
  • ISO Installation : kubevirt-iso 빌더를 사용하여 ISO 파일에서 VM 골든 이미지를 빌드합니다.
  • ISO Media Files : 설치 과정에서 추가 파일(예: 구성, 스크립트 등)을 포함합니다.
  • Boot Command : 미리 정의된 명령 세트를 사용하여 VNC 연결을 통해 VM 부팅 프로세스를 자동화합니다 .
  • Integrated SSH/WinRM Access : SSH 또는 WinRM을 통해 VM을 프로비저닝하고 사용자 정의합니다 .

참고 : 이 플러그인은 현재 사전 출시 단계에 있으며 Red Hat 과 HashiCorp 에서 함께 활발하게 개발 중입니다.

플러그인 구성 요소

이 플러그인의 핵심 구성 요소는 kubevirt-iso 빌더입니다. 이 빌더를 사용하면 ISO 파일에서 시작하여 Kubernetes 클러스터에 직접 VM 골든 이미지를 생성할 수 있습니다.

빌더 디자인

설계

이 다이어그램은 KubeVirt 플러그인과 함께 Packer를 사용하여 Kubernetes 클러스터에서 부팅 가능한 볼륨을 구축하는 워크플로를 보여줍니다.

  1. ISO 이미지에서 임시 VM을 만듭니다.
  2. Shell 이나 Ansible 프로비저 너를 사용하여 프로비저닝을 실행합니다.
  3. VM의 디스크를 복제하여 재사용 가능한 부팅 볼륨( DataVolume 및 DataSource )을 생성합니다.

이 부팅 가능한 볼륨은 설치를 반복하지 않고도 새로운 VM을 인스턴스화하는 데 재사용될 수 있습니다.

단계별 예제: Fedora VM 이미지 빌드

다음 Packer 템플릿(Fedora 42)은 주요 기능을 보여줍니다.

  • kubevirt-iso 빌더를 사용한 ISO 기반 설치.
  • 설치를 자동화하기 위한 내장된 구성 파일입니다.
  • GRUB에 ks.cfg 주입해서 위한 부팅 명령을 보냅니다 .
  • Shell 프로비저너를 사용한 SSH 프로비저닝 .
  • InstanceTypes 및 Preferences 와의 완벽한 통합 .

Kubernetes 클러스터 내에서 Fedora VM 이미지를 빌드하려면 다음 단계를 따르세요.

1단계: KubeConfig 변수 내보내기

Packer 플러그인에서도 사용되는 KubeConfig 변수를 내보내세요.

export KUBECONFIG=~/.kube/config

이는 Kubernetes 클러스터와 통신하는 데 필요합니다.

2단계: ISO DataVolume 배포

Fedora ISO를 클러스터의 스토리지로 가져오려면 DataVolume을 만듭니다.

kubectl apply -f - <<EOF
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: fedora-42-x86-64-iso
  annotations:
    #
    # This annotation triggers immediate binding of the PVC,
    # speeding up provisioning.
    #
    cdi.kubevirt.io/storage.bind.immediate.requested: "true"
spec:
  source:
    http:
      #
      # Please check if this URL link is valid, in case the import fails.
      # If so, please modify the URL here below.
      #
      url: "https://download.fedoraproject.org/pub/fedora/linux/releases/42/Server/x86_64/iso/Fedora-Server-dvd-x86_64-42-1.1.iso"
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 3Gi
EOF

대안: 로컬 ISO 업로드

URL에서 가져오는 대신 virtctl 클라이언트 도구를 사용하여 로컬 ISO를 업로드할 수 있습니다.

virtctl image-upload dv fedora-42-x86-64-iso \
  --size=3Gi \
  --image-path=./Fedora-Server-dvd-x86_64-42-1.1.iso \

Fedora Server 42 ISO는 Fedora 공식 웹사이트에서 다운로드할 수 있습니다.

3단계: 킥스타트 파일 만들기

이 Kickstart 파일은 Fedora 설치를 자동화하여 무인 VM 설정을 가능하게 합니다.

다음 구성으로 ks.cfg 이름의 파일을 만듭니다.

cat > ks.cfg << 'EOF'
cdrom
text
firstboot --disable
lang en_US.UTF-8
keyboard us
timezone Europe/Paris --utc
selinux --enforcing
rootpw root
firewall --enabled --ssh
network --bootproto dhcp
user --groups=wheel --name=user --password=root --uid=1000 --gecos="user" --gid=1000

bootloader --location=mbr --append="net.ifnames=0 biosdevname=0 crashkernel=no"

zerombr
clearpart --all --initlabel
autopart --type=lvm

poweroff

%packages --excludedocs
@core
qemu-guest-agent
openssh-server
%end

%post
systemctl enable --now sshd
systemctl enable --now qemu-guest-agent
%end
EOF

이 구성을 사용하면 SSH가 임시 VM을 프로비저닝하고 QEMU 게스트 에이전트가 KubeVirt 자체와 더 잘 통합될 수 있습니다.

4단계: Packer 템플릿 만들기

Packer 템플릿의 예를 만들어 보세요( edora.pkr.hcl):

cat > fedora.pkr.hcl << 'EOF'
packer {
  required_plugins {
    kubevirt = {
      source  = "github.com/hashicorp/kubevirt"
      version = ">= 0.8.0"
    }
  }
}

variable "kube_config" {
  type    = string
  default = "${env("KUBECONFIG")}"
}

variable "namespace" {
  type    = string
  default = "vm-images"
}

variable "name" {
  type    = string
  default = "fedora-42-rand-85"
}

source "kubevirt-iso" "fedora" {
  # Kubernetes configuration
  kube_config   = var.kube_config
  name          = var.name
  namespace     = var.namespace

  # ISO configuration
  iso_volume_name = "fedora-42-x86-64-iso"

  # VM type and preferences
  disk_size          = "10Gi"
  instance_type      = "o1.medium"
  preference         = "fedora"
  os_type            = "linux"

  # Default network configuration
  networks {
    name = "default"

    pod {}
  }

  # Files to include in the ISO installation
  media_files = [
    "./ks.cfg"
  ]

  # Boot process configuration
  # A set of commands to send over VNC connection
  boot_command = [
    "<up>e",                            # Modify GRUB entry
    "<down><down><end>",                # Navigate to kernel line
    " inst.ks=hd:LABEL=OEMDRV:/ks.cfg", # Set kickstart file location
    "<leftCtrlOn>x<leftCtrlOff>"        # Boot with modified command line
  ]
  boot_wait                 = "10s"     # Time to wait after boot starts
  installation_wait_timeout = "15m"     # Timeout for installation to complete

  # SSH configuration
  communicator      = "ssh"
  ssh_host          = "127.0.0.1"
  ssh_local_port    = 2020
  ssh_remote_port   = 22
  ssh_username      = "user"
  ssh_password      = "root"
  ssh_wait_timeout  = "20m"
}

build {
  sources = ["source.kubevirt-iso.fedora"]

  provisioner "shell" {
    inline = [
      "echo 'Install packages, configure services, or tweak system settings here.'",
    ]
  }
}
EOF

5단계: VM 이미지 내보내기(선택 사항)

선택적으로, 새로 생성된 디스크 이미지를 내보내고 이를 containerDisk 에 패키징하여 여러 Kubernetes 클러스터에서 공유할 수 있습니다.

필수 종속성

Packer를 실행하는 컴퓨터에 다음 도구를 설치하세요.

  • virtctl: KubeVirt 클러스터에서 VM 이미지를 내보냅니다.
  • qemu-img: 원시 이미지를 qcow2 형식으로 변환합니다.
  • gunzip: 내보낸 VM 이미지를 압축 해제합니다.
  • podman: 컨테이너 이미지를 빌드하고 푸시합니다.

shell-local빌드가 완료된 후 실행되는 포스트 프로세서를 Packer 빌드에 추가합니다.

variable "registry" {
  type    = string
  default = "quay.io/containerdisks"
}

variable "registry_username" {
  type      = string
  sensitive = true
}

variable "registry_password" {
  type      = string
  sensitive = true
}

variable "image_tag" {
  type    = string
  default = "latest"
}

build {
  ...

  post-processor "shell-local" {
    inline = [
      # Export VM disk image from PVC
      "virtctl -n ${var.namespace} vmexport download ${var.name}-export --pvc=${var.name} --output=${var.name}.img.gz",

      # Decompress exported VM image
      "gunzip -k ${var.name}.img.gz",

      # Convert raw image to qcow2 (smaller and more efficient format)
      "qemu-img convert -c -O qcow2 ${var.name}.img ${var.name}.qcow2",

      # Generate Containerfile
      "echo 'FROM scratch' > ${var.name}.Containerfile",
      "echo 'COPY ${var.name}.qcow2 /disk/' >> ${var.name}.Containerfile",

      # Login to registry
      "podman login -u ${var.registry_username} -p ${var.registry_password} ${var.registry}",

      # Build and push image
      "podman build -t ${var.registry}/${var.name}:${var.image_tag} -f ${var.name}.Containerfile .",
      "podman push ${var.registry}/${var.name}:${var.image_tag}"
    ]
  }
}

레지스트리 사용자 이름 및 비밀번호와 같은 민감한 자격 증명은 템플릿에 하드코딩되어서는 안 됩니다.

6단계: Packer 플러그인 초기화

다음 명령을 한 번 실행하여 Packer 플러그인을 설치하세요.

packer init fedora.pkr.hcl

이렇게 하면 KubeVirt 플러그인이 자동으로 다운로드되고 설정됩니다.

7단계: Packer 빌드 실행

마지막으로 다음을 사용하여 새 VM 골든 이미지를 만드는 빌드를 실행합니다.

packer build fedora.pkr.hcl

Packer는 Kubernetes 클러스터에 새로운 VM 골든 이미지를 생성합니다.

결론

이 연습에서는 Packer와 KubeVirt 플러그인을 사용하여 Kubernetes 내에서 Fedora VM 골든 이미지를 구축했습니다. ISO 소스를 정의하고, Kickstart 구성을 사용하여 설치를 자동화하고, SSH를 통해 VM을 프로비저닝하는 모든 과정을 Kubernetes 클러스터 내에서 진행했습니다.

여기에서 다음을 수행할 수 있습니다.

  • 부팅 가능한 볼륨을 재사용하여 새로운 VM을 즉시 시작합니다.
  • CI/CD 파이프라인에 Packer 빌드를 통합합니다.
  • RHEL 및 Windows 와 같은 다른 운영 체제에 대한 이미지를 빌드하기 위해 동일한 프로세스를 적용합니다 .

이 플러그인은 아직 사전 릴리스 단계이지만 이미 Kubernetes 내에서 일관된 VM 이미지를 생성하는 간소화된 방법을 제공합니다.

한번 시도해 보시고 GitHub 에서 피드백이나 기여를 공유해 보세요 !

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

You May Also Like
Read More

kubevirt-manager 소개

kubevirt-manager 홈페이지의 3개 페이지에 있는 내용을 하나로 정리해 봤습니다. 간단하고 효과적이며 사용자 친화적인 웹 사용자 인터페이스를 통해 KubeVirt 워크로드를…
Read More

Discourse 설치하기

오픈소스 커뮤니티 솔루션으로 유명한 Discourse를 설치해봤습니다. 설치 환경 제 블로그, 마스토돈과 기타 등등을 돌리고 있는 홈서버가 있습니다. Discourse를…
Read More

OpenSCAP의 profile 정보

OpenSCAP을 Lab 연습하다 통해서 처음 접해봤습니다. 사용 가능한 profile들이 다양했고, 각 프로파일의 점검항목(체크리스트)에 대한 구체적인 내용이 궁금해졌습니다. cli에서…
Read More

VirtualMachineInstanceMigrations RBAC 강화

KubeVirt Blog를 보다가 관심 가는 글이 보여서 AI번역+약간 교정해 보았습니다.출처: https://kubevirt.io/2025/Hardening-VMIM.html 컨텍스트 VM 라이브 마이그레이션 요청은 VirtualMachineInstanceMigration 인스턴스로 표현됩니다.…
Read More

Harvester v1.3.0 Release

Harvester v1.3.0이 릴리즈됐습니다. 릴리즈 노트에 있는 내용 기계번역해서 정리해 봤습니다. https://github.com/harvester/harvester/releases 경고: Harvestter와 함께 Rancher v2.7.11을 사용하는 경우,…