Migre seu aplicativo Linux à nuvem Amazon, Parte 1: Migração inicial

Como migrar seu aplicativo para a nuvem

A computação em nuvem e Infrastructure as a Service (IaaS) são bem documentadas, mas o que não é frequentemente discutido é como fazer com que um aplicativo seja executado em um ambiente de nuvem. Nesta série, descubra como mover um aplicativo para a nuvem e tirar vantagem dos recursos que esta configuração tem a oferecer. Na Parte 1, veja uma migração direta de um servidor físico para um servidor em nuvem.

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.



28/Mai/2014

Sobre esta série

Esta série de artigos segue a migração de um aplicativo de web a partir de um único servidor físico para o Amazon Elastic Compute Cloud (Amazon EC2). Durante o trajeto, você aprenderá como adaptar seu aplicativo ao ambiente de nuvem e como tirar vantagem dos recursos que a nuvem tem a oferecer.

Infrastructure as a Service (IaaS) é um excelente conceito: Você usa recursos de computações; você paga por eles. Você deseja mais poder de computação; você paga mais. A desvantagem deste modelo é que você trabalha com computadores que nunca verá ou conhecerá muito bem. Uma vez que isso tenha sido superado, no entanto, há muito a ganhar usando IaaS.

Como o modelo IaaS é tão diferente do modelo tradicional de aquisição de servidores, a forma de gerenciamento de seus computadores virtuais é diferente. A forma como você executa seu aplicativo na nuvem também é diferente. Coisas que eram consideradas constantes, como latência insignificante entre servidores, não são mais certas.

Trabalhando com Amazon EC2

O Amazon EC2 permite que qualquer pessoa com um cartão de crédito pague por servidores por hora, ligando-os ou desligando-os por meio de um application programming interface (API). Você tem uma variedade de tipos de servidores entre os quais escolher — dependendo se sua preocupação principal for memória, disco ou poder de CPU — juntamente com um pacote de complementos, de discos persistentes a balanceadores de carga. Você paga somente pelo que usar.

Além da oferta do Amazon EC2 existem outras que lhe dão, entre outras coisas, processamento de pagamentos, bancos de dados e enfileiramento de mensagens. Nesta série de artigos, você usará o Amazon Simple Storage Service (Amazon S3), que dá acesso a espaço em disco com pagamento pelo uso.


O exemplo de aplicativo

O aplicativo da web que esta série usa como exemplo é um serviço de folha de pagamento chamado SmallPayroll.ca, escrito com a estrutura Ruby on Rails e um backend PostgreSQL. É típico de muitos aplicativos da web: Tem uma camada de banco de dados, uma camada de aplicativos e um conjunto de arquivos estáticos, como arquivos de cascading style sheet (CSS) e JavaScript. Os usuários navegam por vários formulários para inserir e manipular dados além de gerar relatórios.

Os vários componentes em uso são:

  • Nginx. O servidor web front-end para arquivos estáticos e balanceador para camada intermediária.
  • Mongrel. O servidor de aplicativos propriamente dito.
  • Ruby. A linguagem em que o aplicativo é escrito.
  • Gems. Plug-ins e bibliotecas de terceiros para tudo, de criptografia de banco de dados a monitoração em nível de aplicativo.
  • PostgreSQL. O mecanismo de banco de dados Structured Query Language.

O uso do site excedeu a capacidade do único servidor que o armazena no momento. Portanto, é preciso uma migração para um novo ambiente, e esta é uma oportunidade excelente para mover-se para a nuvem.

Melhorias desejadas

Mas simplesmente mover de um servidor para um pequeno número de servidores com base na nuvem não tiraria vantagem do que pode ser feito na nuvem, nem resultaria em uma leitura emocionante. Portanto, durante a movimentação, você fará algumas melhorias, algumas das quais só são possíveis em um ambiente de nuvem:

  • Maior confiabilidade. Como você pode escolher o tamanho do servidor a executar na nuvem, é possível executar vários servidores menores para obter redundância.
  • Capacidade para escalamento para baixo e para cima. Servidores são adicionados de forma incremental ao conjunto à medida que o serviço cresce. No entanto, o número de servidores também pode ser aumentado para acomodar picos de curto prazo em tráfego ou diminuído durante períodos de baixo movimento.
  • Armazenamento em nuvem. Backups dos dados do aplicativo serão feitos no Amazon S3, eliminando a necessidade de armazenamento em fita.
  • Automação. Tudo no ambiente Amazon — dos servidores ao armazenamento e aos balanceadores de carga — pode ser automatizado. menos tempo gerenciando um aplicativo significa mais tempo para outras coisas mais produtivas.

Você fará estas melhorias de forma incremental durante esta série de artigos.


Estratégias de teste e migração

Ao implementar um aplicativo pela primeira vez, geralmente você pode se dar ao luxo de poder testá-lo e ajustá-lo sem o peso do tráfego de produção. Em contraste, ao migrar um aplicativo, você tem o desafio de usuários que colocam uma carga no site. Uma vez que o novo ambiente recebe tráfego de produção, os usuários esperarão que tudo funcione adequadamente.

Uma migração não significa necessariamente tempo de inatividade zero. É muito mais fácil se você puder colocar o serviço off-line por um período de tempo. É possível usar esta janela de inatividade para realizar sincronizações finais de dados e permitir que quaisquer mudanças na rede se estabilizem. A janela não deverá ser usada para realizar a implementação inicial para o novo ambiente — ou seja, o novo ambiente deverá estar em um estado operacional antes que a migração do aplicativo inicie. Com isto em mente, os pontos chave são a sincronização de dados entre os ambientes e as mudanças na rede.

Ao planejar sua estratégia de migração, ajuda iniciar com um detalhamento de seu ambiente atual. Responda às seguintes perguntas:

  • Que software uso em meus servidores para executar o aplicativo?
  • Que software uso em meus servidores para gerenciar e monitorar os recursos do servidor e do aplicativo?
  • Onde são mantidos todos os dados dos usuários? Em bancos de dados? Em arquivos?
  • São ativos estáticos, como imagens, CSS e arquivos JavaScript, armazenados em outro local?
  • De que pontos de contato com outros sistemas o aplicativo precisa?
  • Fiz backup de tudo recentemente?

Notificando os usuários

Em geral, notificar seus usuários é uma coisa boa, mesmo que não antecipe qualquer tempo de indisponibilidade. No caso do aplicativo SmallPayroll.ca, os usuários tendem a usar o site em um intervalo consistente, correspondente a seu ciclo de folha de pagamento de duas semanas. Portanto, um aviso com antecedência de duas semanas seria um período razoável. Sites como o Google AdWords, que é a interface administrativa da plataforma de publicidade do Google, avisam com cerca de uma semana de antecedência. Se seu site for mais um site de notícias, cuja retirada do ar por uma hora não prejudicaria tanto os usuários, você poderá escolher notificar no dia da indisponibilidade.

A forma da notificação também varia dependendo da natureza de seu site e como você se comunica atualmente com seus usuários. Para o SmallPayroll.ca, uma mensagem destacada quando o usuário efetuar login será suficiente. Por exemplo, uma mensagem parecida com "O sistema estará indisponível entre 0h01 e 1h, horário do Leste dos EUA, em 24 de junho de 2010. Todas as informações inseridas antes deste horário serão salvas. Para obter mais informações, clique aqui." Esta mensagem fornece três informações chave que os usuários precisam saber:

  • Quando a indisponibilidade ocorrerá, incluindo o fuso horário
  • Tranquilização de que seus dados estarão a salvo
  • Indicação do local de informações adicionais

Se possível, evite usar 0h ou 12h, incluindo o termo meia-noite. Eles tendem a confundir as pessoas, pois muitos não têm certeza se meia-noite do dia 17 de junho refere-se ao início do dia (0h01) ou tarde da noite (23h59). De forma similar, muitos não têm certeza se meio-dia significa 0h ou 12h. É muito mais fácil adicionar um minuto e tornar o horário não ambíguo.

Seus detalhes poderão ser diferentes, especialmente se antecipar funcionalidade parcial durante a indisponibilidade. Se você decidir que colocará a notícia somente durante a indisponibilidade (como para um site de notícias), as mesmas informações ainda serão úteis. Minha tela favorita de indisponibilidade de site era algo parecido com "O site está fora do ar para manutenção; retornará por volta de 15h. EST. Jogue Asteroids enquanto espera!"

Não negligencie também seus usuários internos. Se tiver representantes de contas, será preciso avisá-los caso seus clientes façam perguntas.

Considerações sobre DNS

O sistema de nome de domínio (DNS) encarrega-se de traduzir um nome como www.example.com em um endereço IP como 192.0.32.10. Seu computador conecta-se a endereços IP, portanto esta tradução é importante. Ao migrar de um ambiente para outro, é quase certo que você usará um endereço IP diferente (a exceção seria se permanecesse no mesmo prédio físico).

Computadores armazenam em cache o mapeamento nome-para-IP por um certo período de tempo, conhecido como time to live (TTL), para reduzir o tempo de resposta geral. Ao trocar de um ambiente para o outro — e, portanto, de um endereço IP para outro — pessoas que tenham a entrada de DNS armazenada em cache continuarão a tentar usar o ambiente antigo. A entrada de DNS para o aplicativo e seu TTL associado deverão ser gerenciados cuidadosamente.

TTLs são tipicamente entre uma hora e um dia. Como preparação para a migração, no entanto, é melhor que a TTL seja um tempo curto, como 5 minutos. Esta alteração deverá ser feita pelo menos um período de TTL antes do horário previsto para alteração do endereço, pois os computadores obtêm o TTL juntamente com o mapeamento nome-para-IP. Por exemplo, se o TTL para www.example.com estivesse definido para 86.400 segundos (um dia), seria preciso redefinir o TTL para 5 minutos pelo menos um dia antes da migração.

Desacoplando os ambientes novo e antigo

É essencial testar completamente seu novo ambiente antes da migração. Todos os testes deverão ocorrer em isolamento do ambiente de produção, preferivelmente com uma captura instantânea dos dados de produção para que possa exercitar melhor o novo ambiente.

Realizar um teste completo com uma captura instantânea dos dados de produção serve a dois propósitos. O primeiro é que é mais provável de encontrar erros se estiver usando dados do mundo real, pois são mais imprevisíveis do que dados de teste usados durante o desenvolvimento. Dados do mundo real poderão fazer referência a arquivos que você se esqueceu de copiar ou que requeiram certas configurações que foram esquecidas durante o detalhamento.

O segundo motivo para usar dados de produção é que você poderá praticar a migração ao mesmo tempo em que carrega dados. Você deverá ser capaz de provar a maioria dos aspectos de seu plano de migração, exceto pela troca real dos ambientes.

