Como implantar o Mongo no AWS usando o Docker: o guia definitivo para iniciantes

Eric Burel Blocked Desbloquear Seguir Seguindo 9 de janeiro

Por que você precisa disso?

Porque JS + Python + Mongo = desenvolvimento de dados completo

Eu sou um desenvolvedor do Meteor. Mais precisamente eu uso o Vulcan.js, mas essa é outra história . O Meteor é um framework Node.js completo, muito bom para SaaS, aplicativos em tempo real, protótipos, softwares de gerenciamento e muitos outros casos de uso.

Por padrão, funciona com o MongoDB. O MongoDB é um sistema de gerenciamento de banco de dados NoSQL (DBMS). Ele armazena documentos como JSON e seu shell usa JavaScript, que são algumas das razões pelas quais ele é tão apreciado pelos desenvolvedores do Node.js.

Existe uma ferramenta legal chamada Meteor Up para implementar automaticamente os aplicativos Meteor e os bancos de dados Mongo associados nos servidores de produção. Neat é na verdade um eufemismo, é incrível.

E também sou um desenvolvedor de Python. O Python é excelente para captura na web e ciência de dados. É fácil de usar e adequado para alto desempenho.

Às vezes, gosto de usar o Python para extrair e processar dados e o Meteor para criar a interface do usuário. Chamo isso de "desenvolvimento de dados completo" , já que vai da fonte de dados bruta até a interface do usuário final.

Os três sagrados do desenvolvedor de dados completo: Meteor, Mongo, Python

Mas há um problema: o Meteor Up atualmente não expõe o banco de dados do Mongo, apenas o aplicativo local do Meteor pode se conectar a ele. Então eu não posso ligar meus servidores Python aos meus bancos de dados gerenciados do Meteor fora da caixa 🙁

Um serviço pago faria o trabalho fornecendo uma URL para o banco de dados hospedado, como este:

 mongo://username:password@somedomain.com:27017 

Mas por que gastar dinheiro quando você pode lutar por horas para configurar seu próprio banco de dados Mongo no AWS usando o Docker, e aprender toneladas de truques úteis no processo? É ainda melhor se alguém, digamos, fizer primeiro e escrever um longo tutorial para facilitar as coisas para você!

Nota importante: está perfeitamente bem se você precisar de várias sessões para concluir este tutorial. Não desista! O resultado vale a pena, já que dominar o Docker e a AWS são duas habilidades muito apreciadas pelos empregadores e muito úteis na vida real. Poste suas perguntas como comentários se você tiver alguma, eu farei o meu melhor para responder a todas elas.

1 – Vamos descobrir o Docker

Nosso primeiro recipiente

Convido você a ler o documento de instalação oficial do Docker aqui e instalá-lo, o que leva apenas alguns minutos. Então, vamos brincar um pouco. Execute os seguintes comandos no seu terminal e observe os resultados:

 execução do docker --name my-lame-db -d mongo 
docker ps

Tão simples quanto isso, acabamos de criar um contêiner isolado que executa o Mongo!

Você pode acessar os arquivos oficiais do Docker de imagem do Mongo em algum lugar dessa pasta hospedada no GitHub para entender melhor o que acontece aqui. De acordo com as últimas linhas do Dockerfile, o nosso banco de dados está disponível na porta “27017” como padrão:

 EXPOSE 27017 CMD ["mongod"] 

Mas o Mongo se expõe nessa porta no interior do contêiner. Mas o contêiner é isolado, portanto, apenas programas dentro do contêiner podem falar com o Mongo. Nosso banco de dados está ativo e em execução, mas preso sozinho em seu contêiner: /

Isso é manco! Vamos libertá-lo!

Abra o contêiner, mapeie as portas

Se você quiser acessar o Mongo a partir do OUTSIDE do contêiner, você terá que mapear a porta exposta e uma porta da máquina. A opção -p é especificamente para isso:

 docker run -p 27017:27017 --name my-local-db -d mongo 

Se você tivesse um servidor Node, você docker run -p 80:3000 my-node-app por exemplo. Seu servidor rodando na porta 3000 estaria assim disponível via HTTP (porta 80). Primeiro a porta do contêiner e a porta da imagem.

Vamos tentar acessar nosso banco de dados no navegador, apenas por diversão:

Agradável! Nosso banco de dados está funcionando! Você pode tentar os comandos `docker stop my-awesome-db` e` docker start my-awesome-db`. Você verá esse endereço não disponível e, em seguida, estará disponível novamente.

