[ad_1]
Docker é uma tecnologia para empacotar componentes de sua pilha como contêineres isolados. É prática comum executar cada um de seus processos em seu próprio contêiner, criando uma divisão clara entre os componentes. Isso melhora a modularidade e permite acessar os benefícios de escalabilidade da conteinerização.
Ainda pode haver situações em que você deseja executar vários serviços em um único contêiner. Embora isso não seja natural para o ecossistema do Docker, mostraremos algumas abordagens diferentes que você pode usar para criar contêineres com mais de um processo de longa duração.
Identificando o problema
Os contêineres do Docker executam um único processo em primeiro plano. Isso é definido pela imagem ENTRYPOINT
S CMD
instruções. ENTRYPOINT
definido dentro de uma imagem Dockerfile
tempo CMD
pode ser substituído ao criar contêineres. Os contêineres param automaticamente quando o processo em primeiro plano é encerrado.
Você pode iniciar outros processos a partir do CMD
mas o contêiner continuará em execução enquanto o processo original em primeiro plano estiver ativo. Manter o contêiner operacional durante a vida útil combinada de dois serviços independentes não é diretamente possível usando o ENTRYPOINT/CMD
mecanismo.
Envolvendo vários processos em um ponto de entrada
Os scripts wrapper são a solução mais simples para o problema. Você pode escrever um script que inicia todos os seus processos e espera que eles terminem. Configurando o script como seu Docker ENTRYPOINT
irá executá-lo como o processo de primeiro plano do contêiner, mantendo o contêiner em execução até que um dos scripts encapsulados seja concluído.
#!/bin/bash /opt/first-process & /opt/second-process & wait -n exit $?
Este script inicia o /opt/first-process
S /opt/second-process
binários dentro do contêiner. O uso de &
permite que o script continue sem esperar que cada processo termine. wait
é usado para suspender o script até que um dos processos seja concluído. O script sai com o código de status emitido pelo script encerrado.
Esse modelo resulta no contêiner executando tanto first-process
S second-process
até que um deles saia. Nesse ponto, o contêiner será interrompido, mesmo que o outro processo ainda esteja em execução.
Para usar este script, modifique sua imagem do Docker ENTRYPOINT
S CMD
para torná-lo o processo de primeiro plano do contêiner:
ENTRYPOINT ["/bin/sh"] CMD ["./path/to/script.sh"]
a --init
opção de contêiner
Um desafio com o gerenciamento de processos de contêineres é a limpeza eficaz à medida que eles saem. O Docker executa seu CMD
como processo ID 1, tornando-o responsável por manipular sinais e matar zumbis. Se seu script não tiver esses recursos, você poderá acabar com processos filho órfãos que persistem dentro de seu contêiner.
a docker run
O comando tem um --init
sinalizador que modifica o ponto de entrada a ser usado tini
como PID 1. Esta é uma implementação mínima do processo de inicialização que executa seu CMD
lida com encaminhamento de sinal e coleta contínua de zumbis.
vale a pena usar --init
se você espera gerar muitos processos e não deseja lidar manualmente com a limpeza. Tini é um sabor inicial leve projetado para recipientes. É muito menor do que alternativas completas como systemd
S upstart
.
Usando um gerenciador de processos dedicado
O script manual torna-se rapidamente abaixo do ideal quando você tem muitos processos para gerenciar. Adotar um gerenciador de processos é outra maneira de executar vários serviços em seus contêineres do Docker. O gerenciador de processos se torna seu ENTRYPOINT
e você tem a responsabilidade de iniciar, manter e limpar após seus processos de trabalho.
Existem várias opções disponíveis ao implementar essa abordagem. supervisord
é uma opção popular que é facilmente configurada através de um /etc/supervisor/conf.d/supervisord.conf
procedimentos:
[program:apache2] command=/usr/sbin/apache2 -DFOREGROUND [program:mysqld] command=/usr/sbin/mysqld_safe
Este arquivo de configuração configura supervisord
para iniciar o Apache e o MySQL. Para usá-lo em um contêiner do Docker, adicione todos os pacotes necessários à sua imagem e copie seu supervisord
arquivo de configuração no local correto. Estabelecer supervisord
Como a imagem CMD
para executá-lo automaticamente quando os contêineres forem iniciados.
FROM ubuntu:latest RUN apt-get install -y apache2 mysql-server supervisor COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf ENTRYPOINT ["/bin/sh"] CMD ["/usr/bin/supervisord"]
Porque supervisord
funciona continuamente, não é possível parar o container quando um de seus processos monitorados termina. Uma opção alternativa é s6-overlay
que tem essa habilidade. Ele usa um modelo de serviço declarativo no qual você coloca scripts de serviço diretamente em /etc/services.d
:
# Add s6-overlay to your image ADD https://github.com/just-containers/s6-overlay/releases/download/v3.1.0.0/s6-overlay-noarch.tar.xz /tmp RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz RUN printf "#!/bin/shn/usr/sbin/apache2 -DFOREGROUND" > /etc/services.d/first-service/run RUN chmod +x /etc/services.d/first-service/run # Use s6-overlay as your image's entrypoint ENTRYPOINT ["/init"]
Você pode adicionar um executável finish
script em seus diretórios de serviço para lidar com a interrupção do contêiner com docker stop
. s6-overlay
executará automaticamente esses scripts quando seu processo receber um TERM
sinal devido a stop
domínio.
Os scripts de finalização recebem o código de saída do seu serviço como o primeiro argumento. O código é definido como 256 quando o serviço é encerrado devido a um sinal perdido. O script precisa escrever o código de saída final para /run/s6-linux-init-container-results/exitcode
; s6-overlay lê esse arquivo e sai com o valor que ele contém, fazendo com que esse código seja usado como código de parada do seu contêiner.
#!/bin/sh echo "$1" > /run/s6-linux-init-container-results/exitcode
Quando você deve executar vários processos em um contêiner?
Essa técnica é melhor usada com processos fortemente acoplados que não podem ser separados para serem executados como contêineres separados. Você pode ter um programa que depende de um utilitário auxiliar em segundo plano ou um aplicativo monolítico que faz seu próprio gerenciamento de processos individuais. As técnicas mostradas acima podem ajudá-lo a conter esses tipos de software.
A execução de vários processos em um contêiner ainda deve ser evitada sempre que possível. Aderir a um único processo em primeiro plano maximiza o isolamento, evita que os componentes interfiram uns nos outros e melhora sua capacidade de depurar e testar peças específicas. Você pode dimensionar componentes individualmente usando orquestradores de contêiner, oferecendo a flexibilidade de executar mais instâncias de seus processos com maior uso de recursos.
conclusão
Os contêineres geralmente têm um processo em primeiro plano e são executados enquanto estiverem ativos. Esse modelo se alinha às práticas recomendadas de conteinerização e permite que você obtenha o máximo de benefícios da tecnologia.
Em algumas situações, você pode precisar que vários processos sejam executados em um contêiner. Como todas as imagens têm um único ponto de entrada, você deve escrever um script wrapper ou incluir um gerenciador de processos que assuma a responsabilidade de iniciar os binários de destino.
Os gerenciadores de processos oferecem tudo o que você precisa, mas sobrecarregam suas imagens com pacotes e configurações adicionais. Os scripts de contêiner são mais simples, mas podem precisar ser combinados com scripts do Docker. --init
flag para evitar a proliferação de processos zumbis.
[ad_2]