Mesmo que esteja trabalhando em seu novo ambiente como se fosse produção, somente um ambiente pode ser associado com o nome de host do aplicativo. A forma mais fácil de resolver este requisito é fazer uma substituição de DNS em seu arquivo hosts. No UNIX®, este arquivo reside em /etc/hosts; no Windows®, ele reside em C:\windows\system32\drivers\etc\hosts. Simplesmente siga o formato das linhas existentes e adicione uma entrada apontando o nome de host do aplicativo para seu futuro endereço IP. Não se esqueça de fazer o mesmo para quaisquer servidores de imagem ou qualquer outra coisa que vá mover. Provavelmente será necessário reiniciar seu navegador, mas, depois disso, poderá inserir sua URL de produção e ser levado a seu novo ambiente.


Uma base do Amazon EC2

O serviço Amazon EC2 permite pagar por uma máquina virtual (VM) por hora. O Amazon oferece diferentes tipos de máquinas e as classifica por perfis de CPU, memória e disco. O Amazon mede memória e disco em termos de gigabytes e CPU em termos de Amazon EC2 Compute Units (ECU), onde 1 ECU é, aproximadamente, um processador AMD Opteron ou Intel® Xeon® de 1.0 a 1.2GHz (era 2007). Por exemplo, a instância pequena padrão oferece 1,7 GB de memória, 160 GB de espaço em disco e 1 ECU de CPU. No momento em que este artigo foi escrito, a maior máquina era High-memory Quadruple Extra Large, com 68,4 GB de memória, 1,7 TB de espaço em disco e 26 ECUs divididas em oito núcleos virtuais. Os preços variam de 8,5 centavos de dólar por hora para o menor e 2,40 dólares por hora para o maior.

Uma instância do Amazon EC2 começa como uma Amazon Machine Image (AMI), que é um modelo que você usa para construir qualquer número de VMs. O Amazon publica algumas AMIs, e é possível fazer sua própria e compartilhá-la com outros. Algumas das AMIs criadas por usuários estão disponíveis sem custo; algumas incorrem em cobrança por hora, além da cobrança por hora do Amazon. Por exemplo, a IBM publica várias AMIs pagas que permitem o pagamento da licença por hora.

Quando quiser inicializar uma VM, você escolhe o tipo de máquina e uma AMI. A AMI é armazenada no Amazon S3 e copiada para a partição raiz de sua VM ao iniciar a instância. A partição raiz é sempre de 10 GB. O espaço de armazenamento associado com o tipo da máquina é chamado de armazenamento da instância ou armazenamento efêmero e é apresentado em sua VM como uma unidade separada. O armazenamento é chamado de efêmero porque, ao desligar sua instância, as informações são perdidas para sempre. É preciso fazer backup periodicamente de seus dados para proteger-se contra perda. Isto também significa que, se o host físico executando sua instância travar, sua instância é desligada e o disco efêmero é perdido.

A Amazon Machine Image

Todas as AMIs têm um identificador atribuído pelo Amazon, como ami-0bbd5462. O Amazon fornece algumas AMIs públicas e outras pessoas tornaram suas próprias AMIs públicas. É possível escolher começar com uma AMI pública e fazer suas próprias modificações ou pode começar do zero. A qualquer momento que fizer alterações no sistema de arquivos raiz de uma AMI, é possível salvá-la como uma nova AMI, o que é chamado de reempacotamento.

Nesta série, você começará com uma imagem do CentOS publicamente disponível, mas é possível escolher uma imagem diferente. É bom gastar algum tempo verificando qualquer imagem que usar para assegurar-se de que não existam contas extras e de que os pacotes estejam atualizados. Também é possível montar sua própria AMI do zero, mas isto está fora do escopo deste artigo.

A API do Amazon

Todas as funcionalidades necessárias para iniciar, parar e usar a nuvem do Amazon EC2 está disponível usando um serviço da web. O Amazon publica as especificações para os serviços da web e fornece um conjunto de ferramentas de linha de comandos. É preciso fazer o download dessas ferramentas antes de continuar (consulte Recursos). Também recomendo que veja o guia de início rápido (consulte Recursos) para configurar seu ambiente, o que economizará muito tempo de digitação.

Você autentica na API usando credenciais de segurança. Essas credenciais podem ser encontradas no link Account dentro do console de gerenciamento do Amazon Web Services (AWS) (consulte Recursos). Você precisará de seus arquivos do certificado X.509 e chaves de acesso. Mantenha-os seguros! Qualquer pessoa que os tenha poderá usar recursos do AWS e incorrer em cobranças em seu nome.

Antes de iniciar sua primeira instância

Antes de iniciar sua primeira instância, é preciso gerar as chaves de Secure Shell (SSH) para se autenticar na nova instância e configurar o firewall virtual para protegê-la. A Listagem 1 mostra o uso do comando ec2-add-keypair para gerar um par de chaves SSH.

Listagem 1. Gerando o par de chaves SSH
[sean@sergeant:~]$ ec2-add-keypair main
KEYPAIR main    40:88:59:b1:c5:bc:05:a1:5e:7c:61:23:5f:bc:dd:fe:75:f0:48:01
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAu8cTsq84bHLVhDG3n/fe9FGz0fs0j/FwZiDDovwfpxA/lijaedg6lA7KBzvn
...
-----END RSA PRIVATE KEY-----
[sean@sergeant:~]$ ec2-describe-keypairs
KEYPAIR main    40:88:59:b1:c5:bc:05:a1:5e:7c:61:23:5f:bc:dd:fe:75:f0:48:01

