Como manter o tempo no convidado KVM retomado com libvirt?

18

No meu host, estou usando libvirt e um convidado KVM. Quando o host está sendo desligado, a libvirt suspende o convidado. Quando o host está inicializando, libvirt retoma o convidado. O problema é que, se o convidado for suspenso e retomado após 24 horas, por exemplo, o tempo do convidado será 24 horas no passado.

Eu pensei que talvez o problema esteja relacionado ao clocksource, mas ele já está definido como "kvm-clock".

$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
kvm-clock tsc hpet acpi_pm 

$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
kvm-clock
Hristo Hristov
fonte

Respostas:

11

O problema

Eu tenho o mesmo problema e não encontrei uma boa solução. Aqui está o que eu encontrei:

O problema é que, após a retomada, os horários do sistema e do hardware no convidado são diferentes:

root @ convidado: ~ # data; hwclock
11 de outubro de 13:09:38 UTC 2014
Sáb 11 de outubro 13:10:42 2014 -0.454380 segundos

No host, eles concordam:

raiz @ quatro: ~ # data; hwclock
Sábado, 11 de janeiro de 2013 13:11:35 UTC 2014
Sáb 11 de outubro 13:11:36 2014 -1.000372 segundos

A solução seria executar hwclock --hctosysno convidado depois que ele fosse retomado. No entanto, não encontrei uma maneira de fazer isso com alterações apenas no sistema de convidados, pois o convidado não percebe que foi suspenso e retomado.

QEmu Guest Agent

Existe a possibilidade de executar um software chamado QEmu Guest Agent no convidado e notificar do host para atualizar o relógio do sistema convidado a partir do relógio do hardware convidado. No entanto, a página menciona que o agente convidado torna o host e o convidado vulneráveis ​​a ataques um do outro devido a problemas com um analisador JSON (pelo menos eu acredito que o código afetado também seja executado no host, não tenho certeza disso ) De qualquer forma, veja como configurar isso:

  1. Configure um canal serial virtio para o agente, conforme mencionado no wiki libvirt (consulte também a documentação do formato de domínio libvirt ).

  2. Depois que o canal serial estiver disponível, instale e inicie o QEmu Guest Agent no convidado. (Debian:. apt-get install --no-install-recommends qemu-guest-agent)

  3. Ative o deslocamento do relógio suspendendo, aguardando e retomando. Em seguida, execute o seguinte comando no host para corrigi-lo: virsh qemu-agent-command backup '{"execute":"guest-set-time"}'A página wiki que virsh qemu-agent-commandestá usando não é suportada , mas não encontrei nenhum outro comando que faça o trabalho.

Eu encontrei duas discussões sobre como automatizar, dentro do libvirt, a chamada para guest-set-timesuspender o resumo:

No entanto, nada foi implementado ainda, tanto quanto pude ver.

Encontrei informações sobre como enviar comandos para o agente convidado no wiki do stoney-cloud.org .

Eu também tentei definir tickpolicy="catchup"a configuração do timer libvirt, mas isso não resolveu o problema.

NTP

Uma alternativa ao uso do agente seria usar um daemon ntp ou chamar o ntpdate periodicamente a partir de uma tarefa cron. Eu não recomendaria o último, pois isso pode atrasar o tempo, o que pode confundir os programas (por exemplo, o servidor IMAP do Dovecot não tenta lidar com o tempo que está atrasado e pode terminar).

Eu tentei os seguintes daemons NTP:

  • openntpd : corrige o tempo muito lentamente a uma taxa de cerca de 2 segundos por 60 minutos no meu teste. O deslocamento de tempo foi de 120 segundos. Além disso, o openntpd gera um erro se o deslocamento de tempo for muito grande e, no meu teste, falhar completamente na correção do horário nesse caso. Vantagens do openntpd: Pode ser executado como usuário comum no chroot.

  • chrony : Corrige um desvio de tempo de 120 segundos em 30 minutos no meu teste. O chrony pode ser configurado para ser executado como usuário comum. O suporte chroot não está implementado. O intervalo de pesquisa do servidor NTP pode ser configurado para cada servidor NTP.

  • systemd-timesyncd : corrige um deslocamento de tempo de 120 segundos em 30 segundos no meu teste. Executa como usuário regular por padrão. No entanto, o intervalo de pesquisa dos servidores NTP aumenta até 2048 segundos, para que uma suspensão / retomada não seja detectada até 34 minutos após a retomada, na pior das hipóteses. Isso não parece ser configurável. Além disso, observei que timesyncd retrocede o tempo, causando os mesmos problemas que chamar ntpdate em um cron (veja acima).

chrony resolve o problema. O Openntpd não é adequado porque sua taxa de correção é muito baixa e não parece ser configurável. O systemd-timesyncd também não resolve completamente o problema, porque seu intervalo de pesquisa não é configurável.

Testei as seguintes versões Debian dos daemons NTP: openntpd 20080406p-10, chrony 1.30-1 e systemd 215-5 + b1.

Milão
fonte
3

Muitas operações de host de virtualização no convidado podem resultar em uma pausa - retomada. Isso afetará negativamente o relógio do sistema no convidado. Por exemplo, a clonagem de uma VM resulta em uma pausa durante a clonagem. O relógio do hóspede depois está atrasado. Para que o NTP sincronize o relógio, você precisa reiniciar o convidado - não é uma boa solução em todos os casos, com certeza. Como alternativa, você pode simplesmente reiniciar o ntpd no convidado, mas isso também não é o ideal. Idealmente, deve haver um evento (VM retomado) disponível que você possa opcionalmente usar para esse tipo de correção para o convidado.

Depois de passar algum tempo pesquisando isso, decidi usar o relógio do host diretamente como referência para o relógio do sistema convidado do CentOS 7.

Em vez de executar o ntpd no convidado, decidi que a cada 15 minutos eu definiria, via crontab, o relógio do sistema convidado do relógio de hardware do convidado. O relógio de hardware do convidado reflete o horário no host de virtualização que é controlado via ntpd em execução no host de virtualização. Isso me proporciona um tempo confiável no sistema operacional convidado. Na pior das hipóteses, o relógio pode estar desativado por até 15 minutos antes de ser sincronizado no horário adequado após a retomada do hóspede.

# crontab -e

0,15,30,45 * * * * /sbin/hwclock --hctosys

Seria muito melhor ter um evento disponível no convidado que iniciasse uma sincronização de horário quando o convidado fosse reiniciado, mas aparentemente isso não está disponível. A abordagem crontab é uma solução alternativa, pois faz uma chamada hwclock a cada 15 minutos. Faz o trabalho, mas não da maneira mais elegante que eu gostaria.

zman58
fonte
2

O kvm-clock sincroniza o horário do convidado para hospedar o horário na inicialização do convidado . Você deve usar o cliente ntp no convidado e desligar / iniciar em vez de suspender / retomar.

dyasny
fonte
Sim, posso confirmar que sincroniza na inicialização, porque quando eu faço o desligamento / inicialização do convidado, tudo está bem. Usar o ntp não é uma solução por vários motivos (é uma solução alternativa, entra em pânico quando a diferença de horário é enorme, requer acesso ao servidor de horário). Estou procurando uma maneira de resolver o problema com a suspensão / retomada, porque esta é uma opção interessante, agradável e padrão no libvirt.
Hristo Hristov
suspender é 1) migrar o estado da VM para o arquivo e 2) destruir. Quando você retoma da suspensão, o estado da VM é restaurado (migrado do arquivo de volta para a memória da VM). Esse estado incluirá o registro de data e hora atual. Então, sim, é o padrão, mas não, o tempo ainda é importante, e a hora precisa chegar de algum lugar, e é aí que o NTP deve entrar. Duvido que outra fonte de relógio o ajude, mas você pode tentar com acpi_pm.
dyasny
Você não deve usar o NTP no convidado .
Brian Cain
4
@ Brian Cain, isso é altamente discutível, especialmente sem nenhuma explicação ou raciocínio por trás da declaração. Para fornecer um profflink: docs.redhat.com/docs/pt-BR/…
dyasny
2

A libvirt suporta a sincronização do horário do convidado desde 2015 . No Debian Stretch e depois procure a opção SYNC_TIMEem /etc/default/libvirt-guests:

# If non-zero, try to sync guest time on domain resume. Be aware, that
# this requires guest agent with support for time synchronization
# running in the guest. For instance, qemu-ga doesn't support guest time
# synchronization on Windows guests, but Linux ones. By default, this
# functionality is turned off.
#SYNC_TIME=1

Você pode testar a sincronização de horário no sistema host com:

virsh qemu-agent-command INSERT_YOUR_DOMAIN_HERE '{"execute":"guest-set-time"}'

Este comando deve retornar {"return":{}}com sucesso.

Jakob
fonte
0

Uso uma maneira semelhante para sincronizar o tempo após a suspensão / retomada da VM, mas acho melhor tentar adivinhar, que ela deve ser sincronizada na direção certa e é maior que a curta diferença, que pode ser corrigida pelo NTPD.

https://gist.github.com/jhrcz/7138803

PS. O novo changelog do centos 6.7 diz que isso pode ser feito automaticamente, apenas com a fonte de clock kvm-clock.

Jan Horacek
fonte