Como visualizar o histórico de eventos da instalação do Docker

Publicados: 2022-08-11

Logotipo do Docker

O Docker Engine registra um evento sempre que ações significativas são tomadas pelo daemon. Você pode acessar o log de eventos para identificar quando uma ação ocorreu e acompanhar as alterações nos objetos ao longo do tempo.

Neste artigo, explicaremos o que é capturado como eventos e quando você pode querer visualizá-los. Em seguida, mostraremos como monitorar eventos em tempo real usando a CLI do Docker e a API REST.

O que são eventos do Docker?

Os eventos do Docker descrevem as atividades realizadas pelo seu daemon do Docker. A maioria das interações com objetos, como contêineres, imagens, volumes e redes, registra um evento, criando um log que você pode usar para inspecionar alterações anteriores.

Existem muitos tipos diferentes de eventos que identificam alterações específicas em seu ambiente:

  • Criando e removendo contêineres
  • Status de verificação de integridade do contêiner
  • Comandos executados dentro de contêineres com docker exec
  • Puxando e empurrando imagens
  • Criando, destruindo, montando e desmontando volumes
  • Habilitando e desabilitando plugins do daemon do Docker

Você pode ver a lista completa na documentação do Docker.

Cada evento registrado inclui um carimbo de data/hora e o ID do objeto afetado. Você pode usar essas informações para montar um histórico de alterações em seu ambiente, observando ou não os acionadores originais.

Os eventos armazenados também podem ajudar a diagnosticar problemas como falhas inesperadas de contêiner. A visualização do log permite identificar a hora exata em que um contêiner parou, fornecendo um ponto de dados que você pode correlacionar com seus outros logs. Os eventos podem estabelecer quando as verificações de integridade de um contêiner começaram a falhar, reduzindo o período de interesse quando você precisa inspecionar serviços externos para determinar a causa raiz de um problema.

Transmissão de eventos do Docker com a CLI do Docker

O comando da CLI docker events transmite eventos do seu daemon do Docker para a janela do terminal. Os eventos aparecerão em tempo real até que você encerre o processo pressionando a combinação de teclado Ctrl+C.

Executar o comando sem argumentos não mostrará nenhuma saída para começar. Somente a nova atividade é exibida para que a saída permaneça vazia até que ocorra um evento. Você pode provocar um iniciando um novo contêiner em um shell diferente:

 $ docker run --rm hello-world

Vários eventos agora devem aparecer na janela do terminal que está executando o comando docker events :

 2022-05-31T15:20:00.267970018+01:00 imagem pull hello-world:latest (name=hello-world)
2022-05-31T15:20:00.347054862+01:00 container cria 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (imagem=hello-world, name=nifty_morse)
2022-05-31T15:20:00.347805277+01:00 anexo de contêiner 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (imagem=hello-world, name=nifty_morse)
2022-05-31T15:20:00.621070053+01:00 container start 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (imagem=hello-world, name=nifty_morse)
...

Cada evento é exibido em sua própria linha. O carimbo de data/hora do evento é exibido primeiro, seguido pelo tipo de objeto afetado (como image ou container ) e, em seguida, a ação que foi executada (como create , attach e start ). O restante da mensagem contém metadados úteis sobre o objeto. O exemplo acima revela que a imagem hello-world:latest foi extraída e um contêiner criado a partir dela.

Saída de formatação

A lista de eventos brutos geralmente é difícil de manejar. Você pode reformatar a saída usando o sinalizador --format que aceita uma string de modelo Go:

 $ docker events --format '{{ .Time }} {{ .Action }} {{ .Type}} {{ .ID }}'

A execução deste exemplo produzirá uma saída semelhante a esta:

 1654006800 puxar imagem hello-world:latest
1654006800 criar contêiner 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 anexar recipiente 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
1654006800 iniciar o contêiner 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378

Você pode obter eventos representados como objetos JSON usando {{ json . }} {{ json . }} como sua string de modelo:

 $ docker events --format '{{ json . }}' | jq
{
  "status": "criar",
  "id": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
  "from": "olá mundo",
  "Tipo": "contêiner",
  "Ação": "criar",
  "Ator": {
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    "Atributos": {
      "imagem": "olá mundo",
      "name": "nifty_morse"
    }
  },
  "escopo": "local",
  "hora": 1654006800,
  "timeNano": 1654006800347054800
}

Aqui, o JSON bruto está sendo passado pelo jq , então é bem impresso no seu terminal. Isso torna as informações mais fáceis de digitalizar.

Ao criar strings de formato personalizado, você pode usar as propriedades na saída JSON como referência para espaços reservados compatíveis. Na maioria dos casos, você precisará colocar em maiúscula a primeira letra de cada propriedade, como time to {{ .Time }} .

Filtrando eventos

O log de eventos de um daemon do Docker ocupado pode se tornar rapidamente barulhento. Você pode restringir os eventos a uma ação, objeto ou tipo de objeto específico com o sinalizador --filter :

  • docker events --filter type=container – Obtenha todos os eventos relacionados a contêineres.
  • docker events --filter event=create – Obter eventos de criação de contêiner.
  • docker events --filter container=demo-container – Obtenha todos os eventos salvos para o contêiner chamado demo-container (você pode fazer referência ao ID ou nome do contêiner).

Além do container , você pode filtrar por todos os nomes de tipo de objeto suportados, como image , network e volume .

Vários filtros são suportados quando você repete o sinalizador --filter . Filtros distintos são interpretados como condições AND lógicas; vários usos do mesmo filtro tornam-se cláusulas OR . Aqui está um exemplo que mostra o evento create para os app-container e api-container container:

 $ eventos docker \
    --filter container=app-container
    --filter container=api-container
    --filtro evento=criar

Acessando eventos históricos

docker events são padronizados para mostrar apenas eventos armazenados desde que o comando está em execução. Você pode incluir eventos históricos adicionando o sinalizador --since . Isso aceita uma expressão de tempo legível por humanos ou um carimbo de data/hora absoluto:

 $ eventos docker --desde 1h
$ eventos docker --desde '2021-05-01T16:00:00'

Os eventos registrados após o horário determinado serão mostrados imediatamente em seu terminal. Novos eventos continuarão a aparecer em tempo real à medida que forem registrados.

Você pode excluir eventos após um determinado horário com o sinalizador --until . Funciona de maneira semelhante a --since . O uso de --until desabilitará o streaming em tempo real de novos eventos porque eles ficarão fora do prazo solicitado.

Streaming de eventos do Docker da API REST do Daemon

Outra maneira de acessar eventos armazenados é por meio da API REST do daemon do Docker. Você pode usar o ponto de extremidade /events para transmitir eventos em tempo real depois de habilitar a API em seu host do Docker. Os eventos serão retornados no formato JSON:

 $ curl http://127.0.0.1:2375/v1.41/events
{
  "Tipo": "contêiner",
  "Ação": "criar",
  "Ator": {
    "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378",
    "Atributos": {
      "imagem": "olá mundo",
      "name": "nifty_morse"
    }
  },
  "escopo": "local",
  "hora": 1654006800,
  "timeNano": 1654006800347054800
}

O endpoint da API oferece suporte aos parâmetros filter , since e until que têm os mesmos comportamentos que suas contrapartes da CLI. Veja como recuperar todos os eventos de criação de contêiner registrados na última hora:

 $ curl http://127.0.0.1:2375/v1.41/events?since=1h&filters={'type':'container','action':'create'}

Enviando eventos para um serviço externo

O Docker não possui uma maneira interna de enviar eventos para um serviço externo. Isso pode ser útil se você quiser que todas as suas criações de contêiner sejam registradas em uma plataforma de monitoramento ou auditoria existente.

Você pode configurar sua própria solução criando um serviço de sistema que executa continuamente docker events . Ele deve enviar cada nova linha de saída para seu sistema externo.

Primeiro, escreva um script Bash que implemente a funcionalidade que você precisa:

 #!/bin/bash
eventos docker --format '{{ .Time }} {{ .Action }} {{ .Type }} {{ .ID }}' | durante a leitura do evento
Faz
    ondulação \
        -X POST \
        -H "Tipo de conteúdo: aplicativo/json" \
        -d '{"evento": "$evento"}' \
        https://example.com/events
feito

Agora crie uma nova unidade de serviço systemd em /etc/systemd/system/docker-events.service :

 [Unidade]
Description=Serviço de monitoramento de eventos do Docker personalizado

[Serviço]
Tipo = bifurcação
ExecStart=/usr/local/bin/docker-events.sh

[Instalar]
WantedBy=multi-usuário.destino

Por fim, recarregue o systemd para carregar seu serviço, inicie e ative a unidade:

 $ sudo systemctl daemon-reload
$ sudo systemctl start docker-events
$ sudo systemctl enable docker-events

Seu serviço agora transmitirá cada novo evento para sua plataforma de monitoramento. Habilitar o serviço configura-o para iniciar automaticamente toda vez que seu host for reinicializado.

Resumo

Os eventos do Docker são criados sempre que o daemon modifica objetos em seu ambiente. O streaming do log de eventos permite monitorar a atividade do daemon em tempo real. Isso pode ajudá-lo a depurar problemas, auditar alterações e garantir a conformidade.

Como os eventos são recuperados diretamente do servidor Docker, eles não devem ser considerados se você precisar recuperar informações no futuro. Apenas 1.000 entradas são retidas continuamente e você não pode acessar eventos por meio do sistema de arquivos do seu host Docker. O mecanismo é mais adequado para tarefas ad-hoc rápidas em que você procura informações específicas relacionadas a uma atividade recente. Para retenção de longo prazo, você deve usar seu próprio serviço de sistema para enviar eventos para um repositório externo.