Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker - Qual a melhor maneira para se trabalhar #53

Closed
allbarbos opened this issue Apr 5, 2018 · 7 comments
Closed

Docker - Qual a melhor maneira para se trabalhar #53

allbarbos opened this issue Apr 5, 2018 · 7 comments

Comments

@allbarbos
Copy link

Galera, tenho um server com várias aplicações e estamos avaliando a migração para containers, no entanto caímos em uma discussão de como implementar os containers e chegamos em 2 casos:

1 - Um container com toda stack necessária pra rodar as aplicações - Ex: Container Nginx, PHP, App1, App2, App3, ..., AppN
2 - Um container para cada coisa isolada Ex: Container Nginx, Container PHP, Container App1, Container App3, ..., Container AppN e todos eles se comunicam entre si

Qual seria a forma mais correta? Ou existe uma forma melhor?

@thiamsantos
Copy link

A boa prática é colocar cada serviço em um container separado.

It is generally recommended that you separate areas of concern by using one service per container.

https://docs.docker.com/config/containers/multi-service_container/

Each container should have only one concern. Decoupling applications into multiple containers makes it much easier to scale horizontally and reuse containers.

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#each-container-should-have-only-one-concern

@wmartins
Copy link

wmartins commented Apr 5, 2018

A forma "correta" ou "melhor" vai depender muito do teu cenário e dos trade-offs de cada uma dessas escolhas. Vou te comentar um pouco da minha experiência com isso (trabalho com Docker há uns anos já, e passei por um monte de situações chatas).

Se tu separar um container para cada coisa, isso te permite escalar eles separadamente. Portanto, se tu precisar ter mais instâncias de Nginx, tu pode aumentar o número de replicas só do Nginx, não precisando subir todos os serviços.
Além disso, o versionamento me parece ser mais fácil assim, pois as coisas "vivem separadas", com isso, uma alteração no Nginx não impacta nas outras coisas. Me parece até mais fácil de debugar e etc.

Entretanto, separar vem com um "preço". É mais difícil de gerenciar isso tanto em ambiente de desenvolvimento quanto em produção. Alguns exemplos de coisas que talvez tu tenha que fazer:

  • Introdução de um Load Balancer / Service Discovery para balancear e reconhecer as N instâncias das tuas aplicações (normalmente, usando uma ferramenta de orquestração - ex: Swarm / Kubernetes - tu "ganha" isso de graça)
  • Introdução de uma ferramenta para visualização / detecção / tratamento de falhas na comunicação entre os serviços. Por exemplo, uma das instâncias não está respondendo corretamente, o ideal é retentar e, eventualmente, reiniciar/realocar essa instância (keywords: Distributed Tracing, Circuit Breaker)
  • Gerenciamento de versão mais "esperto". Ex: a App1 (v1.0.0) só funciona bem junto com a App2 (v1.2.x). Portanto, tem que se ter uma "cultura" para que os projetos evoluam "sozinhos", mas sem quebrar nada, senão tu acaba criando um Monolito Distribuído

Boa parte dessas coisas não são necessárias de serem feitas, mas são coisas que garantem o sucesso de utilizar serviços separados. Tem algumas tools hoje em dia que te facilitam muita coisa nesse sentido, vou deixar os links delas aqui:

  • Linkerd - Resilient service mesh for cloud native apps
  • Kubernetes - Production-Grade Container Orchestration
  • Istio - An open platform to connect, manage, and secure microservices
  • Consul - Service Discovery and Configuration Made Easy

Acho que é um investimento que normalmente vale, mas tem que ver se essas coisas fazem sentido pra ti e para o teu time. No fim das contas, se vocês escolherem separar só porque é uma boa prática, pode acabar que isso fique difícil de gerenciar sem as coisas que comentei acima. E aí, provavelmente ter deixado tudo junto teria sido uma ideia melhor. :)

É tudo bom senso e tomar uma "decisão informada". Se possível, façam alguns testes com as duas formas e vejam como fica, tentando simular o "fluxo real" do trabalho de vocês.

Se precisar trocar mais uma ideia sobre, estamos aí!

@allbarbos
Copy link
Author

