Fundamentos do Packer e QEMU/KVM: Criando Imagens Automatizadas
Nota: Este tutorial é o primeiro de uma série de 6 tutoriais sobre criação de imagens QEMU/KVM com Packer. A série completa abordará desde os fundamentos até técnicas avançadas de personalização e integração com pipelines CI/CD, cobrindo Oracle Linux, Debian e Ubuntu.
Introdução
A criação manual de imagens de máquinas virtuais é um processo demorado, propenso a erros e difícil de reproduzir consistentemente. Imagine ter que instalar manualmente um sistema operacional, configurar pacotes, aplicar atualizações e otimizar configurações toda vez que precisar de uma nova imagem. Agora multiplique isso por dezenas ou centenas de máquinas em um ambiente corporativo.
É aqui que o Packer entra como uma ferramenta revolucionária para DevOps e administradores de sistemas. Desenvolvido pela HashiCorp, o Packer permite automatizar todo o processo de criação de imagens de máquinas virtuais para múltiplas plataformas a partir de uma única configuração.
Neste primeiro tutorial da nossa série, vamos explorar os fundamentos do Packer em conjunto com QEMU/KVM, preparar nosso ambiente de desenvolvimento e criar nosso primeiro arquivo de configuração básico.
O que é Virtualização com QEMU/KVM?
Antes de mergulharmos no Packer, vamos entender brevemente o que é QEMU/KVM:
QEMU (Quick Emulator) é um emulador e virtualizador de código aberto que pode executar sistemas operacionais e programas feitos para uma máquina em uma arquitetura diferente. Quando combinado com o KVM (Kernel-based Virtual Machine), um módulo de virtualização no kernel Linux, o QEMU pode alcançar desempenho próximo ao nativo.
Principais características do QEMU/KVM:
- Código aberto: Totalmente gratuito e de código aberto
- Desempenho: Com KVM, oferece virtualização com desempenho próximo ao nativo
- Flexibilidade: Suporta diversos sistemas operacionais convidados
- Formatos de disco: Trabalha com vários formatos de disco virtual (raw, qcow2, vmdk, etc.)
- Integração: Base para muitas soluções de virtualização como libvirt, OpenStack e Proxmox
O que é o Packer?
Packer é uma ferramenta de código aberto para criar imagens de máquinas idênticas para múltiplas plataformas a partir de uma única configuração. Desenvolvido pela HashiCorp (mesma empresa por trás do Terraform, Vault e Consul), o Packer automatiza o processo de criação de imagens para:
- Máquinas virtuais (QEMU/KVM, VMware, VirtualBox)
- Contêineres (Docker)
- Nuvem pública (AWS AMI, Azure VHD, Google Compute Image)
- E muitas outras plataformas
Por que usar o Packer?
- Automação: Elimina processos manuais e repetitivos
- Consistência: Garante que todas as imagens sejam criadas da mesma forma
- Versionamento: Permite versionar suas configurações de imagem como código
- Multi-plataforma: Cria imagens para múltiplas plataformas simultaneamente
- Integração com IaC: Complementa ferramentas como Terraform e Ansible
- Imutabilidade: Facilita a adoção de infraestrutura imutável
Preparando o Ambiente de Desenvolvimento
Vamos configurar nosso ambiente para trabalhar com Packer e QEMU/KVM. Siga os passos abaixo para instalar as ferramentas necessárias:
Pré-requisitos
- Sistema operacional Linux (usaremos Ubuntu/Debian neste exemplo)
- Acesso de administrador (sudo)
- Processador com suporte a virtualização (Intel VT-x ou AMD-V)
- Pelo menos 4GB de RAM e 20GB de espaço em disco
Instalando o QEMU/KVM
1
2
3
4
5
6
7
8
# Atualizar repositórios
sudo apt update
# Instalar QEMU e ferramentas relacionadas
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst
# Verificar se o KVM está disponível
kvm-ok
Se o comando kvm-ok
retornar “KVM acceleration can be used”, seu sistema está pronto para usar KVM.
Instalando o Packer
O Packer está disponível em repositórios oficiais, mas para garantir que temos a versão mais recente, vamos usar o repositório da HashiCorp:
1
2
3
4
5
6
7
8
9
10
11
# Adicionar a chave GPG do HashiCorp
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
# Adicionar o repositório do HashiCorp
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
# Atualizar e instalar o Packer
sudo apt update && sudo apt install -y packer
# Verificar a instalação
packer version
Certifique-se de que a versão do Packer seja 1.10.0 ou superior, conforme recomendado em nosso projeto.
Estrutura de Diretórios
Para manter nosso projeto organizado, vamos criar uma estrutura de diretórios recomendada:
1
2
3
4
5
6
# Criar diretório do projeto
mkdir -p ~/packer-kvm-tutorial/tutorial1
cd ~/packer-kvm-tutorial/tutorial1
# Criar subdiretórios
mkdir -p http scripts
Esta estrutura básica nos servirá bem para este primeiro tutorial:
http/
: Armazenará arquivos que serão servidos via HTTP durante a instalaçãoscripts/
: Conterá scripts de provisionamento
Entendendo a Estrutura do Arquivo Packer (HCL)
O Packer usa o formato HCL (HashiCorp Configuration Language) para seus arquivos de configuração. Vamos entender as principais seções de um arquivo Packer:
1. Bloco packer
Define a versão mínima do Packer necessária e os plugins requeridos:
1
2
3
4
5
6
7
8
9
packer {
required_version = ">= 1.10.0"
required_plugins {
qemu = {
version = "= 1.1.0"
source = "github.com/hashicorp/qemu"
}
}
}
2. Bloco variable
Define variáveis que podem ser reutilizadas em todo o arquivo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
variable "vm_name" {
default = "ubuntu-kvm-template.raw"
}
variable "disk_size" {
default = "16384"
}
variable "iso_url" {
default = "https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso"
}
variable "iso_checksum" {
default = "a4acfda10b18da50e2ec50ccaf860d7f20823f8f3100053d30f137dc7cc46e9f"
}
3. Bloco source
Define a configuração da máquina virtual e do provedor (QEMU neste caso):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
source "qemu" "iso" {
vm_name = var.vm_name
iso_url = var.iso_url
iso_checksum = var.iso_checksum
disk_size = var.disk_size
memory = 2048
disk_image = false
output_directory = "build/os-base"
accelerator = "kvm"
disk_interface = "virtio"
format = "raw"
net_device = "virtio-net"
boot_wait = "3s"
http_directory = "http"
cpu_model = "host"
ssh_username = "packer"
ssh_password = "packer"
ssh_timeout = "60m"
}
4. Bloco build
Define como a imagem será construída, incluindo provisionadores:
1
2
3
4
5
6
7
8
9
10
build {
sources = ["source.qemu.iso"]
# Exemplo de provisionador para executar um script
provisioner "shell" {
inline = [
"echo 'Instalação concluída com sucesso!'"
]
}
}
Criando Nosso Primeiro Arquivo Packer
Vamos criar um arquivo Packer básico para entender como funciona. Este exemplo não criará uma imagem completa ainda, mas nos ajudará a entender a estrutura e validar nossa configuração.
Crie um arquivo chamado basic.pkr.hcl
no diretório do projeto:
1
nano ~/packer-kvm-tutorial/tutorial1/basic.pkr.hcl
Adicione o seguinte conteúdo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
packer {
required_version = ">= 1.10.0"
required_plugins {
qemu = {
version = "= 1.1.0"
source = "github.com/hashicorp/qemu"
}
}
}
variable "vm_name" {
default = "basic-vm-template.raw"
}
variable "disk_size" {
default = "8192"
}
variable "iso_url" {
default = "https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso"
}
variable "iso_checksum" {
default = "a4acfda10b18da50e2ec50ccaf860d7f20823f8f3100053d30f137dc7cc46e9f"
}
source "qemu" "iso" {
vm_name = var.vm_name
iso_url = var.iso_url
iso_checksum = var.iso_checksum
disk_size = var.disk_size
memory = 2048
disk_image = false
output_directory = "build/basic"
accelerator = "kvm"
disk_interface = "virtio"
format = "raw"
net_device = "virtio-net"
boot_wait = "3s"
http_directory = "http"
cpu_model = "host"
ssh_username = "packer"
ssh_password = "packer"
ssh_timeout = "60m"
# Este comando não funcionará sem um arquivo de automação adequado
# Está aqui apenas para ilustrar a estrutura
boot_command = [
"<esc><wait>",
"install <wait>",
"preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg <wait>",
"<enter><wait>"
]
}
build {
sources = ["source.qemu.iso"]
# Exemplo simples de provisionador
provisioner "shell" {
inline = [
"echo 'Este é um exemplo básico de provisionamento.'"
]
}
}
Validando o Arquivo Packer
Antes de tentar construir uma imagem, é uma boa prática validar seu arquivo Packer para garantir que não há erros de sintaxe:
1
2
3
cd ~/packer-kvm-tutorial/tutorial1
packer init .
packer validate basic.pkr.hcl
Se tudo estiver correto, você verá a mensagem “The configuration is valid.”
Nota: Este arquivo básico não construirá uma imagem funcional ainda, pois não temos os arquivos de automação necessários (como o preseed.cfg mencionado no boot_command). Nos próximos tutoriais, abordaremos a criação desses arquivos para diferentes distribuições Linux.
Entendendo os Componentes Principais
Vamos revisar os componentes principais que vimos no nosso arquivo básico:
1. Variáveis
As variáveis permitem parametrizar sua configuração, facilitando a reutilização e personalização:
1
2
3
variable "vm_name" {
default = "basic-vm-template.raw"
}
Você pode substituir o valor padrão ao executar o Packer:
1
packer build -var "vm_name=custom-template.raw" basic.pkr.hcl
2. Provedor QEMU
O provedor QEMU configura como a máquina virtual será criada:
vm_name
: Nome do arquivo de imagem resultanteiso_url
eiso_checksum
: Localização e verificação da ISOdisk_size
: Tamanho do disco em MBmemory
: Quantidade de RAM em MBaccelerator
: Usa KVM para melhor desempenhoformat
: Formato do disco (raw, qcow2, etc.)boot_command
: Comandos enviados durante o boot para automatizar a instalação
3. Provisionadores
Os provisionadores permitem configurar a máquina após a instalação do sistema operacional:
shell
: Executa comandos shell na máquinafile
: Copia arquivos para a máquinaansible
: Executa playbooks Ansible- E muitos outros…
Próximos Passos
Neste tutorial, aprendemos os fundamentos do Packer e QEMU/KVM, preparamos nosso ambiente de desenvolvimento e criamos um arquivo Packer básico. No próximo tutorial, vamos criar nossa primeira imagem completa para Oracle Linux usando Kickstart para automatizar a instalação.
Você já deve estar se perguntando:
- Como automatizar completamente a instalação sem interação manual?
- Como personalizar a imagem com pacotes e configurações específicas?
- Como otimizar a imagem final para uso em produção?
Todas essas perguntas serão respondidas nos próximos tutoriais da série!
Exercícios Práticos
Para fixar o conhecimento adquirido neste tutorial, tente os seguintes exercícios:
- Modifique o arquivo
basic.pkr.hcl
para usar uma ISO diferente (como Debian ou CentOS) - Altere os valores padrão das variáveis (tamanho do disco, memória, etc.)
- Adicione comentários explicativos ao arquivo para documentar cada seção
- Experimente adicionar mais variáveis para outros parâmetros (como
cpu_model
ounet_device
)
Conclusão
Neste primeiro tutorial, estabelecemos as bases para nossa jornada de criação automatizada de imagens com Packer e QEMU/KVM. Aprendemos sobre os conceitos fundamentais, preparamos nosso ambiente de desenvolvimento e criamos nosso primeiro arquivo de configuração Packer.
Nos próximos tutoriais, vamos mergulhar mais fundo na automação completa da criação de imagens para diferentes distribuições Linux, começando com Oracle Linux e o método Kickstart.
Até lá, experimente com o arquivo básico que criamos e familiarize-se com a sintaxe HCL e os conceitos do Packer!