Fundamentos de execução de qualquer coisa no AWS (ou qualquer coisa) parte 1 – configuração, execução, registro

EC2, ECR, Docker, sistema e capacidade básica de CD

Este artigo irá configurá-lo com uma compreensão básica de como preparar o seu código para implantação / execução em qualquer lugar e, em seguida, mostrar-lhe como implementá-lo para o AWS, tornando-o facilmente acessível, facilmente implantável etc. Então eu vou garantir que você construa neste caso e são variações para lhe fornecer soluções mais detalhadas (e ajudá-lo a compreendê-las, é claro). Para esta parte, a AWS é apenas um exemplo, o conhecimento que você adquiriu aqui pode ser aplicado principalmente a todos os provedores da nuvem e mesmo a pilha personalizada com servidor privado (virtual ou dedicado).

Observe que eu escolhi NodeJS como plataforma de servidor, mas isso pode ser basicamente aplicado a qualquer tecnologia que funcione no linux. Além disso, esta não é uma solução empresarial grande e robusta, para algo assim, você precisará atualizar em alguns lugares – esta é a sua inicialização como guia.

Existem dois casos de uso totalmente distintos aqui:

  • Servidor NodeJS permanente – na instância AWS EC2
  • Transiente – execução da tarefa pesada de computação NodeJS na instância EC2 e, em seguida, interrompe a instância até a próxima vez que for necessário

O que é realmente

Servidor

Seu aplicativo web regular, o servidor que escuta em uma determinada porta, expondo api, renderizando html etc.

Tarefa

Quando temos uma execução mais longa, uma tarefa pesada de computação. Provavelmente inclui o download de alguns dados, mesclando-o com algum fluxo e empurrando para banco de dados ou similar.

Nesta parte, abordarei apenas implantação de código / servidor e alguns assuntos relacionados importantes. Na segunda parte, vou ajudá-lo a usar o que aprendemos aqui para nos dar a capacidade de usar o EC2 para executar tarefas (e apenas executar para o comprimento da tarefa), como agendar tarefas, desencadear ad hoc etc.

Antes de começarmos

Segurança

  • Preste atenção para onde e como você está armazenando suas chaves de acesso, toneladas de dados pessoais e poder de computação são roubados das pessoas porque eles comprometem suas credenciais com repositórios públicos de github.
  • Certifique-se de examinar mais atentamente a documentação sempre que eu apontar isso (em casos como Configurações de Grupo de Segurança e Configurações de Funções de IAM, várias autenticações, etc.), a configuração errada de permissões pode levar a todos os tipos de vazamentos de dados e hacks (certifique-se de olhar para os eleitores de Chicago incidente de vazamento de dados)
  • Certifique-se de nunca cometer nenhum dos seus dados de autenticação (sim, este é o mesmo que o segundo).

Comum

  • Ao criar este sistema, certifique-se de ter tudo configurado na mesma região AWS.

Elementos do sistema – o que vamos usar

  • Docker – virtualização
  • Systemd – executando coisas
  • AWS EC2 – docker em execução com systemd
  • AWS ECR – como repositório para imagens docker
  • AWS CloudWatch – Logging

Específicos do AWS

  • Grupo de segurança para EC2
  • Chave de acesso (pem) para ec2
  • Chave de acesso IAM + chave
  • IAM papéis para EC2 e lambda

Sua aplicação web

NodeJS

Vamos começar com o servidor web simples. Aqui está o seu server.js :

 var http = require ('http');
 console.log ('Listening on 8080'); 
 http.createServer (função (solicitação, resposta) { 
 response.writeHead (200, { 
 'Content-Type': 'text / plain', 
 'Access-Control-Allow-Origin': '*' 
 }); 
 response.end ('Hello people!'); 
 }). listen (8080);

Docker

O Docker é um mecanismo de contêiner que nos permite criar um contêiner linux dedicado para o nosso aplicativo, definir todos os parâmetros do sistema, pré-instalar dependências e executá-lo em qualquer lugar com pouca ou nenhuma sobrecarga. Ele também vem com a adição de toneladas de infra-estrutura como um código de bondade e possíveis melhorias (docker-compose, docker-swarm, capacidade de executar no cluster kubernetes …) que irão ajudá-lo a provisionar, dimensionar e, de outra forma, construir e manter facilmente a infraestrutura da sua aplicação.

Simplesmente, tudo o que está acima significa que, se você tiver o servidor linux com o Docker instalado, você pode executar seu aplicativo sem instalações e dependências adicionais.

Coloque Dockerfile com o seguinte conteúdo na mesma pasta:

 DE nó: boro
 WORKDIR / usr / src / app
 CÓPIA DE . .
 CMD ["nó", "servidor.js"]

O código acima indica que o docker para baixar a imagem Docker orientada para nodejs específica (no momento da escrita, o boro é a versão NodeJs LTS), prepare o workdir, copie o que há na mesma pasta como dockerfile e execute o node server.js quando o contêiner é executado.

Isso veio a ser conhecido como infra-estrutura como um código , o que ilustra claramente a capacidade que lhe dá (para escrever o código da infra-estrutura).

