Eu tenho um cluster de nó único k3s em execução em uma máquina. Ainda não tenho nenhuma infraestrutura de registro configurada e deixaria isso como uma experiência de aprendizado futuro por enquanto.
Nesse k3s eu executo alguns cron jobs que criam logs para cada um dos trabalhos em um arquivo separado. Posso observá-los /var/log/containers/cron-job-*
na máquina host. Esses logs desaparecem após um determinado período de tempo (successfulJobsHistoryLimit: 3). Novas instâncias de trabalho criam novos arquivos de log.
Não consigo encontrar uma ferramenta simples que possa monitorar esse diretório de logs, de preferência com um padrão de nome de arquivo, e transmitir/juntar esses pequenos logs de trabalho em um único arquivo de log, incluindo novos arquivos que estão sendo criados. Não me importo se o nome do arquivo for perdido, só quero que as linhas de log terminem em um arquivo servindo como um arquivo de todas as execuções do trabalho.
O que eu considerei?
Eu poderia simplesmente adicionar um script para capturar esses arquivos e anexá-los a um arquivo de destino com um intervalo, mas teria que controlar quais arquivos já foram inseridos no caso de os trabalhos ficarem fora de sincronia ou o intervalo do cron mudar. Também gostaria de estender essa funcionalidade para pods de "longa execução" e, nesse caso, teria que começar a rastrear linhas atualizadas nos logs.
Todos os exemplos que encontrei tratam de rastreamento em tempo real na tela, o que não é o que eu preciso. Eu meio que preciso de múltiplas caudas em um arquivo de log de destino.
Alguma ideia? (Eu também aceitaria algum tipo de exemplo simples de gancho de registro do Kubernetes)
Responder1
Ofereço uma solução que agora escolhi para mim. Não é a resposta que eu procurava, mas uma que parece navegar com o fluxo. Ainda estou curioso para saber se isso poderia ser tratado por algum comando comum do Unix.
De qualquer forma, aqui está o que eu fiz:
A maneira comum parece usar uma ferramenta chamadaFluente, que permite coletar logs de várias fontes e transportá-los para qualquer lugar que você achar adequado - uma espécie de ETL para logs.
Optei por enviar os logs para o servidor syslog porque já tinha um em execução, mas você pode escolher qualquer um dos plugins de saída aqui:Plug-ins de saída. Há também um grande conjunto de plug-ins adicionais:Todos os plug-ins
Passo 1
Obtenha uma configuração do Fluentd que tenha o plugin remote_syslog instalado. Isso não vem com a imagem oficial do docker, mas você mesmo pode configurá-la.
FROM fluent/fluentd:v1.14.0-1.0
USER root
# https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog
RUN fluent-gem install fluent-plugin-remote_syslog
USER fluent
Crie a imagem e envie para o seu registro.
Passo 2
Em seguida, configure um manifesto de implantação do Fluentd com declarações de volume somente leitura para acessar os logs do pod. Os arquivos reais residem em /var/log/pods/* e /var/log/containers contém links simbólicos. Precisamos de arquivos reais. Esses logs são de propriedade do root na máquina host e o usuário fluente não terá acesso para lê-los. Precisamos definir alguns contextos de segurança. Para fazer as coisas funcionarem, usei o grupo raiz para o fsGroup. Sinta-se à vontade para se aprofundar e encontrar/comentar a solução mais ideal para esse aspecto de segurança.
apiVersion: apps/v1
kind: Deployment
...
spec:
...
spec:
securityContext:
fsGroup: 0
volumes:
- name: varlogpods-pv
persistentVolumeClaim:
claimName: pvc-var-log-pods
...
containers:
- name: fluentd
image: your/fluentd-image
Veja meu manifesto completo nesta essência:implantação fluente
etapa 3
Antes de implantar, você também precisa configurar fluent.conf
e descrever algumas regras lá.
O meu está configurado para corresponder a uma linha de log como esta:
2022-04-26T20:05:00.847016854+03:00 stderr F time="2022-04-26 17:05:00" level=info msg="processing 3 records ..."
Para mais informações sobre o plugin tail:cauda
<source>
@type tail
@id in_tail_container_logs
path "/var/log/pods/default_cron-*/*/*.log"
pos_file "/tmp/cron_.log.pos"
read_from_head true
tag cron
<parse>
@type regexp
expression /^(?<logtime>[^ ]*) .* level=(?<level>[^ ]*) msg="(?<message>[^"]*)"$/
time_key logtime
time_format %FT%T.%N%:z
</parse>
</source>
<match cron>
@type remote_syslog
host 172.16.3.10
port 514
protocol udp
severity info
program "fluentd"
hostname "k3sserver"
<buffer>
</buffer>
<format>
@type single_value
message_key message
</format>
</match>
Um atributo de configuração importante aqui é read_from_head true
o que lê os arquivos de log de cima. É necessário para este cenário, uma vez que os logs do pod estão girando, queremos que o Fluentd leia o log completo do pod, e não apenas algumas linhas de atualização no final. Para um cron job curto, o arquivo de log apenas aparece e o tail não relatará nenhuma linha inicial nele.
Passo 4
Mexa na configuração e tente, tente novamente. Não se esqueça de reiniciar sua implantação depois de atualizar a configuração no configMap.