Săriți la conținut

Blog ·

De la un răspuns DHCP la o instalare completă

Netboot, partea a doua. Ce urmează după ofertă: scriptul de pornire, fișierul de răspunsuri, apelul înapoi pe care nu îl scrie nimeni și sumele de control.

De Provibr

A face o mașină să accepte o ofertă de netboot este partea despre care scrie toată lumea. Am scris și noi despre ea, după ce am pierdut o săptămână cu adresa de destinație a unui răspuns proxy-DHCP.

Partea de după nu prea este acoperită nicăieri, și acolo stau eșecurile adevărate. O mașină care pornește și apoi rămâne la nesfârșit blocată pe o întrebare este mai rea decât una care nu a pornit deloc, pentru că arată a progres. Aceasta este a doua jumătate: ce trebuie să fie adevărat între sosirea ofertei și apariția unui prompt de autentificare, și care dintre lucrurile acelea eșuează în tăcere.

Cele cinci lucruri care sunt servite

Odată ce clientul are o ofertă și un fișier de pornire, o instalare nesupravegheată înseamnă cinci artefacte. Niciunul dintre ele nu este opțional, iar ultimul este cel pe care lumea îl omite.

#CeServit deCum eșuează
1Script de pornireHTTPMașina cade într-un shell
2NucleuHTTPPornirea se întrerupe
3InitrdHTTPPornirea se întrerupe
4Fișier de răspunsuriHTTPProgramul de instalare pune o întrebare și așteaptă
5Apel înapoi de finalizareSistemul instalatTotul rămâne blocat până la un termen-limită

Coloana interesantă este ultima. Elementele de la 1 la 3 eșuează zgomotos, pe ecran, într-un fel pe care cineva îl va observa. Elementele 4 și 5 eșuează ca o instalare care pare să ruleze și nu se termină niciodată.

Scripturile de pornire și problema substituentului

Scriptul de pornire trebuie să numească URL-uri absolute și nu le poate cunoaște în clipa în care este scris profilul: adresa a ceea ce servește fișierele depinde de segmentul pe care a pornit mașina.

Așa că profilul conține un substituent care este înlocuit în momentul servirii. Al nostru este @@PROVIBR_BASE@@, iar forma lui este o alegere deliberată, nu o preferință de stil.

Forma evidentă ar fi ${BASE}. Ea este exact cea greșită, pentru că iPXE extinde el însuși ${...}. O substituție care nu are loc devine un șir gol în loc de o eroare, și ajungeți să vă holbați la

text
chain http:///vmlinuz

întrebându-vă ce este în neregulă cu serverul dumneavoastră web. Un delimitator pe care încărcătorul de pornire nu îl recunoaște transformă un eșec tăcut de substituție într-unul vizibil.

Cele trei linii de comandă de nucleu care contează, odată ce dați marca la o parte:

text
# Ubuntu (subiquity)
kernel <kernel> initrd=<initrd> ip=dhcp autoinstall ds=nocloud;s=<dir>/ --- || goto failed

# Debian (preseed)
kernel <kernel> initrd=<initrd> auto=true priority=critical ip=dhcp url=<file> DEBIAN_FRONTEND=text --- quiet || goto failed

# RHEL family (Anaconda)
kernel <kernel> initrd=<initrd> ip=dhcp inst.repo=<tree> inst.ks=<file> inst.text || goto failed

Trei programe de instalare, trei vocabulare complet diferite pentru aceeași idee, iar argumentul care poartă fișierul de răspunsuri se scrie altfel în fiecare. ds= primește un director; url= și inst.ks= primesc un fișier. Dacă le încurcați, obțineți un program de instalare care pornește și apoi pune prima întrebare.

Cele patru chei autoinstall care decid dacă se termină

Autoinstall-ul de la Ubuntu merită un paragraf al lui, pentru că pe un segment izolat patru chei despart o instalare care se încheie de una care nu se încheie, iar niciuna dintre ele nu este despre discuri sau utilizatori:

  • interactive-sections: []: fără ea, subiquity tot se oprește să întrebe ceva.
  • refresh-installer.update: false: fără ea, se duce întâi să caute un program de instalare mai nou.
  • apt.fallback: offline-install: fără ea, așteaptă arhiva înainte să renunțe.
  • drivers.install: false: aceeași clasă de problemă, același rezultat.

Eșecul este în fiecare caz același: un ecran care pare ocupat. Nu există nicio eroare, pentru că din punctul de vedere al programului de instalare nu a mers nimic prost.

Există un indicator pereche pentru mediul de instalare. Initrd-ul de netboot al Ubuntu despachetează un mediu de instalare într-un tmpfs și instalează din el; dacă nu îi spuneți unde se află acel mediu, se duce pe internet să găsească unul. Pe un segment fără legătură în sus, aceasta este diferența dintre a funcționa și patru minute de nimic urmate de un prompt busybox.

Apelul înapoi pe care nu îl scrie nimeni

Elementul 5 din listă este o singură linie într-un script de post-instalare care descarcă un URL, și este piesa care lipsește cel mai des dintr-o configurație făcută în casă.

Fără el nu există niciun eveniment care să însemne gata. Programul de instalare repornește, mașina pornește, iar sistemul care a început instalarea habar nu are, așa că așteaptă până la termenul pe care îl are și apoi raportează o expirare pe o mașină care s-a instalat perfect.

Două detalii fac lucrul acesta mai puțin enervant decât sună. Întâi, livrați cârligul în șablon, în loc să îl documentați, ca cineva care își scrie propriul script de post-instalare să nu fie nevoit să știe că există. Apoi, aveți un cârlig pentru eșec pe lângă cel pentru reușită: o instalare care eșuează la 04:00 și o spune este cu totul altă experiență de asistență decât una care amuțește.