O primeiro comando diz ao Amazon para gerar um par de chaves com o nome main. A primeira linha do resultado dá o hash da chave. O restante da saída é uma chave primada PEM não criptografada. É preciso armazenar esta chave em algum lugar — por exemplo, ~/.ssh/main.pem. O Amazon retém a porção pública da chave, que ficará disponível para as VMs que você iniciar.

O segundo comando, ec2-describe-keypairs, pede ao Amazon a lista atual de pares de chaves. O resultado é o nome do par de chaves, seguido pelo hash.

Cada instância é protegida por um firewall virtual que, inicialmente, não permite nada. O Amazon EC2 chama essas instâncias de grupos de segurança e tem chamadas de API e comandos para manipulá-los. Você os verá mais de perto na hora certa. Enquanto isto, a Listagem 2 mostra como visualizar seus grupos atuais.

Listagem 2. Exibindo os grupos de segurança atuais
[sean@sergeant:~]$ ec2-describe-group
GROUP   223110335193    default default group

A Listagem 2 mostra um grupo chamado default, com a descrição "default group." O ID de usuário associado ao grupo é 223110335193. Não existem regras neste grupo. Se houvesse, elas seriam descritas abaixo do grupo com a palavra PERMISSION na coluna esquerda.


Preparando o ambiente da nuvem

O primeiro passo é preparar o ambiente da nuvem para testar o aplicativo. O novo ambiente imitará o ambiente atual de produção.

Comece iniciando a AMI, que tem um ID de ami-10b55379. A Listagem 3 mostra a AMI sendo iniciada e o status sendo verificado.

Listagem 3. Iniciando a AMI do CentOS
[sean@sergeant:~]$ ec2-run-instances ami-10b55379 -k main
RESERVATION  r-750fff1e  223110335193  default
INSTANCE  i-75aaf41e  ami-10b55379  pending  main  0  m1.small
2010-05-15T02:02:57+0000 us-east-1a  aki-3038da59  ari-3238da5b  monitoring-disabled
instance-store  
[sean@sergeant:~]$ ec2-describe-instances i-75aaf41e
RESERVATION  r-750fff1e  223110335193  default
i-75aaf41e  ami-10b55379  pending  main  0  E3D48CEE  m1.small
2010-05-15T02:02:57+0000 us-east-1a  aki-3038da59  ari-3238da5b  monitoring-disabled
instance-store  
[sean@sergeant:~]$ ec2-describe-instances i-75aaf41e
RESERVATION  r-750fff1e  223110335193  default
INSTANCE  i-75aaf41e  ami-10b55379  ec2-184-73-43-141.compute-1.amazonaws.com
domU-12-31-39-00-64-71.compute-1.internal  running  main  0  E3D48CEE  m1.small
2010-05-15T02:02:57+0000  us-east-1a  aki-3038da59  ari-3238da5b  monitoring-disabled
184.73.43.141  10.254.107.127  instance-store

O primeiro comando inicia a instância usando a AMI ami-10b55379 e especifica que o par de chaves gerado na Listagem 1 será usado para autenticar a máquina. O comando retorna várias informações, a mais importante delas sendo o identificador da instância (i-750fff1e), que é a identidade da máquina na nuvem do Amazon EC2. O segundo comando usa ec2-describe-instances, que lista todas as instâncias em execução. Na Listagem 3, o identificador da instância foi passado na linha de comandos para exibir somente informações sobre aquela instância. O estado da instância é listado como pending, o que significa que a instância ainda está sendo iniciada. A AMI da IBM é grande, portanto leva, tipicamente, 5 a 10 minutos para iniciar. Executar o mesmo comando algum tempo mais tarde mostrará que o estado é running e que o endereço IP externo 184.73.43.141 foi dado. O endereço IP interno que começa com 10 é útil para falar dentro da nuvem do Amazon EC2, mas não agora.

É possível, então, usar SSH para se conectar ao servidor usando a chave que foi gerada anteriormente. Mas, primeiro, é preciso permitir o SSH (22/TCP). A Listagem 4 mostra como autorizar a conexão e efetuar login em seu novo servidor.

Entendendo chaves SSH

Se não estiver familiarizado com chaves SSH, é útil saber que o SSH pode autenticar usuários com chaves, em vez de senhas. Você gera um par de chaves, que é composto de uma chave pública e uma chave privada. Você mantém a chave privada e carrega a chave pública em um arquivo chamado authorized_keys, que está dentro do diretório $HOME/.ssh. Ao conectar a um servidor com SSH, o cliente poderá tentar a autenticação com a chave. Se tiver sucesso, você terá efetuado o login.

Uma propriedade do par de chaves é que mensagens criptografadas com uma das chaves só pode ser descriptografada com a outra. Ao conectar a um servidor, ele poderá criptografar uma mensagem com a chave pública armazenada no arquivo authorized_keys. Se você descriptografar a mensagem usando sua chave pública, o servidor saberá que você está autorizado a efetuar o login sem uma senha.

A próxima pergunta lógica é "Como o arquivo authorized_keys é preenchido com a chave pública que está armazenada no Amazon?" Cada instância do Amazon EC2 pode falar com um servidor da web na nuvem do Amazon EC2 em http://169.254.169.254 e recuperar metadados sobre a instância. Uma das URLs é http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key, que retorna a chave pública associada com a imagem.

Ao inicializar, a AMI recupera a chave pública e a armazena em authorized_keys. Isto é feito em /etc/init.d/getssh no exemplo de AMI. Poderia também, facilmente, ocorrer em rc.local.

Outro uso dos metadados de instância é passar informações para a imagem. É possível ter uma AMI genérica que poderia ser um servidor da web ou servidor de tarefas em segundo plano e fazer com que a instância decidisse que serviços iniciar, com base nos parâmetros passados ao iniciar a imagem.