@thiamsantos obrigado pelos links, pelo pouco que sei e já vi o pessoal falar é realmente nessa linha de deixar tudo separado.

@wmartins valeu por compartilhar essa experiência, ajudou bastante! Atualmente nós implementamos uma estrutura com um container que possui: Nginx, PHP5, PHP7 e várias aplicações que utilizam WordPress. No entanto como essas aplicações terão muitos acessos, minha maior preocupação seria um cenário em que dê merda em uma delas e haja a necessidade de matar e subir um novo container, nesse tempo derrubaria todas as outras aplicações desse container.
Cheguei a dar uma olhada por cima no Kubernetes pra fazer a parte de gerenciamento, achei bem interessante, indo na linha de adotá-lo seria correto deixar os containers separados então?
Outra dúvida é no caso da separação, por exemplo, tenho 1 Nginx que 30 aplicações que o utilizam, seria necessário alocar um IP fixo para o Nginx e outros 30 IP fixo para as aplicações também?

@mahenrique94
Copy link

No meu antigo serviço fui responsável por refazer e configurar a nossa infra, estava tudo com tomcat e juntos, então resolvi realizar a migração para Docker utilizando o Swarm como osquestrador (ainda não vi necessidade de utilizar Kubernetes pois aumenta muito a complexidade para um mesmo resultado).

Lá eu separei uma aplicação para cada container e uma instância para cada tipo de serviço, por exemplo, MySQL, PHP, Java, Proxy, Jenkins, PostgresQL, etc... Assim se houver a necessidade de realizar uma escalabilidade a nível de hardware seria muito mais simples.

Ai dentro dos máquinas tinha um container com nginx realizando o proxy e distribuição para os demais containers e fora isso tinha um proxy principal que distribuia para as demais instâncias.

Tinha ficado excelente, nunca caia, nunca dava problema e tals.

@wmartins
Copy link

wmartins commented Apr 6, 2018

Só te respondendo.

Cheguei a dar uma olhada por cima no Kubernetes pra fazer a parte de gerenciamento, achei bem interessante, indo na linha de adotá-lo seria correto deixar os containers separados então?

Nesse cenário, faz mais sentido ir separado. Entretanto, é legal vocês fazerem alguns testes pra ver se o Kubernetes atende vocês.

Outra dúvida é no caso da separação, por exemplo, tenho 1 Nginx que 30 aplicações que o utilizam, seria necessário alocar um IP fixo para o Nginx e outros 30 IP fixo para as aplicações também?

Normalmente isso tu resolve utilizando Service Discovery/Load Balancer. Quando tu usa serviços que escalam independentemente, o ideal é que tu não use IPs hardcoded, quando possível. Justamente pois esse número pode aumentar/diminuir, ficando difícil gerenciar todos esses IPs. Portanto, é muito mais fácil simplesmente apontar para "http://services.app1" do que fazer alguma mágica com os IPs e etc.

Além disso, sobre a questão dos IPs "fixos", normalmente o que tu pode fazer é ter IPs fixos para os pontos de "entrada" para a tua aplicação. Por exemplo, digamos que tu tenha 10 réplicas de cada aplicação, tu não precisa ter 10 pontos de entrada. Tu pode ter 3, por exemplo, e fazer um round-robin com DNS.

Logo, quando o usuário acessar "http://my-application", esse endereço "my-application" vai fazer um round-robin pra 3 máquinas (192.168.1.{1, 2, 3}). Quando o request chegar em uma dessas máquinas, cairá no teu load balancer que então balanceará para as 10 réplicas.

Só lembrando que o Kubernetes, por exemplo, te permite gerenciar esse tipo de coisa de uma maneira bem fácil.

Espero que tenha ficado claro. :)

@carloshenriqueribeiro
Copy link

carloshenriqueribeiro commented Apr 10, 2018 via email

@mahenrique94
Copy link

@carloshenriqueribeiro eu gosto dessa prática, acho que cada container deve fazer apenas uma coisa, no seu caso, será responsável apenas por uma aplicação, com isso você tem inumeros ganhos de independência, deploy, escalabilidade, etc...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants