Puppet é um software de código aberto para gerenciamento e implantação de configuração. Fundado em 2005, é multiplataforma e ainda possui linguagem declarativa própria para configuração.
As tarefas relacionadas à administração e manutenção do PostgreSQL (ou outro software realmente) consiste em processos diários e repetitivos que requerem monitoramento. Isso se aplica mesmo às tarefas operadas por scripts ou comandos por meio de uma ferramenta de agendamento. A complexidade dessas tarefas aumenta exponencialmente quando executada em uma infraestrutura massiva, no entanto, o uso do Puppet para esse tipo de tarefa pode resolver esses tipos de problemas de grande escala, pois o Puppet centraliza e automatiza o desempenho dessas operações de maneira muito ágil.
O Puppet funciona dentro da arquitetura no nível cliente/servidor onde a configuração está sendo realizada; essas operações são então difundidas e executadas em todos os clientes (também conhecidos como nós).
Geralmente rodando a cada 30 minutos, o nó dos agentes coletará um conjunto de informações (tipo de processador, arquitetura, endereço IP, etc.), também chamadas de fatos, e então enviará as informações para o master que está aguardando uma resposta para ver se há alguma nova configuração a ser aplicada.
Esses fatos permitirão que o mestre personalize a mesma configuração para cada nó.
De uma forma muito simplista, Puppet é uma das ferramentas de DevOps mais importantes disponível hoje. Neste blog vamos dar uma olhada no seguinte...
- O caso de uso para Puppet e PostgreSQL
- Instalando o Puppet
- Configurando e programando a marionete
- Configurando o Puppet para PostgreSQL
A instalação e configuração do Puppet (versão 5.3.10) descritas abaixo foram realizadas em um conjunto de hosts usando o CentOS 7.0 como sistema operacional.
O caso de uso para Puppet e PostgreSQL
Suponha que haja um problema em seu firewall nas máquinas que hospedam todos os seus servidores PostgreSQL, então seria necessário negar todas as conexões de saída ao PostgreSQL e fazê-lo o mais rápido possível.
Puppet é a ferramenta perfeita para esta situação, especialmente porque velocidade e eficiência são essencial. Falaremos sobre este exemplo apresentado na seção “Configurando Puppet para PostgreSQL” gerenciando o parâmetro listen_addresses.
Instalando o Puppet
Há um conjunto de etapas comuns a serem executadas em hosts mestre ou de agente:
Primeiro passo
Atualização do arquivo /etc/hosts com nomes de host e seu endereço IP
192.168.1.85 agent agent.severalnines.com
192.168.1.87 master master.severalnines.com puppet
Passo Dois
Adicionando os repositórios Puppet no sistema
$ sudo rpm –Uvh https://yum.puppetlabs.com/puppet5/el/7/x86_64/puppet5-release-5.0.0-1-el7.noarch.rpm
Para outros sistemas operacionais ou versões do CentOS, o repositório mais apropriado pode ser encontrado em Puppet, Inc. Yum Repositories.
Passo Três
Configuração do servidor NTP (Network Time Protocol)
$ sudo yum -y install chrony
Passo Quatro
O chrony é usado para sincronizar o relógio do sistema de diferentes servidores NTP e, assim, mantém o tempo sincronizado entre o servidor mestre e o agente.
Uma vez instalado o chrony ele deve ser ativado e reiniciado:
$ sudo systemctl enable chronyd.service
$ sudo systemctl restart chronyd.service
Passo Cinco
Desabilite o parâmetro SELinux
No arquivo /etc/sysconfig/selinux o parâmetro SELINUX (Security-Enhanced Linux) deve ser desabilitado para não restringir o acesso em ambos os hosts.
SELINUX=disabled
Passo Seis
Antes da instalação do Puppet (seja mestre ou agente), o firewall nesses hosts deve ser definido de acordo:
$ sudo firewall-cmd -–add-service=ntp -–permanent
$ sudo firewall-cmd –-reload
Instalando o Puppet Master
Uma vez que o repositório de pacotes puppet5-release-5.0.0-1-el7.noarch.rpm adicionado ao sistema, a instalação do puppetserver pode ser feita:
$ sudo yum install -y puppetserver
O parâmetro de alocação de memória máxima é uma configuração importante para atualizar no arquivo /etc/sysconfig/puppetserver para 2 GB (ou para 1 GB se o serviço não iniciar):
JAVA_ARGS="-Xms2g –Xmx2g "
No arquivo de configuração /etc/puppetlabs/puppet/puppet.conf é necessário adicionar a seguinte parametrização:
[master]
dns_alt_names=master.severalnines.com,puppet
[main]
certname = master.severalnines.com
server = master.severalnines.com
environment = production
runinterval = 1h
O serviço puppetserver usa a porta 8140 para escutar as solicitações do nó, portanto, é necessário garantir que esta porta seja habilitada:
$ sudo firewall-cmd --add-port=8140/tcp --permanent
$ sudo firewall-cmd --reload
Depois de todas as configurações feitas no mestre de marionetes, é hora de iniciar este serviço:
$ sudo systemctl start puppetserver
$ sudo systemctl enable puppetserver
Instalando o Puppet Agent
O agente Puppet no repositório de pacotes puppet5-release-5.0.0-1-el7.noarch.rpm também é adicionado ao sistema, a instalação do agente puppet pode ser realizada imediatamente:
$ sudo yum install -y puppet-agent
O arquivo de configuração do puppet-agent /etc/puppetlabs/puppet/puppet.conf também precisa ser atualizado adicionando o seguinte parâmetro:
[main]
certname = agent.severalnines.com
server = master.severalnines.com
environment = production
runinterval = 1h
A próxima etapa consiste em registrar o nó do agente no host mestre executando o seguinte comando:
$ sudo /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true
service { ‘puppet’:
ensure => ‘running’,
enable => ‘true’
}
Neste momento, no host mestre, há uma solicitação pendente do agente puppet para assinar um certificado:
Isso deve ser assinado executando um dos seguintes comandos:
$ sudo /opt/puppetlabs/bin/puppet cert sign agent.severalnines.com
ou
$ sudo /opt/puppetlabs/bin/puppet cert sign --all
Finalmente (e uma vez que o mestre de marionetes tenha assinado o certificado), é hora de aplicar as configurações ao agente recuperando o catálogo do mestre de marionetes:
$ sudo /opt/puppetlabs/bin/puppet agent --test
Neste comando, o parâmetro --test não significa um teste, as configurações recuperadas do mestre serão aplicadas ao agente local. Para testar/verificar as configurações do mestre, o seguinte comando deve ser executado:
$ sudo /opt/puppetlabs/bin/puppet agent --noop
Configurando e Programando Marionete
Puppet usa uma abordagem de programação declarativa na qual o objetivo é especificar o que fazer e não importa a maneira de alcançá-lo!
O código mais elementar do Puppet é o recurso que especifica uma propriedade do sistema como comando, serviço, arquivo, diretório, usuário ou pacote.
Abaixo é apresentada a sintaxe de um recurso para criar um usuário:
user { 'admin_postgresql':
ensure => present,
uid => '1000',
gid => '1000',
home => '/home/admin/postresql'
}
Diferentes recursos poderiam ser agregados à classe anterior (também conhecida como manifesto) de arquivo com extensão “pp” (significa Puppet Program), no entanto, vários manifestos e dados (como fatos, arquivos e templates) irão compor um módulo. Todas as hierarquias e regras lógicas estão representadas no diagrama abaixo:
O objetivo de cada módulo é conter todos os manifestos necessários para executar tarefas de forma modular. Por outro lado, o conceito de classe não é o mesmo das linguagens de programação orientadas a objetos, no Puppet funciona como um agregador de recursos.
A organização desses arquivos tem uma estrutura de diretório específica a seguir:
No qual a finalidade de cada pasta é a seguinte:
Pasta | Descrição |
manifestos | Código da marionete |
arquivos | Arquivos estáticos a serem copiados para nós |
modelos | Arquivos de modelo a serem copiados para nós gerenciados (pode ser personalizado com variáveis) |
exemplos | Manifesto para mostrar como usar o módulo |
class dev_accounts {
$rootgroup = $osfamily ? {
'Debian' => 'sudo',
'RedHat' => 'wheel',
default => warning('This distribution is not supported by the Accounts module'),
}
include accounts::groups
user { 'username':
ensure => present,
home => '/home/admin/postresql',
shell => '/bin/bash',
managehome => true,
gid => 'admin_db',
groups => "$rootgroup",
password => '$1$7URTNNqb$65ca6wPFDvixURc/MMg7O1'
}
}
Na próxima seção, mostraremos como gerar o conteúdo da pasta de exemplos, bem como os comandos para testar e publicar cada módulo.
Configurando Puppet para PostgreSQL
Antes de apresentar os diversos exemplos de configuração para implantar e manter um banco de dados PostgreSQL é necessário instalar o módulo fantoche PostgreSQL (no host do servidor) para utilizar todas as suas funcionalidades:
$ sudo /opt/puppetlabs/bin/puppet module install puppetlabs-postgresql
Atualmente, milhares de módulos prontos para uso no Puppet estão disponíveis no repositório público de módulos Puppet Forge.
Primeiro passo
Configure e implante uma nova instância do PostgreSQL. Aqui está toda a programação e configuração necessária para instalar uma nova instância do PostgreSQL em todos os nós.
O primeiro passo é criar um novo diretório de estrutura de módulo como compartilhado anteriormente:
$ cd /etc/puppetlabs/code/environments/production/modules
$ mkdir db_postgresql_admin
$ cd db_postgresql_admin; mkdir{examples,files,manifests,templates}
Então, no arquivo manifesto manifests/init.pp, você precisa incluir a classe postgresql::server fornecida pelo módulo instalado:
class db_postgresql_admin{
include postgresql::server
}
Para verificar a sintaxe do manifesto, é uma boa prática executar o seguinte comando:
$ sudo /opt/puppetlabs/bin/puppet parser validate init.pp
Se nada for retornado, significa que a sintaxe está correta
Para mostrar como usar este módulo na pasta de exemplo, é necessário criar um novo arquivo de manifesto init.pp com o seguinte conteúdo:
include db_postgresql_admin
A localização do exemplo no módulo deve ser testada e aplicada ao catálogo mestre:
$ sudo /opt/puppetlabs/bin/puppet apply --modulepath=/etc/puppetlabs/code/environments/production/modules --noop init.pp
Finalmente, é necessário definir qual módulo cada nó tem acesso no arquivo “/etc/puppetlabs/code/environments/production/manifests/site.pp” :
node ’agent.severalnines.com’,’agent2.severalnines.com’{
include db_postgresql_admin
}
Ou uma configuração padrão para todos os nós:
node default {
include db_postgresql_admin
}
Geralmente a cada 30min os nós verificam o catálogo mestre, no entanto esta consulta pode ser forçada no lado do nó pelo seguinte comando:
$ /opt/puppetlabs/bin/puppet agent -t
Ou se o objetivo for simular as diferenças entre a configuração mestre e as configurações atuais do nó, pode-se usar o parâmetro nopp (sem operação):
$ /opt/puppetlabs/bin/puppet agent -t --noop
Passo Dois
Atualize a instância do PostgreSQL para escutar todas as interfaces. A instalação anterior define uma configuração de instância em um modo muito restritivo:somente permite conexões em localhost conforme pode ser confirmado pelos hosts associados à porta 5432 (definida para PostgreSQL):
$ sudo netstat -ntlp|grep 5432
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 3237/postgres
tcp6 0 0 ::1:5432 :::* LISTEN 3237/postgres
Para permitir ouvir toda a interface, é necessário ter o seguinte conteúdo no arquivo /etc/puppetlabs/code/environments/production/modules/db_postgresql_admin/manifests/init.pp
class db_postgresql_admin{
class{‘postgresql:server’:
listen_addresses=>’*’ #listening all interfaces
}
}
No exemplo acima é declarada a classe postgresql::server e configurando o parâmetro listen_addresses para “*” que significa todas as interfaces.
Agora a porta 5432 está associada a todas as interfaces, pode ser confirmada com o seguinte endereço IP/porta:“0.0.0.0:5432”
$ sudo netstat -ntlp|grep 5432
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN 1232/postgres
tcp6 0 0 :::5432 :::* LISTEN 1232/postgres
Para colocar de volta a configuração inicial:permitir apenas conexões de banco de dados de localhost o parâmetro listen_addresses deve ser definido como “localhost” ou especificando uma lista de hosts, se desejado:
listen_addresses = 'agent2.severalnines.com,agent3.severalnines.com,localhost'
Para recuperar a nova configuração do host mestre, basta solicitá-la no nó:
$ /opt/puppetlabs/bin/puppet agent -t
Etapa Três
Crie um banco de dados PostgreSQL. A instância do PostgreSQL pode ser criada com um novo banco de dados bem como um novo usuário (com senha) para utilizar este banco de dados e uma regra no arquivo pg_hab.conf para permitir a conexão do banco de dados para este novo usuário:
class db_postgresql_admin{
class{‘postgresql:server’:
listen_addresses=>’*’ #listening all interfaces
}
postgresql::server::db{‘nines_blog_db’:
user => ‘severalnines’, password=> postgresql_password(‘severalnines’,’passwd12’)
}
postgresql::server::pg_hba_rule{‘Authentication for severalnines’:
Description =>’Open access to severalnines’,
type => ‘local’,
database => ‘nines_blog_db’,
user => ‘severalnines’,
address => ‘127.0.0.1/32’
auth_method => ‘md5’
}
}
Este último recurso tem o nome de “Autenticação para vários noves” e o arquivo pg_hba.conf terá mais uma regra adicional:
# Rule Name: Authentication for severalnines
# Description: Open access for severalnines
# Order: 150
local nines_blog_db severalnines 127.0.0.1/32 md5
Para recuperar a nova configuração do host mestre, basta solicitá-la no nó:
$ /opt/puppetlabs/bin/puppet agent -t
Passo Quatro
Crie um usuário somente leitura. Para criar um novo usuário, com privilégios somente leitura, os seguintes recursos precisam ser adicionados ao manifesto anterior:
postgresql::server::role{‘Creation of a new role nines_reader’:
createdb => false,
createrole => false,
superuser => false, password_hash=> postgresql_password(‘nines_reader’,’passwd13’)
}
postgresql::server::pg_hba_rule{‘Authentication for nines_reader’:
description =>’Open access to nines_reader’,
type => ‘host’,
database => ‘nines_blog_db’,
user => ‘nines_reader’,
address => ‘192.168.1.10/32’,
auth_method => ‘md5’
}
Para recuperar a nova configuração do host mestre, basta solicitá-la no nó:
$ /opt/puppetlabs/bin/puppet agent -t
Conclusão
Neste blog, mostramos os passos básicos para implantar e começar a configurar seu banco de dados PostgreSQL de forma automática e personalizada em vários nós (que podem até ser máquinas virtuais).
Esses tipos de automação podem ajudá-lo a se tornar mais eficaz do que fazê-lo manualmente e a configuração do PostgreSQL pode ser realizada facilmente usando várias das classes disponíveis no repositório puppetforge