Listagem 4. Conectando à instância
[sean@sergeant:~]$ ec2-authorize default -p 22 -s $MYIP/32
...
[sean@sergeant:~]$ ssh -i ~/.ssh/main.pem root@184.73.43.141
The authenticity of host '184.73.43.141 (184.73.43.141)' can't be established.
RSA key fingerprint is af:c2:1e:93:3c:16:76:6b:c1:be:47:d5:81:82:89:80.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '184.73.43.141' (RSA) to the list of known hosts.
...

O primeiro comando permite a porta 22 (TCP é a opção padrão) a partir de uma fonte de seu endereço IP. O /32 significa que somente o host tem permissão, não a rede inteira. O comando ssh se conecta ao servidor usando a chave privada.

Instalando o Ruby

O CentOS vem com uma versão limitada do Ruby, portanto você instalará o Ruby Enterprise Edition (REE), que é um interpretador Ruby de alto desempenho compatível com a ramificação 1.8.7 atual do Ruby. Apesar do nome parecer caro, o software é livre. A Listagem 5 mostra como instalar o REE.

Listagem 5. Instalando o REE
# rpm -e ruby ruby-libs
# yum -y install gcc-c++ zlib-devel openssl-devel readline-devel
...
Complete!
# wget http://rubyforge.org/frs/download.php/71096/ruby-enterprise-1.8.7-2010.02.tar.gz
...
# tar -xzf ruby-enterprise-1.8.7-2010.02.tar.gz
# ruby-enterprise-1.8.7-2010.02/installer -a /opt/ree

Os primeiros dois comandos da Listagem 5 removem a instalação padrão do Ruby e instalam um compilador C e alguns pacotes de desenvolvimento necessários. O wget efetua o download do tarball atual do REE, que é, a seguir, descomprimido pelo tar. Finalmente, o último comando executa o instalador com uma opção para aceitar todos os padrões e colocar os resultados em /opt/ree. O instalador é inteligente o suficiente para lhe dizer os comandos que deverão ser executados se alguns pacotes estiverem ausentes, portanto observe cuidadosamente a saída se a instalação não funcionar.

Depois que o Ruby for instalado, adicione o diretório bin a seu caminho com export PATH="/opt/ree/bin:$PATH", que poderá ser colocado no diretório disponível para todo o sistema /etc/bashrc ou no diretório .bashrc dentro de seu diretório inicial.

Instalando o PostgreSQL

O servidor PostgreSQL é parte da distribuição do CentOS, portanto tudo o que você precisa fazer é instalá-lo com o utilitário yum. A Listagem 6 mostra como instalar o PostgreSQL e assegurar-se de que ele será executado na inicialização.

Listagem 6. Instalando o PostgreSQL
# yum -y install postgresql-server postgresql-devel
...
Installed: postgresql-devel.i386 0:8.1.21-1.el5_5.1 
   postgresql-server.i386 0:8.1.21-1.el5_5.1
Dependency Installed: postgresql.i386 0:8.1.21-1.el5_5.1 
   postgresql-libs.i386 0:8.1.21-1.el5_5.1
Complete!
# chkconfig postgresql on

O comando yum instala pacotes a partir de um repositório. Na Listagem 7, você está instalando o componente do servidor PostgreSQL e as bibliotecas de desenvolvimento. Isto automaticamente puxa os utilitários principais de banco de dados e quaisquer outros pacotes de que precisar. Você não precisará ainda do pacote de desenvolvimento, mas, quando precisar integrar o Rails e o PostgreSQL, precisará das bibliotecas dentro de postgresql-devel.

Por padrão, o banco de dados armazena seus arquivos em /var/lib/pgsql/data, que é parte do sistema de arquivos raiz. Você moverá este diretório para o armazenamento da instância em on /mnt, como mostra a Listagem 7.

Listagem 7. Movendo o armazenamento de dados do PostgreSQL para /mnt
# mv /var/lib/pgsql/data /mnt
# ln -s /mnt/data /var/lib/pgsql/data
# service postgresql start

Depois de inserir os comandos na Listagem 7, o /mnt do PostgreSQL estará no fim.

A seguir, é preciso ativar logins com senha para o banco de dados payroll_prod (que será criado na próxima etapa). Por padrão, o PostgreSQL não usa senhas: ele usa um sistema interno de identificação. Simplesmente adicione:

host "payroll_prod" all 127.0.0.1/32 md5

na parte superior de /var/lib/pgsql/data/pg_hba.conf e, a seguir, execute:

 su - postgres -c 'pg_ctl reload'

para que a alteração entre em vigor. Com esta configuração, logins normais ao PostgreSQL não precisarão de uma senha (que é motivo pelo qual o comando reload não precisou de uma senha), mas qualquer acesso ao banco de dados payroll precisará.

A etapa final é configurar o banco de dados Rails a partir da linha de comandos. Execute su - postgres -c psql e acompanhe na Listagem 8.

Listagem 8. Criando o usuário e o banco de dados
postgres=# create user payroll with password 'secret';
CREATE ROLE
postgres=# create database payroll_prod;
CREATE DATABASE
postgres=# grant all privileges on database payroll_prod to payroll;
GRANT

E, com isso, seu banco de dados está criado.

Migrando os dados