Primeiros resultados – máquina local

Continue e faça o seguinte

 construção do docker. -t node-app 
 docker run -p 8080: 8080 node-app

Então, ao fazer isso, conseguimos criar um servidor virtualizado dentro do contêiner docker … Para executá-lo em qualquer lugar, você precisará do docker na máquina. Esta é, basicamente, a única coisa que você precisa para executar rapidamente várias instâncias do mesmo servidor.

Neste ponto você é agnóstico da plataforma, você pode executar seu código NodeJS em qualquer lugar no sistema que suporte docker. Você pode criar docker e executar seu código em qualquer servidor agora. Esta é, é claro, a solução não completa … e não é fácil de automatizar também.

Tornando-o disponível para implantação

Quando você está construindo algo, parte lógica disso é implantá-lo em algum lugar (seu laptop não conta). O que faremos é construir a imagem do Docker e depois empurrá-lo para o repositório de contêiner para uso posterior.

O que você precisa fazer é criar um repositório de contêiner, nomeá-lo o que quiser (eu assumirei que você chamou de nó de teste ) e empurre seu servidor em contêiner como uma versão mais recente lá. Aqui estão as etapas para configurar isso na máquina local ou de construção:

  1. O primeiro comando obtém o comando ECR login e o executa imediatamente. Então, aqui, a AWS decidiu buscar uma abordagem realmente interessante para a autenticação – você executa um comando no cli e, como resultado, você começa a executar comandos para autenticar a ECR … para que você possa fazer isso, seu sistema deve ser autenticado na AWS já.
  2. Construir
  3. Marcar como aws_account_id> .dkr.ecr.< region> .amazonaws.com / <ecr_repo>

4. Pressione para repo

 aws ecr get-login - no-include-email - região <your_region> | / bin / bash
 docker build -t node-test.
tag de docker node-test < aws_account_id> .dkr.ecr.< region> .amazonaws.com / node-test
 docker push <your ecr url>: mais recente

Configuração da nuvem

Eu intencionalmente deixei de excluir o provisionamento para este artigo para orientá-lo verdadeiramente pelo básico.

Uma vez que estamos falando de ter o máximo possível de potencial em uma infraestrutura sem ter que fazer muito trabalho (especialmente configurar servidores privados e tal), é lógico ir para a solução da nuvem.

Esta solução é, em algum momento, descrevendo o uso da nuvem de cálculo Elástico AWS para implantar seu código e algumas outras coisas da AWS para segmentos adicionais da solução, mas eu sugiro fortemente que considerem outras opções também.

Configuração do servidor (VM) – o que o EC2 precisa

Criar instância EC2 (vou continuar e agir como se você tenha criado o ubuntu one). Baixe o arquivo .pem (para obter acesso ssh).

Faça o login para EC2 que você criou usando seu arquivo pem (nomeie access.pem e coloque-o dentro do repo, e gitignore, é claro). Você também precisa dar permissões adequadas, sobre o qual você será notificado em algum momento

 Chmod 400 access.pem 
 ssh -i access.pem ubuntu @ <instance_url / ip>

quando dentro , você precisa ter certeza de que ele tem duas coisas instaladas – Docker e AWS cli :

 sudo su
 apt-get install docker.io awscli

Crie também ~ / .aws / credentials com conteúdo:

 [padrão] 
 aws_access_key_id = <sua identificação da chave aws> 
 aws_secret_access_key = <sua chave aws>

Essa é a base disso – agora todas as dependências estão em e podemos ter tantos exemplos dessa VM como precisamos. É uma boa prática tornar sua plataforma de código agnóstica, VM deve ser o mais simples possível – shell que executa seu código de virtualização +. Há, no caso de lidar com uma única máquina, algum provisionamento de doemon de serviço a ser feito para alcançar um alto nível de automação, pelo bem deste guia, vamos fazê-lo manualmente.

Systemd – núcleo da sua configuração vm

Para que a configuração seja boa o suficiente, as VM criadas precisam ser conchas simples com o mínimo de dependências e acopladas de forma livre ao sistema de compilação.

Para este efeito, podemos criar deamon systemd para começar o nosso roteiro (ou servidor) no início do sistema, o que significa que recém-provisionado servidor ou servidor reiniciado vai fazer a mesma coisa quando se inicia:

  • Puxe a imagem docker do repositório docker
  • Execute nova imagem do docker

Além disso, para o propósito deste artigo, já que eu vou orientá-lo a implementar isso no AWS, ele precisa se autenticar no repositório de contêiner elástico AWS (ECR) para poder tirar imagens do docker dele.

Aqui está como fazê-lo:

Vamos chamá-lo de nó-js, isso significa que devemos criar o arquivo /etc/systemd/system/node-js.service com o seguinte conteúdo:

 [Unidade] 
 Descrição = serviço Docker NodeJS 
 Requer = docker.service 
 Depois = syslog.target
 [Serviço] 
 StandardOutput = syslog + console 
 # Muda killmode de "controle-grupo" para "nenhum" para permitir Docker remover 
 # trabalho corretamente. 
 KillMode = nenhum
 #EnvironmentFile = - / opt / svc / driver-portal / systemd.env
 # Pré-iniciar e começar 
 ## As diretivas com "= -" podem falhar sem consequências 
 ExecStartPre = / bin / sh -c '/ usr / bin / aws ecr get-login --region us-east-1 | / bin / bash ' 
 ExecStartPre = - / usr / bin / docker kill nodejs-server 
 ExecStartPre = - / usr / bin / docker rm nodejs-server 
 ExecStartPre = / usr / bin / docker puxa <your ecr repo>: mais recente 
 ExecStart = / usr / bin / docker run --log-driver = awslogs --log-opt awslogs-region = eu-central-1 --log-opt awslogs-group = nodejs --log-opt awslogs-stream = servidor  
 --name nodejs-server <your ecr repo>: mais recente
 # Pare 
 ExecStop = / usr / bin / docker stop nodejs-server
 [Instalar] 
 WantedBy = multiusuário.target

Como você pode ver, além da configuração básica do sistema, existem três coisas distintas que estamos fazendo aqui:

  • Autenticar a AWS ECR – para este IAM O papel da instância EC2 deve permitir o uso de ECR
  • Parar e limpar o espaço do docker (se livrar da instância antiga se houver).
  • Tirando a versão mais recente da imagem docker e executando-a

Bônus – registro

Como você pode ver, há uma parte adicional que incluí na imagem do docker em execução: —-log-driver=awslogs --log-opt awslogs-region=eu-central-1 --log-opt awslogs-group=nodejs --log-opt awslogs-stream=server , você precisa disso para fins de registro e eu o recomendo, mas esteja ciente de que este é o primeiro produto da nuvem (neste caso AWS) que mudará se você decidir usar diferentes soluções em nuvem ou até mesmo abordagem de log.

Esta é parte que garante que todos os logs da instância do Docker vão para o AWS CloudWatch, isso também significa que você precisará de autenticação adicional para o serviço docker na máquina virtual (sim, papel IAM … não é suficiente, por motivos)

Para o serviço Docker na VM ter autenticação em aws, crie: /etc/systemd/system/docker.service.d/aws-credentials.conf

 [Serviço]
 Ambiente = "AWS_ACCESS_KEY_ID = <your_aws_access_key_id>"
 Ambiente = "AWS_SECRET_ACCESS_KEY = <your_aws_secret_access_key>"

Preste atenção que esta é uma autenticação específica, não para o processo Docker / recipiente / imagem em si (que executa o código que pode usar AWS api através de autenticação local config) ou VM (que faz logon na ECR para puxar a imagem docker), mas para o serviço Docker que executa todas as virtualizações. Isso é para que possamos, por exemplo, transmitir todos os logs de várias instâncias do docker para o CloudWatch. Por que precisamos disso? Estou supondo que a Amazon deixou muitas pessoas assumirem o manto do criador padrão de segurança.

Depois de adicionar isso, basta ir e adicionar o grupo de log chamado nodejs para o CloudWatch. Quando suas instâncias forem iniciadas, você poderá encontrar seus logs lá.

A capacidade CI / CD

A configuração Systemd descrita nesta seção é um grande passo em direção a algo que cada novo projeto precisa – capacidade de integração / entrega contínua.

Eu outras palavras – seu fluxo de trabalho no início, como uma equipe de um homem (ou equipe de pessoas múltiplas, mas sem servidor de CI) seria:

  • Acabar recurso
  • Teste localmente no Docker
  • Building Docker e pressionando para ECR
  • Sshing na máquina remota e no serviço de reinício que executa suas coisas.

Como isso não é ideal, você provavelmente vai querer uma solução usando algum CI. Apenas descreverei etapas que tratam da entrega do código:

  • Código passa material pré-compilado (linters, testes unitários, etc.)
  • A imagem Docker é construída
  • O sistema empurra a imagem construída para o repositório de contêiner (ECR no nosso caso, mas você pode ir com qualquer coisa)
  • Ao executar o comando SSH remoto para reiniciar o serviço no servidor que executa o seu código, o CI desencadeia o sistema que baixa a imagem do docker, remove qualquer versão anterior que possa estar lá e executa a imagem do docker.

Mais para frente

Lá está – Capacidade CI usando instância EC2 única, docker, alguma magia linux e ECR. Há alguns caminhos lógicos futuros para explorar para melhorar isso:

  • Use a ferramenta CI – Jenkins ou GoCD devem se integrar facilmente neste fluxo, criando imagens docker e empurrando-as para ECR e para implantação, reiniciando remotamente systemd no EC2
  • Olhe para a escalabilidade – isso, em alguns casos, significa remover systemd dependendo do que você usa (swer de docker, kubernetes, mesos …)
  • Use ferramenta de provisionamento – Ansible, marionete, chef ….
  • SSL – você precisa de balanceador de carga elástico na frente do seu

Posso escrever sobre algumas dessas coisas no futuro, mas, próximo passo – executando e automatizando tarefas.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *