Você migrou o aplicativo SmallPayroll.ca para a nuvem
Amazon na Parte 1 desta série e deixou-o mais robusto na Parte 2. O aplicativo pode até mesmo incluir e remover
servidores sozinho, dependendo da carga, como você viu na Parte 3. Agora é provável que, a qualquer momento, os
números e os endereços de IP dos servidores ativos não possam ser
previstos, o que dificulta a conexão a eles. Como resultado
disso, o ambiente de nuvem é diferente de um centro de dados
tradicional.
A dinamicidade da nuvem também dificulta a implementação do
aplicativo. A lista de servidores será diferente entre as
implementações; portanto, como você atualiza o aplicativo? Por
falar nisso, como você monitora os seus servidores em relação a
falhas?
Não se trata de um centro de dados normal
Em um centro de dados “normal”, é possível dar os nomes que você
quiser aos computadores, dar a eles endereços de IP que são
convenientes para você e, se você quiser, ir e
olhar os servidores para ter certeza de que ainda estão lá.
Talvez você mantenha uma planilha para controlar os servidores,
talvez tenha software, talvez só guarde as informações na cabeça
ou em um arquivo de texto. Você conta com o gerenciamento de
configuração para se certificar de que a sua configuração seja
consistente?
O ambiente de nuvem é muito diferente de um centro de dados
tradicional, porque você abre mão do controle de várias funções.
Não é possível prever os endereços de IP e nem mesmo se
certificar de que dois servidores estarão na mesma sub-rede.
Se
você passa para a escala automática de recursos, todo o trabalho
que você teve com as configurações manuais pode ser perdido
quando um novo nó é ativado. Os scripts que dependem de saber
que você tem 20 servidores da Web com um nome previsível não
funcionarão na nuvem.
Felizmente, um pouco de disciplina pode contornar esses problemas
e até mesmo melhorar o tempo de atividade no centro de dados
físico!
Endereços de IP e nomenclatura
As pessoas tendem a passar bastante tempo se preocupando com os
nomes a ser dados aos servidores e com a forma de criar um
esquema sensato de endereços de IP.
As instâncias do Amazon
Elastic Compute Cloud (Amazon EC2) atribuem um endereço IP
razoavelmente aleatório e um nome baseado nesse endereço. Você
poderia renomear o servidor, mas isso geralmente requer
conhecimento sobre o restante do ambiente. Por exemplo: para dar
a um servidor o nome webprd42, é necessário saber que o
último servidor ativado foi webprd41.
A melhor solução é não depender de nomes ou endereços de IP e
construir os seus softwares de forma que esses nomes não tenham
importância.
Gerenciamento de configuração
Em um ambiente físico, geralmente é possível fazer mudanças
manuais na configuração dos servidores. Quando os servidores são
ativados automaticamente, as mudanças manuais não são aplicadas.
É possível reempacotar a Amazon Machine Image (AMI) depois de
cada mudança, mas isso não resolve o problema do envio (push) de
atualizações para os outros servidores que já estão executando.
Felizmente, pacotes de software excelentes, como o Puppet e o
Cfengine, podem automatizar essas mudanças para você – ao final do artigo na seção Recursos você pode aprender mais sobre.
A implementação de mudanças no aplicativo é outro aspecto do
gerenciamento de configuração que merece uma análise em
separado. Ferramentas genéricas de gerenciamento de configuração
podem realizar a tarefa, mas usá-las para reproduzir as etapas
específicas ao implementar um aplicativo e gerenciar migrações e
retrocessos de configuração é difícil. A comunidade de Rails fez
outras ferramentas, como o Capistrano, para realizar a tarefa de
implementação de aplicativos (consulte
Recursos).
É conveniente considerar o gerenciamento de configuração como
dois problemas separados. O primeiro é gerenciar o servidor – da instalação de pacotes de software até a configuração
de vários daemons. O segundo é implementar novas versões de
software de forma controlada.
Monitoramento do sistema
É importante saber o que os servidores estão fazendo. CPU,
recursos de disco, memória e rede são componentes vitais que
devem ser monitorados.
Os daemons que executam no sistema,
incluindo o próprio aplicativo, podem ter outras métricas a ser
observadas. Por exemplo: o acompanhamento do tempo de resposta
do aplicativo e o número de conexões ao servidor da Web e ao
servidor de aplicativos podem indicar problemas antes que eles
aconteçam.
Existem várias ferramentas para monitorar servidores e
representar os resultados em gráficos. O desafio é monitorar
novos servidores à medida que eles ficam on-line e parar o
monitoramento conforme eles ficam off-line.
Padrões da forma que são aplicados à arquitetura de nuvem
Surgem três padrões ao analisar a forma de gerenciar um ambiente
dinâmico como o Amazon EC2:
- Pesquisa do cliente. O servidor consulta um
servidor central em relação aos recursos. Não é necessário
saber os endereços de todos os servidores ao usar esse
padrão, mas os servidores operam de acordo com a sua própria
programação; portanto, não é possível controlar a
sincronização da pesquisa do cliente. - Push do servidor. Esse padrão primeiro
consulta a interface de programação de aplicativos (API) do
provedor de nuvem e, em seguida, um servidor central contata
cada servidor para executar o trabalho. Esse padrão é mais
lento e requer que as ferramentas de gerenciamento
“entendam” a característica dinâmica do ambiente, mas tem o
benefício de permitir a sincronização das atualizações. - Registro do cliente. Conforme cada servidor
fica on-line, ele se registra em um servidor central. Antes
de o servidor ser finalizado, ele cancela o registro. Esse
método é mais complexo, mas permite usar ferramentas que não
têm conhecimento da nuvem em um ambiente de nuvem.
Pesquisa do cliente para o gerenciamento de configuração
Esse padrão é fácil de implementar: o cliente simplesmente
pesquisa um servidor bem conhecido para obter instruções em uma
programação predeterminada. Se o servidor não tem nada para o
cliente fazer, ele passa essa informação ao cliente.
A
desvantagem é que as instruções só podem ser emitidas se o
cliente pesquisa o servidor; se a mudança é urgente, é
necessário aguardar a próxima pesquisa.
O gerenciamento de configuração do servidor é um uso excelente da
pesquisa. O pacote Puppet da Reductive Labs é uma ferramenta de
gerenciamento de configuração bastante difundida.
Um processo,
chamado Puppetmaster, executa em um servidor central.
Os clientes executam o daemon Puppet, que pesquisa o
Puppetmaster para obter o manifesto de configuração adequado.
Esses manifestos de configuração especificam o estado final
desejado de um determinado componente, como “certifique-se de
que o daemon de NTP esteja instalado e em execução”. O Puppet lê
esses manifestos e corrige eventuais problemas.
A sua distribuição pode vir com o Puppet ou você pode instalá-lo
rapidamente com gem install puppet
facter. Entretanto, o Puppet implementa um sistema de
segurança que complica a situação. É necessário que os clientes
tenham uma chave assinada para “conversar” com o Puppetmaster.
É
possível instruir o Puppetmaster a assinar chaves
automaticamente para os clientes que se conectam, mas isso
permitiria que qualquer pessoa fizesse o download dos seus
arquivos de configuração. Ignorar o Puppetmaster, distribuir os
manifestos manualmente e executar as ferramentas Puppet
localmente é uma solução alternativa.
A sequência de eventos para fazer com que o cliente execute os
manifestos do Puppet é a seguinte:
- Fazer o download de uma cópia atualizada dos manifestos e
arquivos associados a partir do servidor. - Executar o Puppet com relação ao manifesto.
Para a etapa 1, a ferramenta preferencial é o rsync, que só faz download de arquivos alterados.
Para a etapa 2, o comando puppet
(parte da instalação do Puppet) executa o manifesto. Observe que
há duas advertências em relação a essa abordagem:
- O servidor deve aceitar a chave pública de shell seguro
(SSH) do cliente. Essa chave pode ser distribuída na AMI. - Todos os arquivos de configuração que você especifica no
manifesto devem ser copiados com o manifesto. O servidor de
arquivos integrado ao Puppet também requer certificados;
portanto, não é possível usar esse método de transferência
de arquivos.
O manifesto de amostra garante que o cliente tenha a configuração
correta de Network Time Protocol. Isso envolve garantir que o
software esteja instalado, o arquivo de configuração seja
modificado e o daemon esteja executando. A Listagem 1 mostra o
manifesto de nível superior.
Listagem 1. O manifesto de nível superior
import "classes/*" node default {<br /> include ntpclient } A Listagem 1 primeiro importa todos os arquivos no diretório das
classes; cada arquivo contém informações sobre um único
componente. Em seguida, todos os nós incluem a classe ntpclient, que é definida na Listagem
2.
Listagem 2. A classe ntpclient
class ntpclient { package { ntp: ensure<br /> => installed } service { ntpd: ensure => true,<br /> enable => true, subscribe => [ Package [ntp],<br /> File["ntp.conf"] ], } file { "ntp.conf": mode => 644,<br /> owner => root, group => root, path =><br /> "/etc/ntp.conf", source =><br /> "/var/puppetstage/files/etc/ntp.conf", before =><br /> Service["ntpd"] } } Uma análise detalhada da linguagem Puppet está fora do escopo
deste artigo, mas de modo geral, a Listagem 2 define uma classe
chamada ntpclient que é composta por
um pacote chamado ntp, um serviço
chamado ntpd e um arquivo em /etc
chamado ntp.conf.
Se o pacote ntp não está instalado, o Puppet usa a ferramenta
adequada, como o yum ou o apt-get para instalá-lo. Se o serviço
não está executando e está nos scripts de inicialização, é
corrigido. Se o arquivo ntp.conf é diferente da cópia em
/var/puppetstage/files/etc, ele é atualizado. As linhas before e subscribe garantem que o daemon seja reiniciado se a
configuração mudar.
O servidor armazena os manifestos e arquivos em/var/puppetdist, e
os clientes copiam essa árvore para /var/puppetstage. A
estrutura de tópicos da árvore de diretórios é mostrada na
Listagem 3.
Listagem 3. Conteúdo de /var/puppetdist
/var/puppetdist/ |-- files | `--<br /> etc | `-- ntp.conf `-- manifests |-- classes | `-- ntp.conf `--<br /> site.pp Finalmente, a Listagem 4 sincroniza os arquivos e executa o
manifesto no cliente.
Listagem 4. Código do cliente para sincronizar e executar o manifesto
#!/bin/bash /usr/bin/rsync -avz puppetserver:/var/puppetdist/<br /> /var/puppetstage/ --delete /usr/bin/puppet<br /> /var/puppetstage/manifests/site.pp Esse código, quando executado a partir de cron periodicamente, pega as mudanças nos manifestos
e as aplica ao servidor de nuvem. Se a configuração do servidor
sofre alguma mudança, o Puppet toma providências para que o
servidor volte à conformidade.
Iniciação em Puppet
Um dos benefícios do Puppet é a possibilidade de começar
devagar e colocar mais coisas sob o controle do Puppet à
medida que você aprende a linguagem. Por exemplo: é possível
começar com o NTP, como mostra este artigo, e aumentar para
suportar outros serviços. Cada vez que você melhora o
manifesto do Puppet, você deixa os sistemas muito mais
confiáveis e poupa muito trabalho no futuro.
Obtendo atualizações de aplicativos
As atualizações de configuração nos servidores raramente requerem
sincronização entre os servidores. Se um pacote precisa ser
atualizado, geralmente uma janela de meia hora é suficiente.
Entretanto, no caso da atualização de aplicativos, é conveniente
introduzir as mudanças de uma vez e ter controle sobre a
sincronização. O Capistrano é uma ferramenta bastante utilizada
para fazer isso. Você escreve um script que usa a linguagem
específica para o domínio do Capistrano e executa várias
tarefas.
A Listagem 5 mostra um script mínimo do Capistrano para
enviar um aplicativo a um conjunto conhecido de servidores.
Listagem 5. Um script simples do Capistrano
set :application, "payroll"<br /> set :repository, "https://svn.smallpayroll.ca/svn/app/trunk/"<br /> set :user, 'payroll' set :home, '/home/payroll' set :deploy_to,<br /> "#{home}" set :rails_env, "production" role :db,<br /> "174.129.174.213", :primary => true role :web,<br /> "174.129.174.213", "184.73.3.169" A maioria das linhas da Listagem 5 define variáveis que alteram o
comportamento padrão do Capistrano, que é usar o SSH para
acessar todos os servidores e usar uma ferramenta de
gerenciamento do código de origem para fazer o registro de saída
de uma cópia do aplicativo.
As duas últimas linhas definem os
servidores em uso ? especificamente, os servidores de
banco de dados e os servidores da Web. Essas funções são
conhecidas pelo Capistrano (e podem ser estendidas para os seus
próprios propósitos).
O problema da Listagem 5 é que os servidores devem ser
predefinidos. Entretanto, é possível fazer com que o Capistrano
determine a lista de servidores no tempo de execução usando as
APIs do Amazon Web Services (AWS). Primeiro, execute:
gem install amazon-ec2 Para instalar uma biblioteca que implementa a API. Em seguida,
modifique a receita do Capistrano (deploy.rb) como mostra a
Listagem 6.
Listagem 6. Modificando o Capistrano para carregar dinamicamente a lista de servidores no tempo de execução
# Put this at the beginning<br /> of your deploy.rb require 'AWS' # Change your role :web<br /> definition to this role(:web) { my_instances } # This goes at<br /> the bottom of the recipe def my_instances @ec2 =<br /> AWS::EC2::Base.new( :access_key_id =><br /> ENV['AWS_ACCESS_KEY_ID'], :secret_access_key =><br /> ENV['AWS_SECRET_ACCESS_KEY']) servers =<br /> @ec2.describe_instances.reservationSet.item.collect do<br /> |itemgroup| itemgroup.instancesSet.item.collect {|item|<br /> item.ipAddress} end servers.flatten end A Listagem 6 altera a função da Web de uma definição estática
para uma lista dinâmica de servidores retornados a partir da
função my_instances. A função usa a
chamada da API do Amazon EC2 DescribeInstances para retornar uma lista de
servidores.
A API retorna os dados em um formato que agrupa
instâncias que foram ativadas juntas sob o mesmo identificador
de reserva. O loop externo collect se
repete nesses grupos de reserva, e o loop interno collect se repete nos servidores
contidos em cada grupo de contenção. O resultado é um array de
arrays, que é “achatado” para se tornar um único array
dimensional de endereços de IP de servidores e passado de volta
ao responsável pela chamada.
Felizmente, o Capistrano forneceu uma forma de operar em uma
lista dinâmica de servidores. Se ele não fornecesse esses
ganchos, seria necessário adotar outra abordagem.
Registrando em um servidor de gerenciamento
No caso de aplicativos que não permitem facilmente a utilização
de uma lista dinâmica de servidores, é possível contornar o
problema fazendo com que o servidor da nuvem se registre em
outros aplicativos. Esse processo geralmente ocorre em uma das
duas formas a seguir:
- O servidor da nuvem se conecta a outro servidor e executa um
script que atualiza diretamente o aplicativo de
gerenciamento. - O servidor da nuvem coloca um arquivo com alguns metadados
em um local comum, como o Amazon Simple Storage Service
(Amazon S3), onde os outros scripts procuram para
reconstruir os seus arquivos de configuração.
Atualizações diretas
O Cacti é uma ferramenta de gerenciamento de desempenho bastante
conhecida que pode representar graficamente várias métricas por
meio do Protocolo Simples de Gerenciamento de Rede (SNMP) ou de
scripts e combina esses gráficos em consoles ou metagráficos.
A limitação do
Cacti é que você precisa configurar o servidor para o
gerenciamento dentro da interface da Web do Cacti ou por meio de
scripts de linha de comando. Neste exemplo, o servidor da nuvem
se conecta ao servidor do Cacti e se configura.
O Cacti se baseia em um sistema de modelos que faz mudanças em
massa em gráficos com muito mais facilidade. Entretanto, todas
as ferramentas de linha de comando operam no identificador de
modelo, portanto, primeiro é necessário determinar os
identificadores que devem ser usados.
A Listagem 7 mostra como
localizar o modelo do host, que é preenchido previamente para
você com alguns elementos de dados.
Listagem 7. Listando os modelos de host
$ php -q<br /> /var/lib/cacti/cli/add_device.php --list-host-templates Valid<br /> Host Templates: (id, name) 0 None 1 Generic SNMP-enabled Host 3<br /> ucd/net SNMP Host 4 Karlnet Wireless Bridge 5 Cisco Router 6<br /> Netware 4/5 Server 7 Windows 2000/XP Host 8 Local Linux Machine O modelo número 3 é para um host que está executando o daemom
Net-SNMP, disponível com a
maioria das distribuições do Linux. O uso desse daemon
específico (em vez de uma versão mais genérica) permite
monitorar facilmente alguns contadores específicos do Linux.
Sabendo que você está usando o modelo de host 3, a lista de
gráficos disponíveis é mostrada na Listagem 8.
Listagem 8. Listando os modelos de gráfico
$ php -q<br /> /var/lib/cacti/cli/add_graphs.php --list-graph-templates<br /> --host-template-id=3 Known Graph Templates:(id, name) 4 ucd/net<br /> - CPU Usage 11 ucd/net - Load Average 13 ucd/net - Memory Usage Os três gráficos da Listagem 8 são o que você obtém com a
distribuição padrão do Cacti. É possível incluir muitos outros. Pode-se omitir a opção –host-template-id para vê-los ou importar os
gráficos a partir de fontes na Internet.
A Listagem 9 mostra como incluir um novo dispositivo e, em
seguida, um gráfico de CPU.
Listagem 9. Incluindo um novo dispositivo com um gráfico
$ php -q<br /> /var/lib/cacti/cli/add_device.php --description="EC2-1.2.3.4" \<br /> --ip=1.2.3.4 --template=3 Adding EC2-1.2.3.4 (1.2.3.4) as<br /> "ucd/net SNMP Host" using SNMP v1 with community "public"<br /> Success - new device-id: (5) php -q<br /> /var/lib/cacti/cli/add_graphs.php --host-id=5 --graph-type=cg \<br /> --graph-template-id=4 Graph Added - graph-id: (6) -<br /> data-source-ids: (11, 12, 13) A Listagem 9 primeiro inclui um host com o endereço IP 1.2.3.4. O
ID do dispositivo é 5 que, em
seguida, é usado para incluir um gráfico referente ao uso de CPU
(tipo de gráfico de cg e modelo 4).
Os resultados são o ID do gráfico e os IDs das várias fontes de
dados que agora estão sendo monitoradas.
Agora é razoavelmente fácil fazer o script do procedimento na
Listagem 9. A Listagem 10 mostra um script desse tipo.
Listagem 10. add_to_cacti.sh
#!/bin/bash IP=$1 # Add a new<br /> device and parse the output to only return the id DEVICEID=`php<br /> -q /var/lib/cacti/cli/add_device.php --description="EC2-$IP" \<br /> --ip=$IP --template=3 | grep device-id | sed 's/[^0-9]//g'` #<br /> CPU graph php -q /var/lib/cacti/cli/add_graphs.php<br /> --host-id=$DEVICEID --graph-type=cg \ --graph-template-id=4 O primeiro parâmetro para o script é salvo em uma variável
chamada $IP. O script add_device.php
é executado com esse endereço IP, com a saída filtrada para
mostrar somente a linha que contém o ID, usando o comando grep. A saída disso é alimentada em um
script sed que somente imprime
números. Esse valor é salvo em uma variável chamada $DEVICEID.
Com o ID do dispositivo armazenado, incluir um gráfico é tão
simples quanto chamar o script add_graphs.php. Observe que o
gráfico da CPU é o caso mais simples e que alguns tipos de
gráficos requerem mais parâmetros.
Com o script add_to_cacti.sh no servidor do Cacti, basta que o
servidor da nuvem o execute. A Listagem 11 mostra como chamar o
script.
Listagem 11. Chamando o script do Cacti a partir do servidor de nuvem
#!/bin/bash MYIP=`/usr/bin/curl -s<br /> http://169.254.169.254/2007-01-19/meta-data/public-ipv4` ssh<br /> cacti@cacti.example.com "/usr/local/bin/add_to_cacti.sh $MYIP" A Listagem 11 primeiro chama o servidor de metadados do Amazon
EC2 para retornar o endereço IP público e, em seguida, executa o
comando remotamente no servidor do Cacti.
De volta ao Puppet
Se você quisesse usar a autoridade de certificação e o
servidor do Puppet em vez do hack de rsync detalhado anteriormente, esse padrão seria
útil.
Conclusão
Esta série seguiu a migração de um aplicativo de um servidor
único para a nuvem do AWS. As melhorias foram feitas de forma
incremental para aproveitar as ofertas da Amazon EC2, desde a
ativação de novos servidores até equilibradores de carga. Este
artigo final analisou o gerenciamento de um ambiente dinâmico de
nuvem e ofereceu alguns padrões para você usar.
Considerando o baixo custo de entrada do uso de recursos de
nuvem, você deve dar uma olhada e fazer uma migração para
praticar. Mesmo se você decidir não executar o aplicativo na
produção usando a nuvem, você aprenderá muito sobre o que pode
ser feito na nuvem e pode até melhorar as suas qualificações de
gerenciamento de sistemas.
Recursos
Aprender
-
Preparação para o exame LPI 301, tópico 306: Planejamento
de capacidade (developerWorks, abril de 2008) explica
detalhadamente como monitorar sistemas e medir resultados. -
The S3 Cookbook
de Scott Patten é um PDF da Leanpub que explica como usar o Amazon S3 com Ruby. O
livro repassa 60 problemas e explica como resolver cada um
deles, com código. - Participe de briefing ao vivo e gratuito developerWorks para
atualizar-se rapidamente em relação aos produtos e ferramentas
IBM e às tendências do segmento de mercado de TI.
Obter produtos e tecnologias
- Agora
que você obteve múltiplos AMIs no Amazon S3, poderá desejar
remover alguns antigos. Amazon S3
File Manager é um gerenciador de arquivos que rivaliza
os recursos de muito aplicativos independentes ou plug-ins do
navegador. Se excluir um AMI, não se esqueça de ec2-deregister . -
Capistrano é um pacote de implementação popular que age
de maneira semelhante ao Rake. -
O Cfengine é a ferramenta
de gerenciamento de configuração mais popular para UNIX®. É
leve e pode operar em um grande número de máquinas. -
O Cacti é uma ferramenta de
gráfico de rede construída com base na RRDTool. Você pode
representar em gráficos praticamente qualquer coisa. Se estiver
no seu centro de dados, é bem provável que alguém já tenha
escrito um plug-in para representá-lo em um gráfico. -
O Puppet é uma
ferramenta de gerenciamento de configuração escrita em Ruby e
construída para superar algumas limitações do Cfengine. Se você
está procurando um bom jeito de começar,
Pulling Strings with Puppet
de James Turnbull (Apress, 2008) é um livro que agradou o
autor deste artigo.
***
artigo publicado originalmente no developerWorks Brasil, por Sean Walberg
Sean Walberg trabalha com Linux e UNIX desde 1994 em ambientes
acadêmicos, corporativos e de provedores de serviço de Internet.
Escreveu muito sobre administração de sistemas nos últimos anos. É
possível entrar em contato com ele pelo e-mail sean@ertw.com.







