Gerenciar relatórios agendados de hosts com cron

LinuxBeginner
Pratique Agora

Introdução

Um agendamento confiável exige mais evidências do que um resumo de play bem-sucedido. Você implantará um programa protegido de relatório para um usuário comum, gerenciará uma entrada cron nomeada estável, observará execuções naturais, atualizará sua fase e removerá uma entrada temporária separada. A verificação final observará uma nova execução do agendador, preservando a tarefa existente não relacionada.

Implantar um relatório de usuário comum e um agendamento nomeado

Nesta etapa, você implantará um programa de relatório fornecido e o agendará para o usuário automation nos dois hosts gerenciados.

Cron está instalado e seu daemon já está em execução como pré-requisito. Os nós não executam systemd. Cada crontab de automation também contém uma entrada keep-existing-report não relacionada; preserve-a. O módulo cron gerencia uma entrada nomeada estável em vez de substituir o crontab inteiro do usuário.

Entre no projeto e inspecione o programa fornecido no controlador:

cd /home/labex/project
cat files/host-report.sh

O programa acrescenta um timestamp UTC em segundos desde a época Unix, o nome real do host e um argumento de fase a um log gerenciado protegido. Umask 027 dá modo 0640 aos novos arquivos de log. Deixe o programa inalterado e permita que cron o execute naturalmente; invocá-lo manualmente não demonstraria o agendamento.

Defina a fase como entrada reutilizável:

cat > group_vars/all.yml <<'YAML'
report_phase: initial
YAML

Crie o playbook. Uma tarefa cron tem campos de minuto, hora, dia do mês, mês e dia da semana; um asterisco em cada campo executa uma vez por minuto. O name cria um marcador Ansible usado para atualizações posteriores, e user automation seleciona o crontab desse usuário. Become permite gerenciar o agendamento desse usuário nomeado e a propriedade explícita de arquivos; ele não faz o programa agendado executar como root.

cat > reporting.yml <<'YAML'
- name: Manage a scheduled ordinary-user host report
  hosts: all
  gather_facts: false
  become: true
  tasks:
    - name: Prepare the ordinary user's reporting directory
      ansible.builtin.file:
        path: /home/automation/reporting
        state: directory
        owner: automation
        group: automation
        mode: "0750"

    - name: Deploy the supplied report program
      ansible.builtin.copy:
        src: /home/labex/project/files/host-report.sh
        dest: /home/automation/reporting/host-report.sh
        owner: automation
        group: automation
        mode: "0750"

    - name: Keep the named report schedule present
      ansible.builtin.cron:
        name: ansible-host-report
        user: automation
        minute: "*"
        hour: "*"
        day: "*"
        month: "*"
        weekday: "*"
        job: "/home/automation/reporting/host-report.sh {{ report_phase }}"
YAML

Valide e aplique:

ansible-playbook reporting.yml --syntax-check
ansible-playbook reporting.yml

Inspecione os crontabs reais de automation. O comando executa com become para que possa nomear explicitamente a conta consultada:

ansible all -b -m ansible.builtin.command -a 'crontab -u automation -l'

Cada um deve conter um marcador ansible-host-report e o comando a cada minuto, além da entrada keep-existing-report inalterada. Uma linha no crontab, por si só, não comprova a execução.

Aguarde o primeiro disparo natural do agendador. timeout limita a espera a 90 segundos; o loop until do bash verifica a cada dois segundos se existe um log não vazio. O comando apenas lê o estado enquanto cron cria o log:

ansible all -m ansible.builtin.command -a "timeout 90 bash -c 'until test -s /home/automation/reporting/host-report.log; do sleep 2; done'"
ansible all -m ansible.builtin.command -a 'cat /home/automation/reporting/host-report.log'

Cada um deve ter um registro como time= host=web1 phase=initial, com o nome real correspondente em web2. Os timestamps variam e devem estar alinhados ao agendamento natural por minuto. Se a espera limitada falhar, inspecione o agendamento e o daemon em execução em vez de escrever um log de sucesso por conta própria.

Atualizar uma entrada nomeada e observar a nova fase

Nesta etapa, você alterará a entrada da tarefa, preservando sua identidade estável e o agendamento não relacionado.

Atualize o valor salvo da fase. A tarefa cron renderizará o novo comando mantendo o mesmo nome:

cat > group_vars/all.yml <<'YAML'
report_phase: verified
YAML
ansible-playbook reporting.yml

Inspecione os dois crontabs novamente:

ansible all -b -m ansible.builtin.command -a 'crontab -u automation -l'

Ainda deve haver exatamente uma entrada ansible-host-report por host, agora terminando em verified. Reutilizar seu nome atualiza a entrada existente em vez de acumular um segundo agendamento. Keep-existing-report deve permanecer inalterada.

Aguarde uma nova execução natural usando a fase atualizada. grep -q verifica um registro correspondente no log sem imprimi-lo; timeout e o loop until mantêm essa espera limitada:

ansible all -m ansible.builtin.command -a "timeout 90 bash -c 'until grep -q phase=verified /home/automation/reporting/host-report.log; do sleep 2; done'"
ansible all -m ansible.builtin.command -a 'cat /home/automation/reporting/host-report.log'

Ambos agora devem conter um novo registro phase=verified do agendador real. Os registros initial anteriores são um histórico útil e devem permanecer. Atualizar um comando no crontab não altera retroativamente as linhas antigas do log.

Remover apenas uma tarefa temporária nomeada e manter os relatórios estáveis

Nesta etapa, você removerá um agendamento temporário por seu nome estável e verificará que o relatório pretendido do usuário comum continua executando.

Crie uma entrada temporária nomeada inofensiva usando uma tarefa cron ad hoc. Ela agenda /usr/bin/true à meia-noite e fornece uma entrada real para remover:

ansible all -b -m ansible.builtin.cron -a 'name=ansible-temporary-report user=automation minute=0 hour=0 job=/usr/bin/true'
ansible all -b -m ansible.builtin.command -a 'crontab -u automation -l'

Escreva um pequeno playbook de limpeza. State absent e o name/user correspondentes removem apenas essa entrada gerenciada. Não esvazie nem substitua o crontab completo:

cat > cleanup.yml <<'YAML'
- name: Remove only the obsolete named schedule
  hosts: all
  gather_facts: false
  become: true
  tasks:
    - name: Remove the obsolete report entry by its stable name
      ansible.builtin.cron:
        name: ansible-temporary-report
        user: automation
        state: absent
YAML
ansible-playbook cleanup.yml
ansible all -b -m ansible.builtin.command -a 'crontab -u automation -l'

O marcador e o comando temporários devem desaparecer. Tanto ansible-host-report com fase verified quanto keep-existing-report devem permanecer.

Repita as duas declarações:

ansible-playbook reporting.yml
ansible-playbook cleanup.yml

Os dois playbooks devem informar changed=0, unreachable=0 e failed=0 para os dois hosts. Cron pode continuar acrescentando registros de log de forma independente; esses registros naturais de execução não tornam a implantação declarativa não idempotente.

A verificação final inspeciona as tarefas nomeadas do usuário comum, o programa exato implantado e os logs protegidos e depois aguarda outro disparo natural do agendador nos dois hosts. Isso pode levar cerca de um minuto. Deixe o agendamento de relatório e o daemon em execução para que essa observação comprove a execução contínua, em vez de um arquivo de sucesso preparado manualmente.

Resumo

Você gerenciou entradas cron nomeadas estáveis para o usuário comum pretendido, observou a execução agendada real, atualizou a entrada do comando sem duplicar a tarefa e removeu apenas uma entrada temporária. As permissões explícitas do programa e do log e a preservação de agendamentos não relacionados mantiveram claro o escopo. A implantação se repetiu sem alterações enquanto o relatório continuou executando naturalmente.