Training clusters liegen over wat productie toestaat
Databricks trainingsworkspaces, inclusief de omgevingen die worden gebruikt bij events zoals het Virtual Advanced Learning Festival dat tot begin juli 2026 loopt, geven je standaard onbeperkte toegang. Je kiest elk instantietype. Je stelt autoscaling in van 1 tot 128 workers. Je installeert PyPI-packages inline met %pip install. Alles werkt omdat er niets beperkt is.
Productie is anders. De meeste organisaties hanteren cluster policies die instantiefamilies beperken tot kosten-goedgekeurde SKU's. Een notebook die in training op een i3.xlarge draaide, mislukt met CLUSTER_POLICY_VIOLATION als je productiepolicy alleen m5d-instanties toestaat. Autoscaling-bereiken worden afgetopt. Spot instance-ratio's worden verplicht gesteld.
De failure zit niet in je code. Het zit in het verschil tussen wat de trainingsomgeving toestond en wat je cluster policy toelaat. En het foutbericht vertelt je niet welke specifieke policy-beperking je hebt overtreden. Het vertelt je alleen dat de configuratie niet compliant is.
Dit treft het hardst bij jobs die interactief zijn geprototypet. Een data engineer bouwt een pipeline tijdens een training sprint, valideert die tegen voorbeelddata en plant die vervolgens als productiejob in. De job cluster configuratie draagt de standaardinstellingen uit de training mee. De eerste uitvoering mislukt bij het aanmaken van het cluster, voordat er ook maar één regel Spark wordt uitgevoerd.
De controle is eenvoudig maar wordt zelden gedaan: voer vóór het promoveren van een job databricks clusters get --cluster-id uit op een productiecluster en vergelijk de configuratie met je job cluster spec. Vergelijk de velden instance_pool_id, node_type_id, policy_id en autoscale. Als een van die velden ontbreekt in je job definition maar wel wordt afgedwongen door je productiepolicy, mislukt de job bij de eerste geplande uitvoering.
Unity Catalog permissies worden niet overgedragen van sandbox naar productie
Trainingsworkspaces geven je gebruikersaccount doorgaans brede Unity Catalog privileges, vaak USE CATALOG, USE SCHEMA en SELECT op alles in de metastore. Dat is logisch voor leren, maar het is rampzalig als je daarop aannames voor productie baseert.
In productie wordt Unity Catalog toegang bepaald door fine-grained grants op catalogs, schemas, tabellen en volumes. Een notebook die training_catalog.default.customers opvraagt werkt omdat je trainingsidentiteit admin-level grants heeft geërfd. Hetzelfde querypatroon op prod_catalog.sales.customers geeft INSUFFICIENT_PRIVILEGES terug omdat aan je service principal geen expliciete toegang is verleend.
De fout die je ziet is: User does not have permission SELECT on table 'prod_catalog.sales.customers'. De oplossing is een expliciete GRANT SELECT ON TABLE prod_catalog.sales.customers TO service_principal_name. Maar het diepere probleem is dat niets in de trainingsflow je gedwongen heeft dit permissiemodel te doorgronden.
Dit wordt erger met external locations en storage credentials. Trainingsomgevingen gebruiken vaak een enkele storage credential met brede toegang. Productieomgevingen splitsen credentials per domein, per omgeving of per team. Je Delta-tabel write die in training slaagde mislukt met PERMISSION_DENIED op de external location omdat de productie storage credential het S3-prefix beperkt waar je job naar schrijft.
De aanpak: voer je productiejobs uit onder precies de service principal die ze in productie gaan gebruiken, niet onder je gebruikersidentiteit. Gebruik databricks jobs create met het run_as-veld ingesteld op de service principal. Als de job mislukt tijdens een dry run, heb je de permissiekloof gevonden voordat je stakeholders dat doen.
Init scripts en library dependencies breken bij DBR-versiewisselingen
Trainingsomgevingen standaardiseren op een specifieke Databricks Runtime-versie, vaak de nieuwste LTS. Je productieclusters draaien misschien een andere versie. Misschien een versie die actueel was toen de cluster policy zes maanden geleden werd geschreven.
Het verschil manifesteert zich op twee plekken: init scripts en library dependencies.
Init scripts die werken op DBR 14.3 LTS kunnen mislukken op DBR 13.3 LTS omdat systeempakketversies verschillen. Een apt-get install voor een specifieke bibliotheekversie die bestaat in de Ubuntu base image van DBR 14.x bestaat niet in 13.x. Het init script mislukt stil of met een exit-code niet nul die het opstarten van het cluster beëindigt. Je joblog toont INIT_SCRIPT_FAILURE met het pad naar het script maar minimale details over welk commando is mislukt.
Om te diagnosticeren: controleer de init script logs op dbfs:/cluster-log-delivery/. De feitelijke stderr output staat daar, niet in de output van de job run.
Library dependencies creëren een subtieler probleem. Een %pip install pandas==2.1.0 in training slaagt omdat DBR 14.3 met een compatibele NumPy-versie wordt meegeleverd. Dezelfde installatie op DBR 13.3 veroorzaakt een dependency conflict omdat de vastgepinde NumPy in die runtime incompatibel is met pandas 2.1.0. Het notebook hangt tijdens library-resolutie of gooit een DistributionNotFound-fout halverwege de uitvoering.
De aanpak: pin je DBR-versie in de job cluster configuratie, laat die overeenkomen met waartegen je hebt ontwikkeld en test library-installatie op een schoon cluster, niet op een interactief cluster waar packages al zijn gecached. Voeg spark.databricks.clusterUsageTags.clusterAllTags toe aan je cluster logs zodat je kunt traceren welke runtime-versie actief was bij een failure. Dit label is onmisbaar als je een job debugt die vorige week werkte maar vandaag mislukt omdat iemand de standaard runtime van de cluster policy heeft bijgewerkt.
Netwerk-isolatie blokkeert packages en API-calls die training toestond
Trainingsworkspaces hebben bijna altijd onbeperkte uitgaande netwerktoegang. Je notebook roept requests.get('https://api.example.com/data') aan en het werkt. Je installeert packages van PyPI. Je haalt modellen op van Hugging Face Hub. Niets geeft een fout.
ProductieWorkspaces in gereguleerde sectoren (financiële dienstverlening, zorg, overheid) draaien in VNet-geïnjecteerde of Private Link-configuraties zonder publieke internettoegang. De eerste keer dat je productiejob PyPI probeert te bereiken, hangt hij 30 seconden en gooit een ConnectionTimeoutError. De eerste API-aanroep naar een externe dienst geeft ConnectionRefusedError.
Deze failures zijn frustrerend omdat het infrastructuurfouten zijn die zich voordoen als codefouten. De stack trace wijst naar je requests.get-aanroep. Het werkelijke probleem is een Network Security Group-regel of een ontbrekend private endpoint.
De oplossing heeft twee delen. Installeer eerst alle Python-dependencies als workspace libraries of cluster-scoped libraries uit een intern artifact repository (Artifactory, CodeArtifact of een DBFS-hosted wheel). Vertrouw niet op runtime %pip install-commando's die het publieke internet bereiken. Werk voor externe API-aanroepen samen met je platform team om private endpoints te configureren of expliciete NSG-regels toe te voegen voor de endpoints die je jobs nodig hebben.
Test dit vóór het plannen. Voer een eenvoudige connectiviteitscontrole uit vanaf een productiecluster: %python import urllib.request; urllib.request.urlopen('https://pypi.org', timeout=5). Als dat time-out geeft, mislukken je pip-installaties. Als het slaagt, controleer dan of hetzelfde geldt voor je specifieke API-endpoints. Netwerkregels zijn vaak per bestemming, niet globaal toestaan of weigeren.
Secrets en omgevingsvariabelen bestaan in training maar niet in productiescopes
Trainingsomgevingen worden geleverd met vooraf geconfigureerde secret scopes of omgevingsvariabelen die verbindingsstrings, API-sleutels en opslagaccountcredentials aan je notebooks doorgeven. Je verwijst naar dbutils.secrets.get(scope='training', key='storage-key') en het geeft een waarde terug.
In productie bestaat die scope niet. Of hij bestaat maar je service principal mist READ-permissie erop. De fout is SecretNotFoundException of Permission denied for secret scope. Je job mislukt in de eerste cel.
Het verschil is zelden gedocumenteerd. Trainingsmateriaal laat je zien hoe je dbutils.secrets.get gebruikt maar niet hoe je scopes aanmaakt, die koppelt aan Azure Key Vault of AWS Secrets Manager backends en ACL's verleent aan service principals. Het Databricks CLI-commando om een scope aan te maken is databricks secrets create-scope --scope prod-scope --scope-backend-type AZURE_KEYVAULT --resource-id /subscriptions/.../vaults/my-vault. Het commando om toegang te verlenen is databricks secrets put-acl --scope prod-scope --principal service-principal-id --permission READ.
Een veelvoorkomend failure patroon: een team kopieert hun trainingsnotebook naar een productie-repo, werkt de tabelnamen en catalogusverwijzingen bij, maar laat de secret scope-naam ongewijzigd. De job mislukt omdat de training-scope niet bestaat in de productieworkspace. Of erger: die bestaat wel maar wijst naar een ontwikkelings-Key Vault met verouderde credentials. De job authenticeert succesvol maar leest uit het verkeerde opslagaccount.
Audit je secret-verwijzingen vóór deployment. Zoek in je notebooks naar dbutils.secrets.get en dbutils.secrets.list. Breng elke scope en sleutel in kaart naar het productie-equivalent. Bevestig dat de service principal die de job uitvoert READ ACL heeft op elke scope waarnaar hij verwijst. Dit kost vijftien minuten en voorkomt de melding om 2 uur 's nachts als je nachtelijke ingestiejob mislukt omdat die niet bij het bronsysteem kan authenticeren.
MetricSign dicht het gat tussen job definition en job execution
De configuratiemismatches die hierboven zijn beschreven, delen een gemeenschappelijk kenmerk: ze zijn onzichtbaar totdat de job wordt uitgevoerd. Cluster policies, Unity Catalog grants, netwerkregels, runtime-versies en secret scopes worden niet gevalideerd op het moment dat de job wordt aangemaakt. Databricks accepteert de job definition, plant die in en ontdekt het conflict pas bij uitvoering.
Dat betekent dat je eerste signaal dat er iets mis is, een mislukte run is. Als je tientallen jobs in één sprint vanuit een ontwikkelings- of trainingsomgeving hebt gepromoveerd, zijn dat tientallen potentiële eerste-run failures verdeeld over verschillende schema's en verschillende foutcategorieën.
MetricSign monitort Databricks job runs en groepeert failures per hoofdoorzaak in plaats van per jobnaam. Als vijf jobs mislukken met CLUSTER_POLICY_VIOLATION en drie mislukken met INSUFFICIENT_PRIVILEGES in hetzelfde deployment-venster, toont MetricSign die als twee incidenten, niet als acht afzonderlijke alerts. De hoofdoorzaakcontext laat zien welke policy of permissie de gemeenschappelijke noemer is, zodat je de onderliggende configuratie één keer oplost in plaats van elke failure afzonderlijk te triageren.
Dit telt het zwaarst in de periode nadat een team de training heeft afgerond en nieuwe pipelines begint te deployen. De failure rate stijgt. Zonder groepering overstroomt je alerteringskanaal met wat eruitziet als ongerelateerde failures. Met groepering zie je het patroon: dit zijn allemaal training-naar-productie configuratieverschillen en ze clusteren rondom specifieke infrastructuurbeperkingen.
Het alternatief is het handmatig parseren van INIT_SCRIPT_FAILURE, SecretNotFoundException en CLUSTER_POLICY_VIOLATION uit individuele Databricks job run-pagina's, één voor één, en ze handmatig correleren. Dat werkt voor vijf jobs. Niet voor vijftig.