Navegando pela internet vemos muitos tutoriais de como usar o Vagrant em cima do Virtualbox, logo, veja nesse post como usar o Vagrant com o libvirt no Debian. O Vagrant utiliza um arquivo de configuração declarativo que descreve todos os seus requisitos de software, pacotes, configuração do sistema operacional, usuários e muito mais.
Visa espelhar os ambientes de produção, fornecendo o mesmo sistema operacional, pacotes, usuários e configurações, ao mesmo tempo em que oferece aos usuários a flexibilidade de usar seu editor, IDE e navegador favoritos.
O Vagrant também se integra às ferramentas de gerenciamento de configuração existentes, como Ansible, Chef, Docker, Puppet ou Salt, para você poder usar os mesmos scripts para configurar o Vagrant como produção.
Aqui no SempreUpdate temos publicado posts sobre o Vagrant, logo, agora será mostrado como usar o mesmo em cima do libvirt tendo como exemplo a automação de 3 servers.
Veja os posts do Vagrant já publicado clicando aqui.
E como não vamos ter o Virtualbox como gerenciador de VMs, tenha instalado o Virt-Manager que é um gerenciador de VM para libvirt KVM/Qemu.
Caso ainda não tenha instalado, veja os posts do Virt-Manager (instalação e criação de VMs) clicando aqui e aprenda a instalação e criação de máquina virtual (VM).
Como usar o Vagrant com Libvirt no Debian
Como descrito no título do post, vamos ver como usar o Vagrant com libvirt no Debian, criando uma VM, instalando e configurando um sistema, criando nossa própria box e assim desenvolver a configuração para criação dos serves.
O Vagrant é multiplataformas, executa em GNU/Linux, Mac OS, MS Windows e muito mais. Codifique facilmente em seu editor de texto favorito, edite imagens em seu programa de manipulação favorito e depure usando suas ferramentas favoritas, tudo no seu computador local.
1. Instalar o Vagrant e libvirt
Vamos em nosso Host, nesse caso o Debian 11 bullseye instalar o Vagrant do repositório que está em sua versão 2.2.14 e no momento do desenvolvimento desse post a versão disponível no site do projeto é a 2.2.19.
Caso queira fazer o download da versão 2.2.19 (no momento desse post) clique aqui.
Vamos instalar os pacotes necessários, lembrando que deverá ter privilégio de root. No meu caso estou utilizando o sudo no Debian pois ativei-o. Caso você também queira, temos um tutorial sobre como instalar e ativar o sudo no Debian.
sudo apt install libvirt-clients libvirt-daemon-system libvirt0 vagrant
Feito isso, instalamos em nosso sistema o Vagrant 2.2.14 e o Virt-Manager 1.3.2, caso não tenha instalado o virt-manager, veja como instalar aqui.
Assim sendo, já temos o Gerenciador das VMs em modo gráfico (Virt-Manager) para um melhor entendimento das VMs e o Vagrant para o provisionamento das VMs a serem criadas.
2. Instalar o sistema na VM
Nessa etapa, vamos configurar nosso sistema para posteriormente criarmos nossa própria box. Para isso, entende-se que você já tenha uma distribuição GNU/Linux instalada em uma VM. Caso ainda não, veja esse link Gerenciador de VMs Virt-Manager.
Nesse post, foi executado uma instalação padrão do Ubuntu Server 20.04 com a opção OpenSSH Server marcada para instalação. Fique a seu critérios quais outras opções instalar.
Com o sistema Ubuntu Server instalado, vamos instalar alguns pacotes que achamos necessário, além do já instalado openssh-server, ai fica ao seu critério. Aqui vamos instalar apenas 2 pacotes como exemplo, o ethstatus e o tree.
sudo apt install ethstatus tree
Agora vamos configurar o sudo sem senha. Isso é importante, pois muitos aspectos do Vagrant esperam que o usuário SSH padrão tenha um sudo sem senha configurado. Isso permite ao Vagrant configurar redes, montar pastas sincronizadas, instalar software e muito mais.
A configuração geralmente é usando o comando visudo. Com o arquivo de configuração aberto, adicione a linha abaixo no final do arquivo de configuração.
vagrant ALL = (ALL) NOPASSWD: ALL
3. Par de chaves SSH
Agora vamos fazer a configuração SSH gerando as nossas próprias chaves para torna a automação mais segura, pois o Vagrant por padrão usa um par de chaves inseguras para acesso as VMs via SSH.
Em nosso Host (máquina física), vamos gerar o par de chaves. Criamos primeiro o diretório vagrant dentro do .ssh.
mkdir ~/.ssh/vagrant
Em seguida vamos acessar o diretório vagrant e gerar nosso par de chaves.
cd ~/.ssh/vagrant
ssh-keygen -t rsa -b 4096 -q -f $HOME/.ssh/vagrant/vagrant_ubuntu_key -C 'vagrant-ubuntu-server' -N ''
Prosseguindo, vamos acessar a VM do Ubuntu Server via SSH, criar o diretório .ssh no home do usuário vagrant. Em seguida será criado o arquivo authorized_keys, dando as devidas permissões e por último copiar a chave criada no Host (máquina física) para o diretório criado na VM do Ubuntu Server.
OBS: Lembre-se de trocar o IP pelo IP de sua VM.
ssh -l vagrant 192.168.121.46
mkdir -p /home/vagrant/.ssh
touch /home/vagrant/.ssh/authorized_keys
chmod 700 /home/vagrant/.ssh
chmod 600 /home/vagrant/.ssh/authorized_keys
Feito os passos acima, sairemos da conexão SSH e copiaremos a chave que criamos (vagrant_ubuntu_key.pub) no Host para a VM Ubuntu Server.
ssh-copy-id -i ~/.ssh/vagrant/vagrant_ubuntu_key.pub [email protected]
4. Configurar SSH na VM
Devemos editar alguns parâmetros do arquivo de configuração do SSH da VM do Ubuntu Server em /etc/ssh/sshd_config, logo, deixe as linhas referentes no aquivo conforme as abaixo.
PermitRootLogin no
PubKeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
PermitEmptyPasswords no
PasswordAuthentication no
UseDNS no
5. Problema de nomenclatura de interface de rede no libvirt
O Vagrant tem problema com as nomenclaturas de rede no KVM (libvirt), sendo assim, será necessário fazer um workaround a fim de contornar este problema.
Na VM do Ubuntu Server deveremos mudar a interface de enp1s0 para eth0. Veja na imagem abaixo que é identificado a rede como enp1s0.
Sendo assim, no arquivo de configuração do Grub em /etc/default/grub, vamos editar acrescentando alguns parâmetros.
Na linha GRUB_CMDLINE_LINUX=”” do arquivo de configuração, acrescente os parâmetros “net.ifnames=0 biosdevname=0” entre as aspas duplas, ficando conforme abaixo.
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0”
Em seguida execute atualização do Grub para que seja aplicado a modificação.
sudo update-grub
Agora para indicarmos a interface de rede eth0, vamos alterar o nome de enp1s0 para eth0 fazendo backup do arquivo /etc/netplan/00-installer-config.yaml.
sed -i.backup 's/enp1s0/eth0/g' /etc/netplan/00-installer-config.yaml
Agora basta dar reboot no sistema para que a interface de rede seja identificada como eth0.
Finalizando a configuração, vamos desligar a VM do Ubuntu Server.
6. Criar uma box
Nessa etapa vamos criar nossa própria box do Ubuntu Server que configuramos na VM anteriormente, portanto, caso não queira criar sua própria box, poderá baixar os boxes disponíveis no site do projeto Vagrant.
No link abaixo as boxes são para Provider libvirt, como é o intuito desse post. Caso use outro provider, só alterar a opção para sua necessidade.
- Vagrant Boxes – libvirt
Vamos criar o diretório para nosso projeto e acessar o mesmo.
mkdir ~/Vagrant/SempreUpdate && cd ~/Vagrant/SempreUpdate
Agora baixaremos o script do repositório vagrant-libvirt.
wget https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh
Prosseguindo, copiaremos a imagem da VM do Ubuntu Server para o nosso diretório do projeto. Por padrão as imagens instaladas do KVM (libvirt) ficam no diretório /var/lib/libvirt/images.
Em nosso ambiente não criamos as imagens das VMs nesse padrão, sendo assim mude de acordo com seu ambiente. Lembre-se que deverá ter privilégio de root para a cópia.
sudo cp ~/Vms/ubuntu-server.qcow2
Concluído a cópia, execute o script para criação do box do Ubuntu Server.
sudo bash create_box.sh ubuntu-server.qcow2
Pronto! Imagem box do Ubuntu Server criado.
7. Iniciar com o Vagrant
Depois de todas as etapas acima, vamos de fato iniciar com o Vagrant com libvirt no Debian. Todas as etapas teve o intuito de demonstrar a criação de um box personalizado até mesmo por medida de segurança, sabendo a fonte de criação da mesma e também podendo ser configurada para atender as suas necessidades.
O Vagrant utiliza a linguagem HCL (Hashicorp Configuration Language) baseada em Ruby que nos possibilita definir recursos da VM tais como hostname, IP, CPU, memória, disco, quantidade de máquinas para serem criadas e scripts que serão executados ao iniciar a VM. O mesmo precisa de um Provider, que é um Hypervisor e que nesse post utilizaremos o libvirt KVM/Qemu, que será utilizado para nos fornecer os recursos de virtualização.
Para saber muito mais sobre o Vagrant, explore sua documentação clicando no link abaixo.
- Documentação – Vagrant
7.1. Adicionar a box
Vamos adicionar a box criada.
vagrant box add ubuntu-server.box --name ubuntu-server
Para listar a imagem box adicionada execute.
vagrant box list
Para remover a imagem box adicionada execute.
vagrant box remove ubuntu-server
7.2. Criar o Vagrantfile
O Vagrantfile (canse sensitive) é o arquivo de configuração que descreve o provisionamento de cada tipo de VM e que faz toda a mágica acontecer. Para criar o arquivo Vagrantfile, execute o comando com a opção -m (minimal) para remover todas as linhas comentadas e ficar somente o necessário.
vagrant init -m ubuntu-server
Vale lembrar que daqui em diante todos os comandos deverão ser executados no diretório do projeto onde se encontra o arquivo Vagrantfile.
O arquivo Vagrantfile é bastante completo tendo muitos comentários no mesmo caso você crie sem a opção -m conforme mostrado no comando acima, e com isso você consegue subir sua VM alterando apenas o nome da box para a que criamos “ubuntu-server”.
Portanto, criaremos a nossa própria configuração de provisionamento de acordo com as modificações feitas na VM do Ubuntu Server antes de criarmos a box como no caso do SSH.
7.3. Construindo o Vagrantfile
A template que criaremos teve como base o exemplo do Rodrigo Martins.
Estrutura lógica do Vagrant
Utilizaremos com essa estrutura lógica o provisionamento de um array, onde cada bloco dentre as chaves pertence a uma VM a ser criada com suas devidas variáveis de configuração declaradas.
Segue abaixo as linhas de configuração criada, sendo comentadas cada uma para que as mesmas sejam entendidas. Nesse link Vagrantfile você pode baixar o arquivo.
7.3.1. Vagrantfile comentado
# Script a executar ao iniciar VM.
$script = <<-EOF
# Mudar a senha do usuário Vagrant.
echo ‘vagrant:zxc147’ | sudo chpasswd
# Atualizar e instalar pacotes no sistema.
apt update
apt install -y htop neofetch
EOF
# Início do array.
servers=[
# Início do primeiro bloco.
{
# Adaptador de rede do host.
:vm_network => “enp3s0”,
# Hostname da VM.
:vm_hostname => “sup-master”,
# IP da VM.
:vm_ip => “192.168.0.120”,
# Imagem box utilizada na VM.
:vm_box => “ubuntu-server”,
# Quantidade de cores CPUs da VM.
:vm_cpus => 2,
# Quantidade de Memória da VM.
:vm_mem => 1536,
# Fim do primiero bloco.
},
{
:vm_network => “enp3s0”,
:vm_hostname => “sup-node01”,
:vm_ip => “192.168.0.121”,
:vm_box => “ubuntu-server”,
:vm_cpus => 1,
:vm_mem => 1024,
},
{
:vm_network => “enp3s0”,
:vm_hostname => “sup-node02”,
:vm_ip => “192.168.0.122”,
:vm_box => “ubuntu-server”,
:vm_cpus => 1,
:vm_mem => 512,
# Fim do último bloco, observando de não ter o “,” fechando o bloco.
}
# Fim do array.
]
# Início da configuração do Vagrant em sua versão 2 baseado em ruby.
Vagrant.configure(“2”) do |config|
# Nome do array e Variável declaradas em cada bloco com o domínio “srv” mesclando adequadamente em cada configuração.
servers.each do |srv|
# Define o hostname para cada server/bloco de acordo com o domínio.
config.vm.define srv[:vm_hostname] do |node|
# Configuração da box que criamos ou que baixamos.
node.vm.box = srv[:vm_box]
# O nome que a VM vai ter ao ser criada.
node.vm.hostname = srv[:vm_hostname]
# Configuração de rede pública, com IP e interface da rede em modo bridge.
node.vm.network “public_network”,
ip: srv[:vm_ip],
dev: srv[:vm_network]
# Configuração para o provider que será utilizado, no caso libvirt.
node.vm.provider :libvirt do |kvm|
# CPUs utilizada.
kvm.cpus = srv[:vm_cpus]
# Quantidade de memória.
kvm.memory = srv[:vm_mem]
# Mapa do teclado em ABNT2.
kvm.keymap = “pt-br”
# Host padrão.
kvm.host = “localhost”
# URI da conexão do sistema QEMU, padrão usado para obter o endereço IP para gerenciamento.
kvm.uri = “qemu:///system”
# Montar compartilhamento NFS no DIR especificado (/vagrant), o valor “desabled: true” desabilita; Argumento 1 – o caminho do diretório atual do host ( “.” ); Argumento 2 – o caminho do diretório a ser montado no guest ( “/vagrant” ).
node.vm.synced_folder “.”, “/vagrant”, disabled: false
# Com o valor true, o Vagrant procurará por atualizações na caixa configurada em todos os lugares vagos.
config.vm.box_check_update = false
# A chave insegura gerada automaticamente, nesse caso deixamos desabilitada com valor falso.
config.ssh.insert_key = false
# O caminho para a chave privada a ser usada no SSH na máquina convidada. Em nosso exemplo, criamos nossa própria box personalizada com uma chave SSH personalizada, isso deverá apontar para essa chave privada.
config.ssh.private_key_path = [“~/.ssh/vagrant/vagrant_ubuntu_key”]
# Mensagem que será apresentada após o comando vagrant up.
config.vm.post_up_message = “Bem-vindo a Virtualização no SempreUpdate!!!”
# Script – está no topo deste Vagrantfile. Apenas como exemplo.
#config.vm.provision “shell”, inline: $script # Onde temos a configuração para o provisionamento que será feito, no caso o script em shell.
# Script – arquivo executável dentro do diretório do projeto. Crie de acordo com sua necessidade.
#config.vm.provision “shell”, path: “script_basic.sh”
# Script – mensagem ao carregar o Vagrant. Crie de acordo com sua necessidade. Lembre de descomentar as linhas abaixo de cada comentário.
#config.vm.provision “shell”, run: “always”, inline: <<-SHELL
# echo “Seja bem-vindo ao Vangrant!”
#SHELL
## Fim do provisionamento do domínio node.
end
## Fim da definição do bloco do domínio hostname.
end
## Fim da declaração do domínio do array.
end
## Fim da configuração do Vagrant.
end
7.4. Executar o Vagrant
Após a criação do Vagrantfile de acordo com suas necessidades, execute o comando para validar o mesmo sem nenhum erro. Caso apareça erro, deverá ser corrigido o mesmo antes de continuar.
vagrant validate
Tendo o retorno Vagrantfile validated successfully, vamos carregar a VM, nesse caso o sup-master (hostname de um bloco).
vagrant up sup-master
Veja na imagem acima que todas as variáveis que declaramos no primeiro bloco do array do hostname sup-master foi carregado corretamente.
Com a VM carregada sem erros, vamos acessar a mesma com o comando abaixo.
vagrant ssh sup-master
Nas imagens abaixo veja a VM sup-master acessada, com a identificação da rede em modo bridge com o IP 192.168.0.120 e com acesso ao compartilhamento NFS do diretório do projeto ~/SempreUpdate/ProjecteFile sendo montado na VM em /vagrant.
8. Conclusão
Esse post como usar o Vagrant com libvirt no Debian foi elaborado para demostrar todas as etapas desde a instalação do Vagrant, Virt-Manager (indicando outro post para instalação do mesmo), configuração da VM previamente instalada, criação da própria imagem box em vez de fazer download das já existentes e por fim a configuração do Vagrantfile com os comentários de cada linha como visto acima.
Caso a explicação não seja a mais adequada, por favor nos comuniquem para corrigirmos, pois como muitos, sou entusiasta em relação a esta e outras ferramentas e sempre buscando conhecimento.
Para ficar atualizado no Sempre Update siga lá no canal do Telegram ou no Twitter e fique sabendo sempre de novas postagens.
Caso tenha alguma dúvida, entre em nosso grupo no Telegram e compartilhe-o.