Executando um serviço systemd uma vez por dia (em um cluster CoreOS)

1

Atualmente, tenho um cluster do CoreOS na AWS. O cluster executa vários contêineres, principalmente para aplicativos Rails. No entanto, um desses contêineres é um aplicativo puro em Ruby que processa muitos dados de APIs externas específicas.

Na verdade, o contêiner do Docker para esse aplicativo é executado todos os dias às 4h UTC.

myapp.service:

[Unit]
Description=MyApp service
Requires=docker.service

[Service]
ExecStart=/home/core/sc/myapp_start.sh
User=core

myapp.timer:

[Unit]
Description=MyApp Timer
Requires=docker.service

[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true

O script de shell executado pelo serviço pode ser resumido em:

/usr/bin/docker run --rm --name=myapp omg/myapp:$tag

Como o contêiner é implantado em um cluster via CircleCI, o contêiner pode estar em um dos servidores presentes no cluster. No entanto, se o servidor no qual o contêiner está em execução ficar sem memória devido a outro contêiner executando no mesmo servidor e levando a muita RAM, ou se não houver espaço livre disponível em disco, etc - o contêiner será interrompido e executado novamente outro servidor do cluster.

É meio problemático no contexto desse aplicativo Ruby, que deve ser executado apenas uma vez por dia e não ser executado novamente em caso de falha do servidor.

Nessa situação, como eu poderia proceder?

Obrigado.

    
por Mich 04.06.2015 / 05:32

1 resposta

0

Você precisa ensinar seu aplicativo a controlar sua própria execução usando um método que sobreviva a um reinício / movimento de contêiner (pode ser um arquivo em um sistema de arquivos persistente / compartilhado, alguma informação em um banco de dados, algum serviço / aplicativo externo de coordenação , etc - o que for conveniente para o seu contexto).

Ao reiniciar, se o aplicativo perceber que ele já foi executado no intervalo especificado, ele sairá sem fazer nada. pode ser possível até ensiná-lo a pegar e concluir o trabalho anteriormente inacabado, se necessário:)

Se não for possível fazer isso dentro do aplicativo, você poderá colocar o aplicativo em um wrapper personalizado e fazê-lo dentro do wrapper.

    
por 04.06.2015 / 15:26