A maneira correta de manter o contêiner de docker iniciado quando usado para tarefas periódicas


41

Eu tenho contêiner de docker com software instalado e configurado.

Não existe nenhum programa que deva ser iniciado / executado o tempo todo.

O que eu quero - sua capacidade de iniciar algum comando, dependendo de eventos externos. gostar:

docker exec mysupercont /path/to/mycommand -bla -for

e

docker exec mysupercont /path/to/myothercommand 

Mas "exec" é impossível quando o contêiner está parado, e também esse contêiner contém alguns dados "funcionais", que são usados ​​para esses comandos, então não posso usar

docker run ...

sempre, porque recriar contêiner a partir da imagem e destruir meus dados.

Qual é a maneira "certa" e "melhor" de manter esse contêiner em funcionamento? Qual comando posso iniciar por dentro?


Esta é uma pergunta muito bem explicada. Veja outro post semelhante aqui .
Grant Li

1
docker run -d --name=name container tail -f /dev/null
steampowered

Respostas:


46

Você não precisa executar todas as vezes docker run.

docker run é na verdade uma sequência de dois comandos: "create" e "start".

Ao executar o contêiner, você deve especificar o " -it":

-i, --interactive = false Mantenha o STDIN aberto mesmo se não estiver conectado
-t, --tty = false Aloque um pseudo-TTY

Exemplo:

docker run -it debian:stable bash

Depois que o trabalho foi concluído, o comando especificado na inicialização (no meu exemplo bash). Por exemplo, você executa a "saída". O contêiner para:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Agora você pode iniciá-lo novamente

docker start 1329c99a831b

O contêiner é iniciado e novamente executa o comando "bash".
Conecte-se a esta sessão "bash" com o comando

docker attach 1329c99a831b

Resumindo : você precisa entender a diferença entre o recipiente rune start.
Além disso, consulte a documentação para o papel dos parâmetros " -i t" e " -d" para o "Executar"


1
aha, eu entendo isso. A pergunta era: não tenho nada para executar dentro do contêiner, mas preciso mantê-lo no estado "run". Portanto, sua resposta é - use o bash para manter o contêiner no estado de execução?
Korjavin Ivan 27/01

Sim. O processo especificado em tempo de execução deve estar em execução no contêiner continuado a funcionar. O exemplo mais simples é o bash. Talvez você seja a maneira mais fácil de iniciar o contêiner com o "-d" e conectar-se a ele conforme necessário usando o docker attach ID. Saia desta sessão sem terminar o bash, você pode usarCTRL-p CTRL-q
MSemochkin

Processo que você especificar durante do recipiente prazo recebe o PID 1. Assim, o recipiente simplesmente não pode funcionar sem ele ☺
MSemochkin

Minha experiência com iniciar e anexar (ou iniciar com -ai) é que a edição rápida e interativa da sua linha de comando não é exibida. Por exemplo, o tty não está renderizando ou ecoando.
dlamblin

1
Isso é bacana. Observe que se você deseja iniciar o contêiner em segundo plano sem precisar iniciá-lo manualmente novamente (por exemplo, se estiver executando um serviço da Web), use os parâmetros '-itd' e CTRL-p CTRL-q para desconectar sem parar o recipiente.
taranaki

6

Todo esse negócio de saber se você pode ou não iniciar um contêiner parado, depende de como o contêiner foi originalmente criado, ou seja, executado. Se você executou um comando que terminou ou saiu de um comando interativo, por exemplo, bash, não pode iniciar, reiniciar ou executar o contêiner parado. Tudo o que você pode fazer é removê-lo. É lixo.

Mas o último comentário de taranaki, use '-itd', parece ser o que o docker ordenou.

O contêiner continua em execução, e você pode executar o que quiser e pode parar, iniciar ou reiniciar o contêiner. Obviamente, esta é apenas uma descoberta preliminar baseada na imagem alpina. Observe que, se você anexar ao contêiner, ele será interrompido quando você sair, mas você poderá iniciá-lo novamente.


3
+1 "parece ser o que a janela de encaixe ordenou" :-)
Matt Alexander

5

Como você mencionou tarefas periódicas e provavelmente está usando algo como cron devido à maneira que deseja usar docker exec, eu tenho apenas o remédio para você. Pelo menos eu acabei fazendo algo assim.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Corra com o habitual docker run -d ....(eu usei docker-compose)

  3. Configure as máquinas host crontab, por exemplo:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    

Acho essa solução agradável quando confiamos no crontab antigo e comprovado em um ambiente linux bastante padrão, enquanto o Docker lida com os deps e variáveis ​​de ambiente mais exóticos da sua lógica de negócios. Você também pode definir alguns limites se suas tarefas periódicas ficarem paralisadas e tiverem vazamentos de memória ou o que for.


0

A cauda ainda causa algumas operações de arquivo de tempos em tempos.

Aqui está a minha solução para dormir para sempre, sem efeitos colaterais.

# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!

Como funciona

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped

1
difícil entender o que está fazendo. por que não apenas dormir 3650d
Pieter

1
Você está certo, o sono provavelmente funcionaria tão bem quanto a minha solução, no entanto o tempo limite do sono acabará :-D PS: Acrescentarei alguns comentários para facilitar a compreensão da solução.
qoomon 23/08
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.