Para testar, você deveria obter um dump de seu banco de dados do ambiente de produção em um certo momento, para que tenha algo com que testar. O aplicativo SmallPayroll armazena dados tanto no banco de dados quanto no sistema de arquivos. O dump do banco de dados será feito usando o comando pg_dump que acompanha o PostgreSQL; os dados do sistema de arquivo usarão rsync. O banco de dados deverá ser apagado e transferido novamente para a migração por causa da natureza dos dumps de bancos de dados, mas os dados do sistema de arquivo só precisam transferir arquivos novos e alterados, pois o rsync consegue detectar quando um arquivo não sofreu modificações. Portanto, a parte de teste do plano ajuda a acelerar a migração, pois a maioria dos dados já estará lá.

A maneira mais rápida de copiar o banco de dados é executando:

 pg_dump payroll_prod | gzip -c >
                                                /tmp/dbbackup.gz

em sua máquina da produção, copiando dbbackup.gz para o servidor da nuvem e, a seguir, executando:

 zcat dbbackup.gz | psql payroll_prod

Este comando simplesmente cria um dump compactado do banco de dados em um servidor e, a seguir, reexecuta todas as transações no outro servidor. O

rsync é simples assim. Em seu servidor de produção, execute:

 rsync -avz -e "ssh -i .ssh/main.pem"
/var/uploads/ root@174.129.138.83:/var/uploads/

Este comando copia tudo de /var/uploads do servidor de produção atual para o novo servidor. Se executá-lo novamente, somente os arquivos alterados são copiados, economizando tempo mais tarde em sincronizações.

Como você está copiando o banco de dados, não é preciso aplicar primeiro suas migrações do Rails. O Rails acreditará que o banco de dados está atualizado, pois você já copiou a tabela schema_migrations.

Implementando o aplicativo Rails

Neste momento, você tem um servidor base configurado, mas não seu aplicativo. É preciso instalar alguns gems básicos, juntamente com quaisquer gems que seu aplicativo precisar, antes que ele possa ser executado. A Listagem 9 mostra os comandos necessários para atualizar seus gems. Note que é preciso estar na raiz de seu aplicativo Rails, portanto copie-o primeiro para seu servidor.

Listagem 9. Atualizando o RubyGems e instalando seus gems
# gem update --system
Updating RubyGems
Nothing to update
# gem install rails mongrel mongrel-cluster postgres
Successfully installed rails-2.3.8
Building native extensions.  This could take a while...
Successfully installed gem_plugin-0.2.3
Successfully installed daemons-1.1.0
Successfully installed cgi_multipart_eof_fix-2.5.0
Successfully installed mongrel-1.1.5
Successfully installed mongrel_cluster-1.0.5
Building native extensions.  This could take a while...
Successfully installed postgres-0.7.9.2008.01.28
7 gems installed
...
# rake gems:install
(in /home/payroll)
gem install haml
Successfully installed haml-3.0.12
1 gem installed
Installing ri documentation for haml-3.0.12...
Installing RDoc documentation for haml-3.0.12...
gem install money
...

O primeiro comando assegura que o RubyGems propriamente dito esteja atualizado. O segundo comando instala alguns gems úteis:

  • rails. A estrutura Ruby on Rails
  • postgres. O driver do banco de dados que permite usar o PostgreSQL com ActiveRecord
  • mongrel. Um servidor de aplicativos usados para armazenar o aplicativo Rails
  • mongrel_cluster. Utilitários que permitem iniciar e parar grupos de mongrels ao mesmo tempo

O último comando executa uma tarefa do Rails para instalar todos os gems extras que o aplicativo requer. Se você não usou a diretiva config.gem em seu arquivo config/environment.rb, então poderá ser preciso instalar os gems extras manualmente usando o comando gem install gemname.

Tente iniciar seu aplicativo com o comando RAILS_ENV=production script/console. Se este comando for bem sucedido, pare-o e, a seguir, inicie seu pacote de mongrels com:

 mongrel_rails cluster::start -C
/home/payroll/current/config/mongrel_cluster.yml

Se o primeiro comando não for bem sucedido, você receberá várias mensagens de erro para ajudá-lo a encontrar o problema, que geralmente é um gem ou arquivo ausente. Aproveite esta oportunidade para voltar e colocar quaisquer diretivas config.gem ausentes, para que não esqueça o gem no futuro.

Instalando um servidor web front-end

Nginx é o servidor web de escolha para muitos ambientes virtuais. Ele tem baixo custo adicional e é bom para realizar conexões de proxy para um serviço de backend, como mongrel. A Listagem 10 mostra como instalar o nginx.

Listagem 10. Instalando nginx
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
...
# yum install nginx
...
Running Transaction
Installing     : nginx                                             [1/1]
Installed: nginx.i386 0:0.6.39-4.el5
Complete!
# chkconfig nginx on

A Listagem 11 instala o repositório Extra Packages for Enterprise Linux® (EPEL) e, a seguir instala o nginx e assegura que ele será executado na inicialização.

Listagem 11. Uma configuração do nginx para um aplicativo rails
# Two mongrels, balanced based on least connections
upstream mongrel-payroll {
	fair;
	server 127.0.0.1:8100;
	server 127.0.0.1:8101;
}

server {
	listen 80;
	server_name  app.smallpayroll.ca;

	root   /home/payroll/current/public;
	gzip_static on;

	access_log  /var/log/nginx/app.smallpayroll.ca_log  main;
	error_page  404       /404.html;

	location / {
		# Because we're proxying, set some environment variables indicating this
		proxy_set_header X-Real-IP  $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_redirect false;
		proxy_max_temp_file_size 0;


		# Serve static files out of Root (eg public)
		if (-f $request_filename) {
			break;
		}

		# Handle page cached actions by looking for the appropriately named file
		if (-f $request_filename.html) {
			rewrite (.*) $1.html;
			break;
		}

		# Send all other requests to mongrel
		if (!-f $request_filename) {
			proxy_pass http://mongrel-payroll;
			break;
		}
	}
	error_page   500 502 503 504  /500.html;
	location = /500.html {
		root   /home/payroll/current/public;
	}
}

A Listagem 11 mostra uma configuração relativamente típica do nginx, com alguns elementos inseridos para manipular o armazenamento em cache de páginas do Rails e enviar solicitações dinâmicas para um mongrel de saída. Você poderia mapear outras URLs para nomes de arquivo aqui, se necessário.

Com a configuração no lugar, service nginx start inicia o servidor da web.

Testes

Para os testes, seria útil ser capaz de referenciar sua instância na nuvem usando o nome regular de domínio do aplicativo, pois você deseja garantir que esteja usando o site de teste, e não o site de produção. Isto é feito por meio de uma substituição do DNS local. No Windows, edite C:\windows\system32\drivers\etc\hosts; no UNIX, edite /etc/hosts. Adicione uma linha como:

 x.x.x.x app.smallpayroll.ca

onde x.x.x.x é o endereço IP de seu servidor da nuvem e app.smallpayroll.ca é o nome do aplicativo. Reinicie seu navegador e acesse seu site da web. Você estará agora usando a versão de seu aplicativo na nuvem. (Não se esqueça de comentar a linha que acabou de adicionar quando desejar retornar à versão de produção!)

Neste momento, você deverá ser capaz de testar que a versão da nuvem de seu aplicativo funciona da mesma forma que a versão de produção; corrija quaisquer problemas que encontrar. Anote cuidadosamente o que encontrar, pois será bom criar um script caso inicie um segundo servidor. Como você está usando a versão da nuvem de seu aplicativo, é possível excluir e restaurar o banco de dados sem que os usuários reclamem.

Empacotando a nova AMI

A última coisa a fazer é reempacotar sua AMI. A qualquer momento que iniciar uma nova instância, você perderá tudo que está em /mnt e sua partição raiz será redefinida para o que estiver na AMI. Ainda não há nada que possa fazer sobre o problema com o /mnt, mas o reempacotamento assegura que sua AMI continue da maneira como a deixou.

Se a AMI que estiver iniciando não tiver as ferramentas de AMI, é possível instalá-las com o seguinte comando:

rpm -i --nodeps
http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm

Empacotar uma AMI é um processo em três etapas:

  1. Criar a imagem da instância propriamente dita.
  2. Carregar a imagem para o Amazon S3.
  3. Registrar a AMI.

Antes de prosseguir, interrompa suas instâncias do mongrel e do PostgreSQL, para garantir que quaisquer arquivos abertos sejam tratados corretamente. É preciso também copiar suas chaves X.509, que se encontram no Amazon Console, para o /mnt em seu servidor. A Listagem 12 mostra as primeiras duas etapas do empacotamento, que são realizadas na VM propriamente dita.

Listagem 12. Empacotando a AMI
# ec2-bundle-vol -d /mnt -e /mnt --privatekey /mnt/pk-mykey.pem  \
--cert /mnt/cert-mycert.pem --user 223110335193 -p centos-ertw
Please specify a value for arch [i386]:
Copying / into the image file /mnt/centos-ertw...
...
Generating digests for each part...
Digests generated.
Creating bundle manifest...
ec2-bundle-vol complete.
# ec2-upload-bundle -b ertw.com -m /mnt/centos-ertw.manifest.xml \
--secret-key MYSECRETKEY --access-key MYACCESSKEY
Creating bucket...
Uploading bundled image parts to the S3 bucket ertw.com ...
...
Uploaded centos-ertw.part.37
Uploading manifest ...
Uploaded manifest.
Bundle upload completed.

O primeiro comando gera o pacote, especificando que /mnt deverá ser ignorado e que ele irá para /mnt (as opções -e e -d, respectivamente). As opções -k, --cert e --user apontam para suas credenciais de segurança e ID de usuário do AWS, que podem ser encontradas nas configurações de conta de seu console de gerenciamento do AWS. A última opção, -p, permite nomear esta AMI para diferenciá-la das outras.

O primeiro comando executará por cerca de 10 minutos, dependendo do quanto sua partição raiz estiver cheia. O segundo comando carrega o pacote no Amazon S3. A opção -b especifica um nome de depósito, que será criado se ainda não existir. A opção -m aponta para o arquivo de manifesto criado na última etapa. As duas últimas opções são suas credenciais do Amazon S3, que podem ser encontradas junto a suas credenciais X.509 no console de gerenciamento do AWS. Mas lembre-se de que suas credenciais X.509 são usadas para operações do Amazon EC2, enquanto que o Amazon S3 usa chaves de texto.

Finalmente, execute o comando:

 ec2-register
                                                ertw.com/centos-ertw.manifest.xml

para registrar a AMI e verá o identificador da AMI para usar de agora em diante. Note que o comando ec2-register não é distribuído com a AMI, portanto é mais fácil executá-lo a partir do servidor onde a AMI original foi iniciada. Também é possível instalar as ferramentas do Amazon EC2 em sua instância do Amazon EC2.


Realizando a migração

Agora que seu ambiente em nuvem está funcionando, a migração em si deverá ser bem simples. Você verificou que tudo está funcionando: Tudo o que resta é sincronizar os dados e transferir o serviço de forma ordenada.

