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:
- 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á.
- Construir
- 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 dockernode-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.