Vagrant: Provisionamento ágil de Máquinas Virtuais

Como a própria HashiCorp, dona do projeto Vagrant descreve a ferramenta:

“Vagrant é uma ferramenta para a construção de ambientes de desenvolvimento completo. Com um fluxo de trabalho fácil de usar e se concentrar em automação, o Vagrant reduz o tempo de configuração do ambiente de desenvolvimento, aumenta o foco em desenvolvimento/produção, e faz com que o “preparação do ambiente de desenvolvimento” seja uma desculpa do passado.

Se você é um engenheiro de operações (Infraestrutura), Vagrant lhe da um ambiente descartável e um fluxo de trabalho consistente para desenvolver e testar scripts de gerenciamento de infra-estrutura. Você pode rapidamente testar coisas como shell scripts, cookbooks do chef, módulos do puppet, e muito mais, usando virtualização local, como o VirtualBox ou VMware. Então, com a mesma configuração, você pode testar esses scripts em nuvens remotas, como AWS ou RackSpace com o mesmo fluxo de trabalho. Vale seus scripts personalizados para reciclar instâncias EC2. Pare com o malabarismo com SSH entre várias máquinas, e comece a usar Vagrant, levando solidez à sua vida.

Se você é um Desenvolvedor, Vagrant irá isolar dependências e sua configuração dentro de um único ambiente descartável, consistente, sem sacrificar nenhuma das ferramentas que você está acostumado a trabalhar como (editores, navegadores, depuradores, etc.). Uma vez que você ou alguém crie um único Vagrantfile, você só precisa do Vagrant e tudo está instalado e configurado para você trabalhar. Outros membros de sua equipe podem criar seus ambientes de desenvolvimento a partir da mesma configuração, por isso se você estiver trabalhando em Linux, Mac OS X ou Windows, todos os membros da equipe estão executando o código no mesmo ambiente, contra as mesmas dependências, tudo configurado o mesmo caminho. Diga adeus aos erros ou “funciona na minha máquina”.”

1. Introdução ao Vagrant

Espero que você fique maravilhado com esta solução de provisionamento ágil de máquinas virtuais. Ideal para quem pratica bastante laboratórios e/ou faz uso de ambientes de desenvolvimento constantemente, e perde muito tempo instalando SO, preparando o ambiente, fazendo ajustes de configuração, etc.

O Vagrant permite que você possa automatizar tudo isso durante o provisionamento da máquina virtual, e o melhor de tudo, tudo com um único arquivo e um único comando! Além de facilitar em fazer o deploy deste mesmo ambiente para outro com Vagrant, com um pequeno arquivo com pouco mais de 4,0KBs!

Antes de começarmos a parte prática, precisamos entender que o Vagrant é apenas a solução de provisionamento de máquina virtual, e não o virtualizador, por isso precisamos do hypervisor já instalado na máquina. Dentro do conceito do Vagrant, o hypervisor é o que eles chamam de provider, o provider default (padrão) do Vagrant é o VirtualBox, no entanto o mesmo possui suporte a diversos outros fornecedores como VMware, Hyper-V, Docker, etc. Porém neste how-ho será feito com VirtualBox, a forma de instalação do VirtualBox não é coberta nesse how-to, porém garanto que é MUITO simples.

Qual o link disponível do Vagrant para Download? https://www.vagrantup.com/downloads.html

O Vagrant possui suporte a algumas plataformas, dentre elas:

  • CentOS
  • Debian
  • Windows
  • MacOS X

Neste mini how-to vamos abordar tanto em CentOS quanto em Debian. Caso deseja aprender em Windows e/ou MacOS X, segue alguns links de apoio:

  1. Usando o Vagrant como ambiente de desenvolvimento no Windows
  2. Getting Started with Vagrant on OSX 10.10 Yosemite

2. Nossa Primeira Máquina Virtual Auto Provisionada

Então chega de enrolação, e vamos lá! =D

Faça o download do pacote no link https://www.vagrantup.com/downloads.html e baixe o correspondente a sua distribuição.

O modo de instalação é básico, usando o gerenciador de pacotes de baixo nível da sua distribuição. E o melhor que o Vagrant não possui dependências.


No CentOS, execute:

# rpm -ivh vagrant_1.8.5_x86_64.rpm


No Debian, execute:

# dpkg -i vagrant_1.8.5_x86_64.deb

Feita a instalação, já podemos começar a brincar com o Vagrant.

O uso do Vagrant é feito com usuário “comum” do sistema, no meu caso, estou logado no meu notebook com o usuário “elvis”. Não precisa ser feito como root!

Crie um diretório chamado MeuAmbiente (Estes procedimentos abaixo são executados em ambas as distribuições):

$ mkdir MeuAmbiente

Entre no diretório recém criado, e crie o arquivo pilar deste projeto, o vagrantfile. Abaixo segue o conteúdo do mesmo e a explicação dele como comentário no arquivo.

$ cd MeuAmbiente
$ vim vagrantfile
Vagrant.configure(2) do |config|
        config.vm.box = "ubuntu/trusty64" # Distribuição e Versão do SO
        config.vm.hostname = "linuxsrv01" # Hostname da VM
        config.vm.network "forwarded_port", guest: 80, host: 8081 # Encaminhamento de Porta de 80 para 8081
        config.vm.network "public_network", ip: "192.168.0.18" # Configuro IP público estático.
 
        config.vm.provider "virtualbox" do |vb|
                vb.memory = "1024" # 1GB de Memória RAM
                vb.cpus = "1" # Quantidade Core de CPU
                vb.name = "linuxsrv01" # Nome da máquina Virtual no VirtualBox
        end
 
        # Provisionar um servidor web (httpd) Apache com suporte a PHP5.
        config.vm.provision "shell", inline: <

O próprio arquivo é bem claro, ele tem um começo (Vagrant.configure) e um fim (end), dentro desta cláusula passamos os parâmetros de provisionamento da máquina virtual a ser criada.

  • config.vm.box: é a imagem (Box) usada na máquina virtual, por exemplo centos/7, instala a máquina virtual com CentOS 7. Essas imagens são baixadas somente no primeiro provisionamento, em outras instalações que façam uso desta mesma imagem, não será mais necessário download. Mais informações podem ser obtidas em: https://www.vagrantup.com/docs/boxes.html
  • config.vm.hostname: Hostname da máquina virtual. Mais informações podem ser obtidas em: https://www.vagrantup.com/docs/vagrantfile/machine_settings.html
  • config.vm.network: Configurações de rede, encaminhamento de portas, etc. Mais informações podem ser obtidas em: https://www.vagrantup.com/docs/networking/basic_usage.html
  • config.vm.provider: Configurações passadas para o Hypervisor provisionar a máquina com a seguintes configurações especificadas. Mais informações podem ser obtidas em: https://www.vagrantup.com/docs/providers/basic_usage.html
  • config.vm.provision: Configura os passos de provisionamento da máquina virtual durante o primeiro boot. Este aceita diversos provisionadores como: Shell Script, Ansible, Chef e Puppet. Mais informações podem ser obtidas em: https://www.vagrantup.com/docs/provisioning/basic_usage.html

Agora que já entenderam os principais parâmetros do vagrantfile, precisamos apenas criar o arquivo index.php, com a função phpinfo, para coletar as evidências de que o módulo PHP5 já está disponível no Apache para iniciar o desenvolvimento e/ou testes de aplicação (por exemplo).

$ cd MeuAmbiente
$ vim index.php

O conteúdo do arquivo PHP:

<!--?php phpinfo(); ?-->

Com esta etapa pronta, podemos provisionar nossa primeira máquina. =D
O provisionamento é muito simples, dentro do diretório com o arquivo vagrantfile, execute o milagroso comando e aguarde alguns instantes:

$ vagrant up

Observe a saída do comando “vagrant up”, e nota que cada etapa que determinamos no arquivo vagrantfile estão sendo executadas uma a uma:

==&gt; default: Preparing to unpack .../php5-readline_5.5.9+dfsg-1ubuntu4.17_amd64.deb ...
==&gt; default: Unpacking php5-readline (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Selecting previously unselected package libaprutil1-dbd-sqlite3:amd64.
==&gt; default: Preparing to unpack .../libaprutil1-dbd-sqlite3_1.5.3-1_amd64.deb ...
==&gt; default: Unpacking libaprutil1-dbd-sqlite3:amd64 (1.5.3-1) ...
==&gt; default: Selecting previously unselected package libaprutil1-ldap:amd64.
==&gt; default: Preparing to unpack .../libaprutil1-ldap_1.5.3-1_amd64.deb ...
==&gt; default: Unpacking libaprutil1-ldap:amd64 (1.5.3-1) ...
==&gt; default: Selecting previously unselected package apache2-bin.
==&gt; default: Preparing to unpack .../apache2-bin_2.4.7-1ubuntu4.13_amd64.deb ...
==&gt; default: Unpacking apache2-bin (2.4.7-1ubuntu4.13) ...
==&gt; default: Selecting previously unselected package apache2-data.
==&gt; default: Preparing to unpack .../apache2-data_2.4.7-1ubuntu4.13_all.deb ...
==&gt; default: Unpacking apache2-data (2.4.7-1ubuntu4.13) ...
==&gt; default: Selecting previously unselected package apache2.
==&gt; default: Preparing to unpack .../apache2_2.4.7-1ubuntu4.13_amd64.deb ...
==&gt; default: Unpacking apache2 (2.4.7-1ubuntu4.13) ...
==&gt; default: Selecting previously unselected package libapache2-mod-php5.
==&gt; default: Preparing to unpack .../libapache2-mod-php5_5.5.9+dfsg-1ubuntu4.17_amd64.deb ...
==&gt; default: Unpacking libapache2-mod-php5 (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Selecting previously unselected package php5.
==&gt; default: Preparing to unpack .../php5_5.5.9+dfsg-1ubuntu4.17_all.deb ...
==&gt; default: Unpacking php5 (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Selecting previously unselected package ssl-cert.
==&gt; default: Preparing to unpack .../ssl-cert_1.0.33_all.deb ...
==&gt; default: Unpacking ssl-cert (1.0.33) ...
==&gt; default: Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
==&gt; default: Processing triggers for ureadahead (0.100.0-16) ...
==&gt; default: Processing triggers for ufw (0.34~rc-0ubuntu2) ...
==&gt; default: Setting up libapr1:amd64 (1.5.0-1) ...
==&gt; default: Setting up libaprutil1:amd64 (1.5.3-1) ...
==&gt; default: Setting up libaprutil1-dbd-sqlite3:amd64 (1.5.3-1) ...
==&gt; default: Setting up libaprutil1-ldap:amd64 (1.5.3-1) ...
==&gt; default: Setting up apache2-bin (2.4.7-1ubuntu4.13) ...
==&gt; default: Setting up apache2-data (2.4.7-1ubuntu4.13) ...
==&gt; default: Setting up apache2 (2.4.7-1ubuntu4.13) ...
==&gt; default: Enabling module mpm_event.
==&gt; default: Enabling module authz_core.
==&gt; default: Enabling module authz_host.
==&gt; default: Enabling module authn_core.
==&gt; default: Enabling module auth_basic.
==&gt; default: Enabling module access_compat.
==&gt; default: Enabling module authn_file.
==&gt; default: Enabling module authz_user.
==&gt; default: Enabling module alias.
==&gt; default: Enabling module dir.
==&gt; default: Enabling module autoindex.
==&gt; default: Enabling module env.
==&gt; default: Enabling module mime.
==&gt; default: Enabling module negotiation.
==&gt; default: Enabling module setenvif.
==&gt; default: Enabling module filter.
==&gt; default: Enabling module deflate.
==&gt; default: Enabling module status.
==&gt; default: Enabling conf charset.
==&gt; default: Enabling conf localized-error-pages.
==&gt; default: Enabling conf other-vhosts-access-log.
==&gt; default: Enabling conf security.
==&gt; default: Enabling conf serve-cgi-bin.
==&gt; default: Enabling site 000-default.
==&gt; default:  * Starting web server apache2
==&gt; default: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
==&gt; default:  *
==&gt; default: Setting up ssl-cert (1.0.33) ...
==&gt; default: Setting up php5-json (1.3.2-2build1) ...
==&gt; default: php5_invoke: Enable module json for cli SAPI
==&gt; default: php5_invoke: Enable module json for apache2 SAPI
==&gt; default: Setting up php5-common (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Creating config file /etc/php5/mods-available/pdo.ini with new version
==&gt; default: php5_invoke: Enable module pdo for cli SAPI
==&gt; default: php5_invoke: Enable module pdo for apache2 SAPI
==&gt; default: Creating config file /etc/php5/mods-available/opcache.ini with new version
==&gt; default: php5_invoke: Enable module opcache for cli SAPI
==&gt; default: php5_invoke: Enable module opcache for apache2 SAPI
==&gt; default: Setting up php5-cli (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: update-alternatives:
==&gt; default: using /usr/bin/php5 to provide /usr/bin/php (php) in auto mode
==&gt; default: Creating config file /etc/php5/cli/php.ini with new version
==&gt; default: php5_invoke json: already enabled for cli SAPI
==&gt; default: php5_invoke pdo: already enabled for cli SAPI
==&gt; default: php5_invoke opcache: already enabled for cli SAPI
==&gt; default: Setting up php5-readline (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Creating config file /etc/php5/mods-available/readline.ini with new version
==&gt; default: php5_invoke: Enable module readline for cli SAPI
==&gt; default: php5_invoke: Enable module readline for apache2 SAPI
==&gt; default: Processing triggers for ureadahead (0.100.0-16) ...
==&gt; default: Processing triggers for ufw (0.34~rc-0ubuntu2) ...
==&gt; default: Setting up libapache2-mod-php5 (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Creating config file /etc/php5/apache2/php.ini with new version
==&gt; default: php5_invoke readline: already enabled for apache2 SAPI
==&gt; default: php5_invoke json: already enabled for apache2 SAPI
==&gt; default: php5_invoke pdo: already enabled for apache2 SAPI
==&gt; default: php5_invoke opcache: already enabled for apache2 SAPI
==&gt; default: Module mpm_event disabled.
==&gt; default: Enabling module mpm_prefork.
==&gt; default: apache2_switch_mpm Switch to prefork
==&gt; default:  * Restarting web server apache2
==&gt; default: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
==&gt; default:    ...done.
==&gt; default: apache2_invoke: Enable module php5
==&gt; default:  * Restarting web server apache2
==&gt; default: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
==&gt; default:    ...done.
==&gt; default: Setting up php5 (5.5.9+dfsg-1ubuntu4.17) ...
==&gt; default: Processing triggers for libc-bin (2.19-0ubuntu6.9) ...
==&gt; default: ‘/vagrant/index.php’ -&gt; ‘/var/www/html/index.php’

Após alguns instantes, podemos testar se o Apache esta no ar com o PHP 5 habilitado na máquina Virtual, como? Simples, abra seu navegador e acesse http://127.0.0.1:8081, lembre-se que fizemos o forwarding da máquina 8081 da máquina física para 80 da máquina virtual.


Nota-se que o arquivo index.php foi criado no mesmo diretório que continha o arquivo vagrantfile, durante o provisionamento, o vagrant copia tudo que tem dentro deste diretório da máquina física para dentro do diretório /vagrant, dentro da máquina virtual. Caso seja máquina CentOS em algumas versões antigas, ele sincroniza no diretório /home/vagrant/sync.

Além disso, é possível visualizar a máquina criada, diretamente no VirtualBox:

3. Outros comandos úteis do Vagrant

É possível acessar a máquina virtual provisionada via SSH pelo próprio vagrant, através do comando vagrant ssh (dentro do diretório da vm correspondente)

$ vagrant ssh
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-92-generic x86_64)
 
 * Documentation:  https://help.ubuntu.com/
 
 System information disabled due to load higher than 1.0
 
  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud
 
vagrant@linuxsrv01:~$ sudo su
root@linuxsrv01:/home/vagrant#

Este mesmo comando pode ser usado para mais de uma máquina, quando se quer acessar um host em específico execute vagrant ssh nomedamaquina:

$ vagrant ssh linuxsrv01
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-92-generic x86_64)
 
 * Documentation:  https://help.ubuntu.com/
 
 System information disabled due to load higher than 1.0
 
  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud
 
vagrant@linuxsrv01:~$

Caso deseje desligar a máquina, é possível desligar a mesma diretamente pelo próprio Vagrant, através do comando “vagrant halt”.

$ vagrant halt
==&gt; default: Attempting graceful shutdown of VM...

Em um cenário com multiplas máquinas virtuais, é possível desligar uma única máquina em específica:

$ vagrant halt linuxsrv01
==&gt; linuxsrv01: Attempting graceful shutdown of VM...

Além disso, é possível também remover a máquina virtual:

$ vagrant destroy
    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==&gt; default: Destroying VM and associated drives...

Em um cenário com multiplas máquinas virtuais, é possível remover uma única máquina em específica:

$ vagrant destroy linuxsrv01
    linuxsrv01: Are you sure you want to destroy the 'linuxsrv01' VM? [y/N] y
==&gt; linuxsrv01: Destroying VM and associated drives...

4. Adicionando novas Boxes (Imagens) no Vagrant.

Como explicado acima, quando feito o provisionamento da máquina virtual pela primeira vez, com aquela respectiva imagem da versão da distribuição ou sistema, o vagrant faz o download direto do repositório oficial (https://atlas.hashicorp.com/boxes/search), outras máquinas virtuais que forem fazer uso da mesma imagem da versão da distribuição ou sistema, não precisara fazer novamente o download, poupando esforço.

Porém existe também forma de adicionar imagens customizadas pela comunidade direto no seu Vagrant, por exemplo:

$ vagrant box add "OpenBSD 5.3 64-bit" https://dl.dropboxusercontent.com/u/12089300/VirtualBox/openbsd53_amd64.box

No link a seguir http://www.vagrantbox.es/ possui diversas Boxes (imagens) prontas para uso com Vagrant. Sinta-se a vontade para brincar com elas. \o/

5. Trabalhando como Multiplas Máquinas.

É possível construir cenários complexos, com mais de uma máquina virtual como no exemplo feito. Abaixo faremos um cenário onde teremos um balanceador de carga com Nginx e dois nós atrás com Apache (httpd) 2.4 trabalhando integrados.

O Vagrantfile multi-machine, fica configurado conforme abaixo, primeiramente crie o arquivo Vagrantfile e adicione o seguinte conteúdo:

$ vim Vagrantfile
Vagrant.configure("2") do |config|
 
        # Balanceador de Carga
        config.vm.define "nginx01" do |nginx01|
        nginx01.vm.box = "centos/7" # Distribuição e Versão do SO
        nginx01.vm.hostname = "nginx01" # Hostname da VM
        nginx01.vm.network "private_network", ip: "192.168.50.2"
        nginx01.vm.network "forwarded_port", guest: 80, host: 8080 # Encaminhamento de Porta de 8080 (Física) para 80 (VM)
 
 
        nginx01.vm.provider "virtualbox" do |vb|
                vb.memory = "512" # 512MB de Memória RAM
                vb.cpus = "1" # Quantidade Core de CPU
                vb.name = "nginx01" # Nome da máquina Virtual no VirtualBox
        end
 
                # Provisiona Nginx como Balanceador de Carga
                nginx01.vm.provision "shell", :path =&gt; "scripts/nginx.sh"
        end
 
        # Node app01
        config.vm.define "app01" do |app01|
                app01.vm.box = "centos/7" # Distribuição e Versão do SO
                app01.vm.hostname = "app01" # Hostname da VM
                app01.vm.network "private_network", ip: "192.168.50.3"
 
                app01.vm.provider "virtualbox" do |vb|
                        vb.memory = "512" # 512MB de Memória RAM
                        vb.cpus = "1" # Quantidade Core de CPU
                        vb.name = "app01" # Nome da máquina Virtual no VirtualBox
                end
 
                 # Provisiona Apache em Node 01
                app01.vm.provision "shell", :path =&gt; "scripts/apache2.sh"
        end
 
 
        # Node app02
        config.vm.define "app02" do |app02|
                app02.vm.box = "centos/7" # Distribuição e Versão do SO
                app02.vm.hostname = "app02" # Hostname da VM
                app02.vm.network "private_network", ip: "192.168.50.4"
 
                app02.vm.provider "virtualbox" do |vb|
                        vb.memory = "512" # 512MB de Memória RAM
                        vb.cpus = "1" # Quantidade Core de CPU
                        vb.name = "app02" # Nome da máquina Virtual no VirtualBox
                end
 
                 # Provisiona Apache em Node 02
                app02.vm.provision "shell", :path =&gt; "scripts/apache2.sh"
        end
 
end

Note que estamos criando tês maquinas Virtuais, uma chamada nginx01 e outras duas chamadas app01 e app02. No Nginx estamos instalando e configurando o balanceador de carga e nos apps estamos apenas instalando o apache e adicionando uma index simples.

Mas mesmo assim não fica evidente onde esta sendo executado estes procedimentos, na verdade eles estão sendo feito nos scripts, assim como a configuração também esta dentro dos scripts que estão sendo chamados pelo provisionador. Para preparar o cenário, crie dois diretórios:

  • conf
  • scripts

Execute:

$ mkdir conf
$ scripts

Adicione os dois arquivos abaixo dentro conf:

  • nginx.repo
  • balancer.conf

Execute:

$ vim conf/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
$ vim conf/balancer.conf
# Pool do Load balancer
upstream pool.linuxsysadmin.com.br {
        server 192.168.50.3;
        server 192.168.50.4;
}
 
# Informações de proxy passadas no cabeçalho HTTP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Queue-Start “t=${msec}000;
 
# Proxy Pass do balanceador
server {
    listen       80;
    server_name  localhost;
 
        location / {
                proxy_pass http://pool.linuxsysadmin.com.br;
        }
}

Em seguida copie os dois scripts abaixo para dentro do diretório scripts.

$ vim scripts/nginx.sh
#!/bin/bash
 
if [ -e "/vagrant" ]; then
 
        VAGRANT_HOME="/vagrant"
 
elif [ -e "/home/vagrant/sync" ]; then
 
        VAGRANT_HOME="/home/vagrant/sync"
 
else
 
        echo "Not sync folder"
        exit 1
 
fi
 
# Desabilita o SELinux.
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
 
# Copia o repositório oficial do Nginx para a VM.
cp -v /vagrant/conf/nginx.repo /etc/yum.repos.d
 
# Instalar Nginx.
yum -y install nginx
 
# Configura o Balanceador de Cagra.
mv -fv ${VAGRANT_HOME}/conf/balancer.conf /etc/nginx/conf.d/
 
# Subindo o serviço Nginx
systemctl restart nginx
systemctl enable nginx

$ vim scripts/apache2.sh
#!/bin/bash
 
# Determina qual o Sync Folder do Vagrant
if [ -e "/vagrant" ]; then
 
        VAGRANT_HOME="/vagrant"
 
elif [ -e "/home/vagrant/sync" ]; then
 
        VAGRANT_HOME="/home/vagrant/sync"
 
else
 
        echo "Not sync folder"
        exit 1
 
fi
 
# Desabilita o SELinux.
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
 
# Instala o apache
yum -y install httpd
 
# Cria a pagina index.html
echo "$(hostname)" &gt; /var/www/html/index.html
 
# Subindo o serviço apache
systemctl restart httpd
systemctl enable httpd

Desta forma organizamos o nosso Vagrantfile, ficando menos poluído, limpo. O conceito continua sendo o mesmo, sendo a única diferença que ao invés de passarmos vários comandos para o vagrant, apenas fazemos ele chamar um único script.

Com essa estrutura montada, basta executar “vagrant up”, a saída deverá ser parecida com a tela abaixo:

$ vagrant up
Bringing machine 'nginx01' up with 'virtualbox' provider...
Bringing machine 'app01' up with 'virtualbox' provider...
Bringing machine 'app02' up with 'virtualbox' provider...
(...)

Em meu notebook este ambiente foi criado em menos 8 minutos, levando em consideração que meu notebook possui uma configuração básica de mercado, em máquinas mais “parrudas” este ambiente seria construindo muito mais rápido. Outro fator é que eu não precisei baixar a imagem do CentOS 7, já que eu havia instalado este SO, se fosse a primeira vez provavelmente seria feito mais rápido.

Após o ambiente ser criado, basta adicionar em seu /etc/hosts na última linha:

$ sudo vim /etc/hosts
(...)
127.0.0.1       pool.linuxsysadmin.com.br

E acesse seu navegador:

Pode executar F5 para atualizar a página e verificar nginx balanceia as requisições entre os dois nodes app01 e app02. =)

Para mais informações sobre como trabalhar com o modo “Multi-machines”: https://www.vagrantup.com/docs/multi-machine/

6. Conclusão.

Bem, espero que você tenha gostado do post, e principalmente que lhe seja útil em sua jornada e carreira profissional para agilizar seus ambientes, focando no que realmente interessa, sem perder tempo com aquela dor de cabeça de criar máquina virtual, instalar o sistema operacional, preparar o ambiente, instalar e configurar dependências, etc. rs

Forte abraço e sucesso!

Zabbix: Monitorando Jobs de Backups do CA ARCServe

Olá Pessoal,

Devido a dúvida de alguns da comunidade Zabbix. Venho compartilhar o monitoramento dos Jobs do ARCServe Backup, este monitoramento é feito através do comando ca_qmgr do próprio servidor de Backup, que lista a fila e o estado dos jobs.

Utilizei um script VBS para esta tarefa, chamado de check_Arcserve_jobstatus.vbs, a qual verifica os estado dos Jobs. Este script foi utilizado pela comunidade do Nagios, como havia prazo para entregar este monitoramento, foi preciso agilizar o processo de monitoramento, sem reinventar a roda, por isto optei por utilizar o mesmo, que atendeu adequadamente a necessidade.

No entanto, é importante frisar, que não tenho conhecimento em VB Script, por essa razão não tive tempo hábil de fuçar no script e modifica-lo para torna-lo dinâmico com LLD (Low Level Discovery), o que tornaria o mesmo mais atraente.

1. Preparando o cenário

Crie uma pasta chamada Scripts dentro do diretório corrente do servidor de backup (CA ARCServe). Todo o monitoramento dos Jobs é feito exatamente neste mesmo servidor. A estrutura do diretório deve ficar da seguinte forma:

c:\Zabbix\Scripts

Em seguida copie o script abaixo dentro de C:\Zabbix\Scripts\check_Arcserve_jobstatus.vbs com seu editor de texto favorito.

iCritical = 0
iWarning = 0
iSuccess = 0
 
strCmd = CMD("""C:\Program Files\CA\ARCserve Backup\ca_qmgr.exe"" -list")
 
Lines = Split(strCmd, vbCrLf)
 
for each Line in Lines
        iPos = inStr(Line, "READY")
        if (iPos) then
                select case (Trim(Mid(Line, iPos + 42, 15)))
                case "FINISHED"
                        iSuccess = iSuccess + 1
                case "FAILED", "RUN FAILED", "CRASHED"
                        iCritical = iCritical + 1
                case "INCOMPLETE", "CANCELLED"
                        iWarning = iWarning + 1
                end select
        end if
next
 
Out = ""
 
if (iCritical) then
        Out = iCritical
end if
if (iWarning) then
        Out = iWarning
end if
if (iSuccess) then
        Out = iSuccess
end if
if (iCritical = 0) and (iWarning = 0) and (iSuccess = 0) then
        Out = 3
end if
 
WScript.StdOut.WriteLine (Out)
 
function CMD(byRef cmdLine)
        set oShell = WScript.CreateObject("WScript.Shell")
    set oExec = oShell.Exec(cmdLine)
 
    ret = oExec.StdOut.Readall()
    set oExec = nothing: Set oShell = nothing
 
        CMD = ret
end function

Edite o arquivo zabbix_agentd.conf dentro de C:\Zabbix\conf (ou o diretório onde encontra o seu arquivo de configuração) e adicionado na última linha o parâmetro necessário para que funcione o monitoramento dos Jobs de Backup.

UserParameter=job.backup.status,cscript //NoLogo C:\Zabbix\Scripts\check_Arcserve_jobstatus.vbs

Devido a questões de restrições e/ou políticas de segurança, o usuário SYSTEM, mesmo usuário proprietário dos serviços do Windows, o mesmo não tinha permissão para execução de scripts, por tanto caso você passe pela mesma situação, será necessário alterar o usuário que inicia e executa o serviço para um usuário que tenha permissões adequadas para executar este script e iniciar o serviço do agente zabbix.

Acesse o services.msc do Windows Server, e clique em propriedades do serviço Zabbix Agent, e informe a conta as permissões. No print abaixo consta o Domain Admin, no entanto, não recomendo o uso do mesmo para este cenário.

Após este ajuste é necessário reiniciar o serviço do agente zabbix para aplicar as alterações.

Em seguida crie um template no zabbix da seguinte da seguinte forma: Acesse Configurações > Templates:

Após entrar em Templates, clique em “Criar Template” e preencha o mesmo como no modelo abaixo e clique em add:

Após criar o template, clique em Administração > Geral, e em seguida selecione “Mapeamento de Valores”, e preencha os mesmos da seguinte forma (Lembre-que segui o mesmo modelo do Nagios, por tanto, pra ficar mais claro o resultado do monitoramento, essa é a forma mais intuitiva):

Volte em templates, e clique no template recém criado, entre em Aplicações e cria a aplicação “Jobs Backups”.

Após criar a aplicação, clique em itens, e crie o item abaixo de monitoramento dos Jobs e Backup.

E por fim, clique em Triggers, e crie o threshold da seguinte forma:

Feito o template, pode adicionar o mesmo no Host (Servidor de Backup CA ARCServe), e após alguns instantes já é possível monitora-lo, visualizando a coleta em Monitoramento > Dados Recentes:

Em caso de alarme, a trigger será acionada no zabbix da seguinte forma:

Pessoal espero que isso lhes ajude. De qualquer forma, forte abraço e grato pela atenção!

Fonte: CA ARCserve Backup r12 Number of Job Error Check