Como esperado, você não pode se conectar ao seu db através do navegador. Mas esta mensagem de rejeição vem de Mongo, o que é um bom sinal. Vamos tentar novamente usando a ferramenta oficial do CLI:

 mongo localhost: 27017 #ou apenas "mongo", já que este é o padrão uri 

Você pode acessar o seu shell de banco de dados, estamos fazendo progresso!

Mas… eu quero que meu banco de dados esteja em um servidor distante, não seja executado localmente em minha máquina isolada.

2 – Acesse a AWS no seu terminal

Escolhemos a AWS como nosso provedor de nuvem porque ela é amplamente difundida, mas lembre-se de que isso é apenas um exemplo. A AWS oferece aos novos usuários hospedagem gratuita por 12 meses para uma instância do servidor, portanto, você não precisa pagar para seguir este tutorial. As etapas são basicamente semelhantes se você escolher outro serviço de hospedagem.

O primeiro passo é criar um acesso programático ao Amazon Web Services usando o serviço IAM (Identity and Access Management). Essa chave será usada pelo Docker Machine (veja abaixo) para fazer algumas operações, como criar uma instância do AWS EC2 para você.

Configurar isso está fora do escopo do nosso tutorial. Portanto, convido-vos a ler a primeira parte deste artigo de Vishal Kumar . Siga os primeiros 8 passos até obter credenciais da AWS. O resto do artigo é interessante também, mas um pouco avançado neste ponto e direcionado para a pilha MEAN. Vamos nos concentrar em Mongo apenas no momento.

Neste ponto, você deve ter suas credenciais.

 [padrão] 
aws_access_key_id = [tecla de acesso do arquivo de credencial baixado]
aws_secret_access_key = [chave de acesso secreto do arquivo de credencial baixado]

Mantenha eles salvos! Você terá que recriar um par de chaves se você as perder … e você certamente NÃO quer que ninguém as descubra também!

3 – Coloque o Docker na nuvem com o Docker Machine

Nunca mais precise do console da AWS

O Docker Machine é um utilitário para gerenciar as diferentes máquinas que hospedam seus contêineres (máquinas locais, servidores de nuvem). Daí o nome, Docker … Máquina. Você pode configurá-lo para vários provedores de nuvem e funciona muito bem com a AWS.

A documentação oficial fornece todas as informações necessárias para a AWS. Eu apenas pulei a parte VPC, é um pouco avançada demais para o momento, mas o resto é muito útil.

Crie a instância do EC2

Você vai acabar escrevendo um comando semelhante ao abaixo.

 docker-machine create  
--driver amazonec2
--amazonec2-access-key ***** --amazonec2-secret-key ****
--amazonec2-region *****
--amazonec2-open-port 27017 my-awesome-server

Vamos acabar com isso.

  • Eu uso o driver EC2, já que sou um usuário da AWS.
  • Eu passo as credenciais em linha, pois tenho várias contas para gerenciar
  • Eu passo na região onde eu geralmente hospedo meus aplicativos ("eu-west-3" para mim),
  • Não se esqueça de abrir a porta 27017 ( --amazonec2-open-port 27017 ), caso contrário, o AWS bloqueará as conexões mesmo que o contêiner esteja configurado corretamente.

Se você não especificou a região corretamente, poderá ter problemas para localizar sua instância no console da AWS. Eu ainda não entendo porque você não pode ter todas as zonas exibidas facilmente nesta interface, mas é assim que funciona.

Você também deve conseguir se livrar da chave de acesso e da chave secreta de alguma forma configurando as credenciais da sua máquina local da AWS ou armazenando-as como variáveis de ambiente. Eu pessoalmente prefiro tê-los na linha de comando, pois posso substituí-los por variáveis de ambiente.

Nesse momento, você pode verificar o console da AWS e ver sua instância configurada como esperado!

4 – Executar um contêiner do Mongo em sua instância

Ative a máquina correta

Agora a parte complicada, demorei um pouco para acertar. O papel do Docker Machine é gerenciar suas máquinas distantes, iniciar instâncias e instalar o Docker nele. Isso é tudo. NÃO é Docker.

Então você ainda tem que usar o Docker. Mas como o Docker sabe qual máquina conectar também?

Experimente e veja o resultado:

 docker-machine env my-awesome-server 

Ele mostrará um pequeno script de shell para configurar variáveis de ambiente.

Também lhe diz para executar este comando:

 eval $(docker-machine env my-awesome-server) 

Isso simplesmente executará o script exibido no seu shell. Quando essas variáveis env são definidas, sua máquina se torna “ativa”.

