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.
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 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.
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?
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.
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.
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.
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.
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.
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.
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.
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.
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 Railspostgres. O driver do banco de dados que permite usar o PostgreSQL comActiveRecordmongrel. Um servidor de aplicativos usados para armazenar o aplicativo Railsmongrel_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.
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.
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:
- Criar a imagem da instância propriamente dita.
- Carregar a imagem para o Amazon S3.
- 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.
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.
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.
Para migrar o aplicativo, realize as seguintes etapas:
- 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. - Pare os serviços do aplicativo no ambiente da nuvem em preparação para a migração dos dados interrompendo seus processos mongrel.
- Copie o banco de dados da mesma forma como fez para testar.
- Execute novamente o
rsync, se necessário. - Reinicie os servidores de aplicativo com o
comando:
mongrel_rails cluster::start -C /home/payroll/current/config/mongrel_cluster.yml - 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.
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.
Você migrou com sucesso um aplicativo para a nuvem! O procedimento básico foi:
- Configurar o novo ambiente.
- Testar com uma cópia dos dados de produção.
- Desligar o ambiente antigo.
- Copiar os dados de produção para o novo ambiente.
- 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.
Aprender
- No Cloud Computing zone do developerWorks,
obtenha os recursos necessários para desenvolver e
implementar aplicativos na nuvem e manter-se
atualizado sobre os recentes desenvolvimentos na
nuvem.
- Solicite os metadados da instância de sua instância do
Amazon EC2 para obter informações sobre a instância,
desde as chaves SSH que deverá usar até informações
especificadas pelo usuário.
- Inicie sua aventura na
nuvem navegando pelo console de gerenciamento do AWS.
- Se for trabalhar com o
Amazon EC2, você deverá se familiarizar com os vários guias que o Amazon fornece.
- Aprenda sobre as AMIs da
IBM da
perspectiva do Amazon e da perspectiva da IBM.
- Pesquise todos os artigos do Sean no
developerWorks.
- Na zona Linux do developerWorks, encontre
centenas de artigos e tutoriais, bem como downloads,
fóruns de discussão e muitos outros recursos para
desenvolvedores e administradores Linux.
- Mantenha-se atualizado com
os eventos técnicos e webcasts do developerWorks
focados em uma variedade de produtos IBM e assuntos
da indústria de TI.
- Participe de uma orientação gratuita do developerWorks Live!
para atualizar-se rapidamente sobre produtos e
ferramentas da IBM, assim como tendências da
indústria de TI.
- Assista às demos on demand do developerWorks que
abrangem da instalação do produto e demos de
configuração para iniciantes à funcionalidade
avançada para desenvolvedores experientes.
- Siga o developerWorks no Twitter, ou inscreva-se em
um feed dos
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.

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.