Puncte:2

cum se verifică dacă ora sistemului este sincronizată cu serverul NTP fără a cunoaște clientul ntp utilizat în produs?

drapel cn

cum să verificați dacă ora sistemului este sincronizată cu serverul NTP fără a cunoaște clientul NTP utilizat în produs? Dezvolt o aplicație care se așteaptă să ruleze în ambele containere sau sisteme independente. Aplicația mea are o cerință de a se asigura că ora sistemului este sincronizată înainte de a încerca să efectueze anumite operațiuni. Cu toate acestea, nu poate fi garantată disponibilitatea pachetului NTP/chrony a fi disponibilă în container, chiar dacă unul sau altul client NTP este utilizat în sistemul de operare gazdă.

Deci, caut o modalitate unificată de a știu dacă ora sistemului este sincronizată sau nu?

John Mahowald avatar
drapel cn
Căutați o soluție portabilă? Unele dintre răspunsurile pe care le primiți nu sunt, de exemplu, systemd este doar Linux.
cptMikky avatar
drapel us
Din câte am citit, se pare că doriți să vă asigurați că ceasul sistemului este „la timp”, ca să spunem așa.Simplul fapt că o casetă este sincronizată cu un server NTP nu înseamnă neapărat că ora este corectă, doar că este sincronizată cu serverul NTP. Dacă aveți nevoie de primul, singurul dvs. pariu sigur este să faceți un fel de comparație de timp compensată cu o sursă de timp de încredere.
Puncte:2
drapel cn

Aplicațiile de calcul de uz general nu pot ști în toate cazurile cum funcționează sincronizarea timpului pe gazdele pe care rulează. Într-un container, nu vedeți și nu vă puteți conecta la chronyd sau ntpd care rulează pe gazdă, dar acest lucru păstrează timpul bine. Sau un invitat VM care se bazează pe sincronizarea timpului gazdei, de asemenea, nu este vizibil. În plus, îngreunând un răspuns general, există mai multe implementări NTP decât ați putea crede: chrony, ntp, ntpsec, openntpd, w32tm.

Adesea, documentarea importanței timpului corect este suficientă.

Pe unele platforme, a face o dependență de pornirea ntpd este relativ simplă. Pe RHEL, la așteptați sincronizarea timpului systemctl enable chrony-wait și adăugați la unitatea dvs. de sistem

După=time-sync.target
Necesită=time-sync.target

Cu toate acestea, există aplicații cu cerințe stricte de timp. Cel mai exigent la care mă pot gândi este autoritățile de marcare a timpului, dintre care unul susține că standardele necesită mai puțin de o secundă compensare sau nu poate fi emis nimic. Acest răspuns agresiv implică că aplicația își face propriile verificări de timp.

Poate combinarea unui client SNTP, care verifică decalajele NTP din aplicația dvs., față de serverele NTP configurabile.Nu se poate verifica o funcționare corectă a ntpd, dar pot verifica decalajele de sănătate, indiferent de modul în care funcționează sincronizarea timpului cu gazda.

Puncte:1
drapel jo

Există două moduri de a face acest lucru.

Dacă containerul pe care îl rulați are o implementare systemd completă, atunci timedatectl programul vă poate informa dacă gazda este sincronizată sau nu.

Modul în care acest lucru este gestionat intern este prin dbus care vorbește cu systemd-timedatat demonul. Ceea ce face este să efectueze un apel de sistem: adjtimex din care este posibil să se recupereze date care indică starea curentă a ajustării în nucleu (dacă există) care se face.

Prin urmare, a doua modalitate de a face acest lucru singur fără o implementare completă este utilizarea adjtimex() apel de sistem.

Nucleul nu dorește să aibă salturi de timp în raportarea timpului (sau, mai rău, timpul călătorind înapoi), ca atare, implementează o denaturare a timpului care, în decurs de câteva ore, ar corecta timpul sistemului (s-a terminat). prin adăugarea sau întârzierea cu câteva milisecunde pe secundă până la finalizarea reglajului).

The adjtimex Apelul de sistem este folosit de obicei de sistemele NTP pentru a modifica deformarea curentă cu care se confruntă ceasul pentru a se sincroniza corect cu o sursă de ceas adevărată -- dar poate fi folosit și pentru a prelua starea curentă a declinului sursei ceasului. Prin urmare, vă oferă posibilitatea de a arunca o privire în ideea nucleelor ​​despre ce sincronizare se face (dacă există).

Pagina de manual pentru adjtimex oferă câteva părți interesante care se referă la ceea ce cereți:

       Câmpul buf.status este o mască de biți care este utilizată pentru a seta și/sau a prelua biții de stare asociați cu implementarea NTP. Câteva bucăți în mască
       sunt atât lizibile, cât și setabile, în timp ce altele sunt doar citibile.
...
       STA_UNSYNC (citire-scriere)
              Ceas nesincronizat.

și

VALOARE RETURNATĂ
       La succes, adjtimex() și ntp_adjtime() returnează starea ceasului; adică una dintre următoarele valori:
...
       TIME_ERROR Ceasul sistemului nu este sincronizat cu un server de încredere. Această valoare este returnată atunci când oricare dintre următoarele este adevărată:

                   * Este setat fie STA_UNSYNC, fie STA_CLOCKERR.

                   * STA_PPSSIGNAL este clar și fie STA_PPSFREQ, fie STA_PPSTIME este setat.

                   * STA_PPSTIME și STA_PPSJITTER sunt ambele setate.

                   * STA_PPSFREQ este setat și fie STA_PPSWANDER, fie STA_PPSJITTER este setat.

                   Numele simbolic TIME_BAD este un sinonim pentru TIME_ERROR, furnizat pentru compatibilitate cu versiunea anterioară.

Ca atare, dacă nu aveți un container complet, este posibil să obțineți în continuare aceste date. Am scris un program simplu care va prelua starea kernel-urilor skew via adjtimex în C.Îl poți compila, de exemplu gcc -o timex timex.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <șir.h>

#include <sys/timex.h>

/* Scris pentru https://serverfault.com/questions/1077601/how-to-check-whether-the-system-time-is-synchronised-to-ntp-server-without-knowi */

void test_status(
    int st) 
{
  dacă (st și STA_PLL)
    printf("Bucla blocată în fază\n");
  dacă (st și STA_PPSFREQ)
    printf("Disciplina de frecventa puls pe secunda\n");
  dacă (st și STA_FLL)
    printf("Disciplina de timp PPS\n");
  dacă (st & STA_INS)
    printf("Inserați secunda intercalată și sfârșitul zilei\n");
  dacă (st & STA_DEL)
    printf("Șterge secunda intercalată și sfârșitul zilei\n");
  if (st & STA_UNSYNC)
    printf("Ceasul nu este sincronizat\n");
  dacă (st & STA_FREQHOLD)
    printf("Frecventa de mentinere\n");
  if (st & STA_PPSSIGNAL)
    printf("Semnalul PPS valid este prezent\n");
  if (st & STA_PPSJITTER)
    printf("Titter-ul semnalului PPS a fost depășit\n");
  dacă (st & STA_PPSWANDER)
    printf("Winder semnal PPS depășit\n");
  if (st & STA_PPSERROR)
    printf("Eroare de calibrare a semnalului PPS\n");
  if (st & STA_CLOCKERR)
    printf("Eroare hardware ceas\n");

  dacă (st & STA_NANO)
    printf("Rezolutie in nanosecunde\n");
  altfel
    printf("Rezolutie in microsecunde\n");

  dacă (st & STA_MODE)
    printf("Bucla blocata de frecventa\n");
  altfel
    printf("Bucla blocată în fază\n");
}