Tarefas pré-migração

Algum tempo antes da migração, assegure-se de diminuir o TTL dos registros de nome do seu domínio para 5 minutos. Você também deverá desenvolver uma lista de verificação das etapas necessárias para mover tudo, os testes que deseja realizar para verificar se tudo está funcionando e o procedimento para reverter a mudança, se necessário.

Assegure-se de que seus usuários sejam notificados da migração!

Imediatamente antes do horário da migração, verifique novamente o ambiente da nuvem para se assegurar de que ele esteja pronto para ser sincronizado e aceitar tráfego de produção.

Migrando o aplicativo

Para migrar o aplicativo, realize as seguintes etapas:

  1. Desative o site atual de produção ou coloque-o em modo somente leitura, dependendo da natureza do site.

    Como a maioria das solicitações de SmallPayroll envolve gravação no banco de dados ou sistema de arquivos, o site será desativado. O gem de implementação Capistrano inclui uma tarefa, cap deploy:web:disable, que coloca uma página de manutenção no site informando aos usuários que o site está fora do ar para manutenção.

  2. Pare os serviços do aplicativo no ambiente da nuvem em preparação para a migração dos dados interrompendo seus processos mongrel.
  3. Copie o banco de dados da mesma forma como fez para testar.
  4. Execute novamente o rsync, se necessário.
  5. Reinicie os servidores de aplicativo com o comando:
     mongrel_rails
      cluster::start -C
      /home/payroll/current/config/mongrel_cluster.yml
  6. Assegure-se de que seu arquivo hosts aponta para o ambiente da nuvem e realize alguns testes. Assegure-se de que os usuários conseguem efetuar o login e navegar pelo site.

Atualizando o DNS

Se seus testes forem bem-sucedidos, então você poderá alterar seus registros de DNS para apontar para o ambiente da nuvem. Neste ponto, acho útil manter um tail -f em execução no arquivo de log do servidor web para observar se as pessoas estão acessando o site.

Há chances de que seu servidor DNS local ainda tenha informações antigas armazenadas em cache pelos próximos 5 minutos. É possível verificar isto com o comando dig, conforme mostra a Listagem 13.

Listagem 13. Verificando se o servidor DNS está armazenando a consulta em cache
# dig  app.smallpayroll.ca @172.16.0.23

; <<>> DiG 9.3.4 <<>> app.smallpayroll.ca @172.16.0.23
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38838
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0

;; QUESTION SECTION:
;app.smallpayroll.ca.           IN      A

;; ANSWER SECTION:
app.smallpayroll.ca.    251     IN      A       69.164.205.185
...

Na seção ANSWER, você pode ver que faltam 251 segundos para que a entrada expire. É importante usar uma ferramenta como dig, host ou nslookup para verificar o DNS, pois seu arquivo hosts está substituindo o DNS por enquanto. Usar ping usaria o que estiver dentro do arquivo hosts.

Realize seu teste final de aceitação enquanto espera que o DNS seja propagado.


Conclusão

Você migrou com sucesso um aplicativo para a nuvem! O procedimento básico foi:

  1. Configurar o novo ambiente.
  2. Testar com uma cópia dos dados de produção.
  3. Desligar o ambiente antigo.
  4. Copiar os dados de produção para o novo ambiente.
  5. Alterar o DNS para apontar para o novo ambiente.

Apesar de agora estar "na nuvem", o aplicativo provavelmente está em pior situação do que antes. Considere os seguintes pontos:

  • O aplicativo ainda está em execução em um servidor.
  • Se o servidor travar, todos os dados serão perdidos.
  • Você tem menos controle sobre o desempenho do que tinha em seu servidor físico.
  • A máquina e o aplicativo não estão trancados.

No próximo artigo, você aprenderá como resolver estes problemas e começar a construir um ambiente mais robusto para seu aplicativo.

Recursos

Aprender

Obter produtos e tecnologias

  • O Ruby Enterprise Edition é uma implementação de alto desempenho do Ruby que pode ser usado por si só ou em conjunto com o Phusion Passenger para integrar com Apache ou nginx. De qualquer forma, você obtém acesso a gerenciamento mais rápido de memória e melhor coleta de lixo.
  • Registre-se em IBM Industry Application Platform AMI for Development Use para obter uma introdução aos vários produtos da IBM na nuvem. Lembre-se de que terá que passar por um processo de registro de saída, mas não será cobrado por nada até que o use. Você pode usar também a ami-90ed0ff9.
  • As ferramentas da API do Amazon EC2 são usadas para comunicar com a API do Amazon para iniciar e terminar instâncias e reempacotar novas instâncias. Estas ferramentas são periodicamente atualizadas à medida que novos recursos são introduzidos no EC2, portanto é bom verificar anúncios de atualização de produtos nesta página. Você precisará pelo menos da atualização 2009-05-15, pois usará alguns dos recursos de balanceamento de carga posteriormente.
  • Avalie os produtos da IBM da forma que melhor lhe convém: Faça o download de uma versão de teste de produto, experimente um produto on-line, use um produto em um ambiente de nuvem ou passe algumas horas no SOA Sandbox aprendendo como implementar Arquitetura Orientada a Serviço de forma eficiente.

Discutir

  • Envolva-se na comunidade My developerWorks. Entre em contato com outros usuários do developerWorks enquanto explora os blogs, fóruns, grupos e wikis dos 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=Linux, Software livre
ArticleID=504347
ArticleTitle=Migre seu aplicativo Linux à nuvem Amazon, Parte 1: Migração inicial
publish-date=05282014