Automatize a criação de templates de imagem com o Packer
O docker representou uma mudança muito grande de paradigma, tanto para o desenvolvimento de aplicações como para a infraestrutura que sustenta estas aplicações.
Uma das facilidades do docker é a criação de uma imagem para execução das aplicações, entretanto o que poderia ser um equivalente na área de virtualização?
Geralmente as ferramentas de virtualização (vmware, virtualbox, kvm, xen, etc…) permitem a criação de máquinas de template, entretanto a criação destes templates, geralmente é feita na mão é com isso não podemos replicar o sucesso ou falha do processo.
Idealmente o melhor seria fazer a instalação do sistema operacional na vm de forma automatizada. Para isso temos o packer.
Packer é um projeto da hashicorp que permite o build automatizado de imagens.
O build é definido em código usando um arquivo em json (template), um template permite a construção de imagens nas mais diversas tecnologias de virtualização, inclusive na nuvem (amazon ec2).
Após a criação das imagens pode ser feito o provisionamento do servidor usando bashscript, ansible, puppet, chef, etc…
Pode ser definido um post-processador que após a geração do template, efetue a compactação da imagem, o envio para uma cloud, etc…
O uso do packer ajuda muito a criar uma infra completamente definida em código.
Vamos a parte prática:
O projeto está disponível no github em: https://github.com/mycloudlab/packer-virtualbox-centos7-demo, você pode fazer um clone do projeto e seguir a seção building do README.md.
Abaixo descrevo o funcionamento da solução de forma interativa e prática.
Crie a seguinte estrutura de pasta:
packer
|
+-- http
A instalação de um sistema operacional conta com diversos passos, como configurar usuário, setar timezone, configuração de bootloader, partições de disco rede, firewall, etc…
A redhat criou um projeto chamado kickstart, que é usado para definir todos os passos acima em código usando um arquivo KS (KickStart), e diversos sistemas operacionais são compativeis com o kickstart!
o kickstart é fornecido via rede (http) para o sistema de build da imagem, o packer sobe um servidor http durante a instalação, então na pasta http devemos criar um arquivo chamado anaconda-ks.cfg, esta pasta (http) também pode ser usada para carregar arquivos posteriormente a instalação:
#version=DEVEL
# System authorization information
#auth --enableshadow --passalgo=sha512
# Use CDROM installation media
#cdrom
# Use graphical install
#graphical
# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=br --xlayouts='br'
# System language
lang en_US.UTF-8
eula --agreed
reboot
# Network information
network --bootproto=dhcp --device=enp0s3 --onboot=off --noipv6
# Root password
rootpw --plaintext root
firewall --service=ssh
# System services
services --enabled=NetworkManager,sshd,chronyd
# System timezone
timezone America/New_York --isUtc
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel
%packages
@^minimal
@core
chrony
kexec-tools
%end
%addon com_redhat_kdump --enable --reserve-mb='auto'
%end
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
Agora vamos fazer o template e criar o script de provisionamento, na pasta packer crie o arquivo centos-7-base.json:
{
"builders": [
{
"type": "virtualbox-iso",
"boot_command": [
"<tab> <wait>",
"text ks=http://:/anaconda-ks.cfg <wait>",
"<enter> <wait>"
],
"boot_wait": "5s",
"disk_size": 81920,
"guest_os_type": "RedHat_64",
"headless": false,
"http_directory": "http",
"iso_urls": [
"http://centos.pop-es.rnp.br/7/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso"
],
"iso_checksum_type": "md5",
"iso_checksum": "5848f2fd31c7acf3811ad88eaca6f4aa",
"ssh_username": "root",
"ssh_password": "root",
"ssh_port": 22,
"ssh_wait_timeout": "360s",
"shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p",
"guest_additions_path": "VBoxGuestAdditions_.iso",
"virtualbox_version_file": ".vbox_version",
"vm_name": "centos-7-x86_64-base",
"output_directory": "output-iso-base",
"vboxmanage": [
[
"modifyvm",
"",
"--memory",
"512"
],
[
"modifyvm",
"",
"--cpus",
"2"
]
]
}
],
"provisioners": [
{
"type": "shell",
"script": "configure-image.sh"
}
]
}
Com isso podemos agora criar o arquivo configure-image.sh que será usado para configurar o servidor após instalação do SO:
Crie na pasta packer o arquivo configure-image.sh, neste arquivo você pode colocar todos os comandos que desejar para configurar o novo servidor, para uma instalação no virtualbox costumo fazer a instalação do vbox guest additions, pois melhora o suporte do virtualbox ao servidor virtual, abaixo segue o conteúdo que faz a instalação:
#!/bin/bash
yum update -y
yum install dkms gcc make kernel-devel \
bzip2 binutils patch libgomp glibc-headers \
glibc-devel kernel-headers kernel-devel-$(uname -r) -y
ISO=$(ls ~/*.iso)
mount -o loop $ISO /mnt
cd /mnt
./VBoxLinuxAdditions.run
Feito isso agora efetuamos o build via packer com o comando abaixo(o packer deve ser instalado antes):
packer build --force centos-7-base.json
Este comando deve ser executado de dentro da pasta do packer.
No final do processo será criado uma pasta output-iso-base que conterá a imagem do sistema no formato vmdk, agora basta importar no virtualbox e ser feliz!
Para demonstrar o processo foi feito um vídeo no youtube que você pode ver isso funcionando, acesse o link e veja:
https://www.youtube.com/watch?v=MqxfuhWJv60
Tente mover o mundo - o primeiro passo será mover a si mesmo. - Platão