Și țineți două ceasuri, nu unul. Comanda care pornește o instalare ar trebui să se încheie imediat ce ascultătorii sunt sus și sesiunea este acceptată, nu când se termină instalarea; a noastră are pentru asta un termen de 90 de secunde, față de un buget de instalare de o oră, impus pe ambele părți. Un singur termen pentru amândouă înseamnă fie o sarcină care stă o oră în interfață fără să facă nimic, fie o instalare oprită pentru că a durat cât durează instalările.

Ce furnizori publică o sumă de control, măsurat

Dacă mașina descarcă un nucleu și un initrd prin HTTP de la o oglindă, ceva ar trebui să verifice ce a venit înapoi. Modul de a face asta este să fixați un sha256 în profil și să îl verificați după descărcare, în locul care face descărcarea.

Asta funcționează doar dacă furnizorul publică una. Am presupus că răspunsul este „în mare parte nu”, am scris asta și s-a dovedit greșit în trei din patru cazuri. Ce se publică de fapt, măsurat pe 2026-09-02:

FurnizorNucleu + initrd de netbootUnde
DebianDaSHA256SUMS lângă installer-amd64/current/images/
Familia RHELDa[checksums] în .treeinfo de lângă arbore
Ubuntu (ISO live server)DaSHA256SUMS lângă versiunea publicată
Ubuntu (nucleu + initrd de netboot)NuNiciun fișier de sume în directorul de netboot, iar arhiva nu este trecută nici în sumele versiunii

Costul acelei presupuneri greșite nu a fost o cădere; a fost mai rău, într-un fel tăcut. Resurse care ar fi putut fi fixate stăteau marcate drept neverificabile, iar profilurile se declarau neinstalabile în timp ce furnizorul publica răspunsul la vedere. Patru din cinci artefacte, pe primele două profiluri.

Comportamentul de atunci când o sumă de control chiar nu există merită proiectat intenționat. La noi, fixarea rămâne goală, resursa este marcată drept în așteptare, iar profilul se declară neinstalabil până când un administrator lipește un hash. Asta este intenționat mai zgomotos decât a descărca oricum. Un nucleu neverificat, luat prin HTTP de la o oglindă, este locul cel mai valoros din care poate fi atacat un sistem de aprovizionare, iar „nu am putut verifica asta, așa că am făcut-o oricum” nu este o politică.

Ce are voie să însemne „întreținut”

Livrăm zece profiluri de bază: Ubuntu Server 24.04 și 26.04, Debian 12 și 13, Rocky Linux 9 și 10, AlmaLinux 9 și 10, CentOS Stream 10, Fedora Server 44.

Starea de suport atașată fiecăruia este calculată, nu tastată. Un profil are voie să se numească întreținut doar când are o rulare verificată pe ambele trasee de firmware, BIOS și UEFI. Unul dintre cele două dă „previzualizare”. Niciunul nu dă „neîntreținut”.

A face din asta o regulă în loc de un câmp merită bruma de cod. O etichetă tastată de mână valorează exact cât grija celui care a tastat-o, iar aceasta este o etichetă pe baza căreia un client pune o mașină în funcțiune.

Ceea ce înseamnă să fim limpezi în privința locului în care ne aflăm astăzi. Ubuntu Server 26.04 și Debian 13 s-au instalat complet nesupravegheat pe un segment izolat, pe o mașină cu BIOS. Traseul UEFI a fost reparat în aceeași rundă, iar a-l repara nu este același lucru cu a-l rula. Prin urmare, la ora scrierii, niciun profil dintre cele livrate nu este maintained, iar profilurile din familia RHEL nu au fost deloc rulate pe o mașină reală: au fost scrise după documentația furnizorului și măsurate față de fișiere sursă reale, ceea ce este o afirmație mai slabă decât pare din afară.

Separat, oferirea netboot-ului ca mod de a crea o mașină nouă este oprită implicit în platforma noastră, în așteptarea unui singur lucru: o mașină reală care se instalează astfel, pe firmware real. Traseul care există și este folosit este reinstalarea peste o mașină existentă. Un indicator de funcționalitate pornit pentru că este scris codul, și nu pentru că s-a observat că lucrul funcționează, produce un buton de comandă care se împotmolește la jumătate la primul client adevărat.

Lucruri mici care costă câte o după-amiază fiecare

  • Validați căile fișierelor servite. Fără slash la început, fără .., fără backslash, o singură clasă de caractere. Lucrul care servește fișiere se află în rețeaua cuiva, cu un sistem de fișiere în spate.
  • Cenzurați rândul de audit. Consemnați ce fișier a fost servit și dacă purta un secret, niciodată conținutul. Oricine are nevoie de conținut poate genera profilul din nou.
  • Nu lăsați fișierul de răspunsuri să fie o a doua sursă a adevărului despre mediul de instalare. Argumentul de nucleu și fișierul de răspunsuri numesc amândouă de unde vin pachetele; derivarea amândurora dintr-o singură setare este singurul mod în care rămân egale.
  • Presupuneți că nimeni nu se uită la consolă. Fiecare alegere de mai sus este o alegere despre ce se întâmplă când instalarea este la minutul șase din opt și nu există niciun om în încăpere.

Aceasta este a doua parte a textului despre de ce eșuează netboot-ul UEFI acolo unde BIOS funcționează și a ieșit din construirea instalării prin rețea în Provibr. Detaliile se află în documentația de netboot.

Începeți cu o gazdă și un agent

Creați un cont, instalați agentul cu o singură comandă și conectați primul dumneavoastră host Proxmox. Perioada de probă durează 14 zile și nu cere date de plată.