int main() {
  struct timex tx = {};
  tx.modes = ADJ_OFFSET_SS_READ;
  int err = adjtimex(&tx);

  comuta(er) {
    cazul 1:
      printf("Eroare de timp: %s\n", strerror(errno));
    pauză;

    cazul TIME_WAIT:
      printf("Inserarea/ștergerea secundă a fost finalizată\n");
    pauză;

    cazul TIME_INS:
      printf("Secunda intercalată va fi adăugată următoarea zi UTC\n");
    pauză;

    cazul TIME_DEL:
      printf("Secunda intercalată va fi ștearsă următoarea zi UTC\n");
    pauză;

    cazul TIME_OOP:
      printf("Inserarea secunda interioara in curs\n");
    pauză;

    cazul TIME_ERROR:
      printf("Eroare la obtinerea timpului\n");
    pauză;

    cazul TIME_OK:
      printf("Ora OK\n");
    pauză;

    Mod implicit:
      printf(„Ora implicită: %x (%d)\n”, err, err);
    pauză;
  }

  stare_test(tx.status);
  ieșire(0);
}

Rulează pe un sistem care nu este sincronizat:

$ ./timex 
Eroare la obținerea timpului
Ceasul nu este sincronizat
Rezoluție în microsecunde
Buclă blocată în fază

Rularea într-un container pe aceeași gazdă care nu este sincronizat:

# podman run -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
Eroare la obținerea timpului
Ceasul nu este sincronizat
Rezoluție în microsecunde
Buclă blocată în fază

Setarea orei în sistemul gazdă pentru sincronizare:

# systemctl start chronyd
# surse cronice
210 Număr de surse = 9
MS Nume/adresă IP Stratum Poll Reach LastRx Ultima mostră               
==================================================== ==============================
^* _gateway 2 6 7 1 +5568ns[ -720ms] +/- 32ms
# ./timex 
Ora OK
Rezoluție în microsecunde
Buclă blocată în fază

Efectuarea aceleiași verificări programatice în container pe aceeași gazdă:

# podman run -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
Ora OK
Rezoluție în microsecunde
Buclă blocată în fază

Există potențial o problemă cu spațiile de nume de timp pe care nu le-am testat (sunt foarte noi totuși) pentru a vedea dacă diferă sau respect adjtimex într-un context separat (vezi man 7 time_namespaces), dar din ceea ce am citit probabil că va funcționa în continuare -- aș lăsa asta pe dvs. să determinați.

Puncte:-1
drapel eg

Cum se verifică dacă ora sistemului este sincronizată cu un server NTP?

Nu există.

Aplicația mea are o cerință de a se asigura că ora sistemului este sincronizată înainte de a încerca să efectueze anumite operațiuni

Nu este responsabilitatea aplicației să configureze mediul corect pentru a rula, adică sistemul și administratorul acestuia.

Aplicațiile se bazează pe data/ora returnate de sistem. Fie că timpul este fie "corect" sau "gresit" ; aplicația în general nu are de unde să știe asta. Pur și simplu va folosi data/ora respectivă a sistemului.

Dacă aveți un model client-server, atunci ar fi bine să furnizați un mesaj de eroare util ori de câte ori tranzacțiile vor fi respinse din cauza decalajelor (extreme) de dată/oră.
Rețineți că existența unui astfel de offset nu vă spune dacă clientul este pe un ceas incorect, sau serverul sau ambele.

Matthew Ife avatar
drapel jo
Ceea ce solicită utilizatorul este dacă este sau nu posibil să se identifice (fără a verifica implementările NTP) pentru a vedea dacă nucleul este ajustat cumva. Deși aplicația nu configurează mediul, o aplicație bună ar putea verifica dacă este în mediul corect, totuși, fără a face nicio modificare.
John Mahowald avatar
drapel cn
O aplicație care nu este sub control și care nu cunoaște mediul va face o treabă proastă de a deduce cum funcționează sincronizarea timpului. Fie lăsați acest lucru la latitudinea administratorului sistemului de operare gazdă, fie definiți mai strict ceasurile software și/sau hardware implicate.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.