Migre o seu Aplicativo Linux para a Nuvem Amazon, Parte 4: Superando desafios administrativos

Evite dores de cabeça conforme você cresce

Até agora, você moveu o seu aplicativo para a nuvem e pode ativar e desativar recursos automaticamente em resposta à demanda. Neste artigo — o quarto de uma série sobre a migração de um aplicativo Linux para a nuvem Amazon, aprenda a manter esse ambiente em transformação sob controle para que suporte o seu aplicativo e os seus negócios.

Sean A. Walberg, Senior Network Engineer

Author photoSean 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.



06/Dez/2010

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 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ê (consulte Recursos ).

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 tem 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:

  1. Fazer o download de uma cópia atualizada dos manifestos e arquivos associados a partir do servidor.
  2. 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 {
                include ntpclient }

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.

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
                => installed } service { ntpd: ensure => true,
                enable => true, subscribe => [ Package [ntp],
                File["ntp.conf"] ], } file { "ntp.conf": mode => 644,
                owner => root, group => root, path =>
                "/etc/ntp.conf", source =>
                "/var/puppetstage/files/etc/ntp.conf", before =>
                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 | `--
                etc | `-- ntp.conf `-- manifests |-- classes | `-- ntp.conf `--
                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/
                /var/puppetstage/ --delete /usr/bin/puppet
                /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.


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"
                set :repository, "https://svn.smallpayroll.ca/svn/app/trunk/"
                set :user, 'payroll' set :home, '/home/payroll' set :deploy_to,
                "#{home}" set :rails_env, "production" role :db,
                "174.129.174.213", :primary => true role :web,
                "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
                of your deploy.rb require 'AWS' # Change your role :web
                definition to this role(:web) { my_instances } # This goes at
                the bottom of the recipe def my_instances @ec2 =
                AWS::EC2::Base.new( :access_key_id =>
                ENV['AWS_ACCESS_KEY_ID'], :secret_access_key =>
                ENV['AWS_SECRET_ACCESS_KEY']) servers =
                @ec2.describe_instances.reservationSet.item.collect do
                |itemgroup| itemgroup.instancesSet.item.collect {|item|
                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 (consulte Recursos ). 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
                /var/lib/cacti/cli/add_device.php --list-host-templates Valid
                Host Templates: (id, name) 0 None 1 Generic SNMP-enabled Host 3
                ucd/net SNMP Host 4 Karlnet Wireless Bridge 5 Cisco Router 6
                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
                /var/lib/cacti/cli/add_graphs.php --list-graph-templates
                --host-template-id=3 Known Graph Templates:(id, name) 4 ucd/net
                - 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 omitira 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
                /var/lib/cacti/cli/add_device.php --description="EC2-1.2.3.4" \
                --ip=1.2.3.4 --template=3 Adding EC2-1.2.3.4 (1.2.3.4) as
                "ucd/net SNMP Host" using SNMP v1 with community "public"
                Success - new device-id: (5) php -q
                /var/lib/cacti/cli/add_graphs.php --host-id=5 --graph-type=cg \
                --graph-template-id=4 Graph Added - graph-id: (6) -
                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
                device and parse the output to only return the id DEVICEID=`php
                -q /var/lib/cacti/cli/add_device.php --description="EC2-$IP" \
                --ip=$IP --template=3 | grep device-id | sed 's/[^0-9]//g'` #
                CPU graph php -q /var/lib/cacti/cli/add_graphs.php
                --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
                http://169.254.169.254/2007-01-19/meta-data/public-ipv4` ssh
                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

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.
  • Avalie os produtos IBM da maneira que for melhor para você: faça download da versão de teste de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na SOA Sandbox aprendendo a implementar Arquitetura Orientada a Serviços de modo eficiente.

Discutir

  • Participe da comunidade do My developerWorks. Entre em contato com outros usuários do developerWorks e explore os blogs, fóruns, grupos e wikis voltados para desenvolvedores.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre, Linux, Cloud computing
ArticleID=595584
ArticleTitle=Migre o seu Aplicativo Linux para a Nuvem Amazon, Parte 4: Superando desafios administrativos
publish-date=12062010