Digite docker-machine active para verificar se a máquina correta está listada.

o /

Agora digite as docker info e você verá que o Name corresponde ao seu aplicativo. Magia! O Docker está “conectado” à máquina ativa, configurada pelo Docker Machine.

Agora podemos executar o mesmo comando de antes:

 docker run -p 27017:27017 --name my-awesome-db -d mongo . 

Ele criará o banco de dados não em nossa máquina local, mas no servidor distante. Tão simples como isso!

Execute este comando para obter o IP da sua máquina:

 docker-machine ip my-awesome-server 

E abra o endereço http://<ip-given-by-docker-machine>:27017 : você deve receber uma bela mensagem de erro dizendo que está tentando acessar o MongoDB via HTTPS: funciona !!!

Execute o mongo <ip-given-by-docker-machine>:27017 … e… você está dentro! Parabéns, você acabou de configurar o contêiner do Docker em um servidor de produção.

Ok, definitivamente não queremos que o mundo inteiro acesse nosso banco de dados, então o próximo passo é configurar a autenticação.

5 – Configuração de autenticação – solução de 2 contêineres

Desculpe, mas você já pode excluir o contêiner que acabou de criar (exercício: deixo que você descubra o contêiner parando e removendo comandos). Foi só um exemplo. Infelizmente, você não poderá configurar a autenticação com ele.

Mantenha o foco porque o processo é um pouco mais complicado do que você esperaria:

  • Vamos criar um primeiro container, vamos chamar de "Container # 1", SEM auth.
  • Vamos configurar esse contêiner para que os dados sejam salvos no disco do servidor (que é uma etapa importante), criar e administrar e excluir o contêiner.
  • Vamos criar um segundo container, "Container # 2" WITH auth. As credenciais do usuário administrador ainda serão válidas, porque são salvas no disco.

Pode haver soluções mais simples das quais eu ainda não estou ciente, por exemplo, fornecendo as credenciais do usuário administrador durante a criação do contêiner, então sinta-se à vontade para comentar se você for um super-herói do Docker / Mongo! E uma solução de um recipiente também é fornecida nos anexos no final do artigo.

Compartilhar dados entre contêineres

Neste ponto, você deve pensar “bem, os contêineres são isolados, então, como o Container nº 1 e o Container nº 2 compartilham o mesmo usuário admin”? E você está certo. A solução está no armazenamento de arquivos no servidor.

Lembra quando mapeamos portas, para que a porta aberta do contêiner mapeie a porta do Mongo? Aplicaremos a mesma lógica ao sistema de arquivos: podemos mapear pastas no contêiner e pastas no servidor.

Vamos adicionar uma opção ao nosso comando e vamos chamá-lo de comando Final do Container # 1:

 execução do docker  
-d
-p 27017: 27017
--name my-awesome-db
-v ~ / dataMongo: / data / db mongo
mongod

Inteligente! Agora, quando nossos contêineres do Mongo lerem / gravarem seus dados no data/db eles também estarão disponíveis para o servidor host , na pasta ~/dataMongo (primeira pasta do host, depois pasta do contêiner).

Crie o usuário admin

Está tudo no título: agora você vai se conectar à sua recém-criada instância do Mongo e criar o usuário admin.

 docker-machine ip my-awesome-server 
mongo <resulting-ip>

Agora você deve estar conectado ao seu shell de banco de dados. Você só precisa criar um superusuário administrativo:

 db.createUser( 
{
user: "admin",
pwd: "yourpassword",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ],
passwordDigestor : "server"
}
)

Você pode examinar o documento oficial , este artigo e este thread de estouro de pilha para obter mais informações.

Além disso, consulte este tópico sobre a diferença entre a função root , que é um superadministrador real, e a função userAdminAnyDatabase , que é uma espécie de “criador do usuário”.

Exclua o contêiner e ative a autenticação

Podemos remover o Container # 1, seu papel era apenas nos permitir acessar um shell do Mongo em nosso servidor, mas faltava autenticação.

 docker stop my-awesome-db 
docker rm my-awesome-db

Podemos então criar nosso contêiner final, com autenticação ativada. Como ele também será conectado ao sistema de arquivos do servidor, os dados criados usando o Container # 1 ainda estarão disponíveis, incluindo o nosso usuário administrador.

Nós simplesmente adicionamos a opção --auth ao comando inicial, ele diz ao Mongo… bem, para habilitar a autenticação. Você adivinhou certo.

Comando final para o recipiente # 2:

 execução do docker  
-d
-p 27017: 27017
--name my-awesome-db
-v ~ / dataMongo: / data / db mongo
--auth
mongod

Agora, conecte-se novamente à sua instância do Mongo e execute:

 db.createCollection ('IAMAHACKER') 

Você receberá uma boa mensagem de erro como esperado!

E agora tente novamente enquanto está sendo autenticado:

 mongo $ (docker-máquina ip my-awesome-server): 27017 -u admin -p yourpassword 

Se funcionar, está feito! Parabéns;)

O que agora?

Seu banco de dados Mongo está ativo e em execução na nuvem, isolado com segurança em seu contêiner Docker e protegido com autenticação de nome de usuário / senha.

Os próximos passos serão conectar seus aplicativos a esse banco de dados. Lembre-se que você pode acessar o IP do seu servidor usando o comando docker-machine ip my-awesome-server . Você certamente terá que criar usuários adicionais para administrar seus bancos de dados.

Além disso, você provavelmente não desejará que ninguém se conecte ao seu shell de banco de dados, mesmo com o conjunto de autenticação. A AWS permitirá que você coloque na lista de permissões alguns IPs, correspondentes aos seus aplicativos e ao seu próprio computador, para que apenas fontes confiáveis possam se conectar ao seu banco de dados.

Há também uma solução de "um contêiner". É menos instrutivo, mas mais rápido e requer apenas um contêiner.

Nota: se você já configurou auth usando a abordagem de 2 contêineres, você já concluiu. Se você ainda quiser testar a abordagem de 1 contêiner, precisará criar uma nova instância no EC2 ou remover a pasta ~/dataMongo do servidor.

Você ainda precisa compartilhar suas pastas com o host, caso contrário, seus dados estão vinculados ao contêiner, o que não deve acontecer! Os contêineres devem ser facilmente deletados sem qualquer perda de dados, então os documentos devem ser armazenados em outro lugar.

A ideia é conectar-se ao seu servidor e acessar o Mongo a partir daí, em vez de acessar o Mongo a partir de sua máquina local. É uma diferença muito sutil, mas é o que nos salva um passo.

Se você se conectar ao Mongo enquanto estiver conectado ao seu servidor, terá mais permissão e poderá configurar um usuário administrador mesmo se a autenticação já estiver definida, já que o Mongo o considera um usuário "local". Para reformulá-lo, já que você conseguiu se conectar à máquina em que o Mongo está sendo executado, sua instância do AWS, o Mongo já considera você como um usuário “seguro”, já que um hacker não deveria estar lá em primeiro lugar.

Execute apenas o comando Final do Container # 2

 execução do docker  
-d
-p 27017: 27017
--name my-awesome-db
-v ~ / dataMongo: / data / db mongo
--auth
mongod

Você sempre pode ssh seu servidor usando docker-machine ssh :

 docker-machine ssh my-awesome-server 

O mongo execução irá abrir o shell do Mongo. A partir daí, você pode adicionar um usuário admin EVEN is auth, como fizemos anteriormente.

Anexo 4— Glossário

Um pouco de pessoas devops resmungando.

AWS: Amazon Web Services, uma famosa coleção de serviços em nuvem com ofertas baratas.

AWS EC2: serviço para hospedagem de instâncias do servidor. É onde você hospedaria sua API ou todo o seu website. Observe que pode haver serviços mais adequados para hospedagem de banco de dados, mas como o EC2 é obrigatório, é minha escolha como iniciante.

Docker: é um … bem, um programa? Em suma, é um monte de coisas que ajuda você a executar programas em contêineres, isolados dos outros programas em execução no servidor, sem custar tantos recursos quanto uma máquina virtual. Os contêineres também são úteis para gerenciar serviços (APIs, bancos de dados, etc.) diariamente: mata / reinicia, cria nova instância em uma linha…

Container: essa será a minha definição simplificada, pense em uma máquina virtual sem um sistema operacional. Ele fornece isolamento sem consumir muitos recursos de computação.

Dockerfile: é um arquivo de configuração para o docker, que define todos os programas / arquivos / comandos / opções necessários para executar o aplicativo.

Docker Machine: um CLI para enviar seus contêineres do Docker onde você quiser, na nuvem ou em seus próprios servidores.

Eu sou o co-fundador da empresa francesa Lebrun Burel Knowledge Engineering (LBKE) – https://www.lebrun-burel.com

Sempre feliz em falar sobre código, aprendizado de máquina, inovação e empreendedorismo!