Dovrei chiamare ugi.checkTGTAndReloginFromKeytab () prima di ogni azione su hadoop?

Nella mia applicazione server mi sto collegando al cluster Hadoop protetto da Kerberos dalla mia applicazione java. Sto usando vari componenti come il file system HDFS, Oozie, Hive, ecc. All’avvio dell’applicazione, richiamo

UserGroupInformation.loginUserFromKeytabAndReturnUGI( ... ); 

Questo mi restituisce l’istanza UserGroupInformation e la tengo per tutta la vita dell’applicazione. Quando si esegue un’azione privilegiata, li avvio con ugi.doAs(action) .

Funziona bene, ma mi chiedo se e quando dovrei rinnovare il ticket UserGroupInformation in UserGroupInformation ? Ho trovato un metodo UserGroupInformation.checkTGTAndReloginFromKeytab() che sembra eseguire il rinnovo del ticket ogni volta che è prossimo alla scadenza. Ho anche scoperto che questo metodo viene chiamato da vari strumenti Hadoop come WebHdfsFileSystem per esempio.

Ora se voglio che la mia applicazione server (possibilmente funzionante per mesi o anche anni) non abbia mai la scadenza del ticket qual è l’approccio migliore? Per fornire domande concrete:

  1. Posso contare sui vari client Hadoop che chiamano checkTGTAndReloginFromKeytab ogni volta che è necessario?
  2. Dovrei chiamare mai checkTGTAndReloginFromKeytab nel mio codice?
  3. In tal caso, dovrei farlo prima di ogni singola chiamata a ugi.doAs(...) o piuttosto impostare un timer e chiamarlo periodicamente (con quale frequenza)?

Committer Hadoop qui! Questa è una domanda eccellente.

Sfortunatamente, è difficile dare una risposta definitiva a questo senza una profonda immersione nei particolari modelli di utilizzo dell’applicazione. Invece, posso offrire linee guida generali e descrivere quando Hadoop gestirà il rinnovo del ticket o il login da un keytab automaticamente per te, e quando non lo farebbe.

Il caso d’uso principale per l’autenticazione Kerberos nell’ecosistema Hadoop è il framework RPC di Hadoop, che utilizza SASL per l’autenticazione. La maggior parte dei processi daemon nell’ecosistema Hadoop gestiscono ciò effettuando una singola chiamata one-time a UserGroupInformation#loginUserFromKeytab all’avvio del processo. Esempi di questo includono il DataNode HDFS, che deve autenticare le sue chiamate RPC al NameNode e il NodeManager YARN, che deve autenticare le sue chiamate al ResourceManager. Com’è ansible che i demoni come DataNode possano effettuare un accesso singolo all’avvio del processo e continuare a funzionare per mesi, oltre i tempi tipici di scadenza dei ticket?

Poiché questo è un caso d’uso comune, Hadoop implementa un meccanismo di ri-login automatico direttamente all’interno del livello client RPC. Il codice per questo è visibile nel metodo Client#handleSaslConnectionFailure RPC:

  // try re-login if (UserGroupInformation.isLoginKeytabBased()) { UserGroupInformation.getLoginUser().reloginFromKeytab(); } else if (UserGroupInformation.isLoginTicketBased()) { UserGroupInformation.getLoginUser().reloginFromTicketCache(); } 

Si può pensare a questo come “valutazione pigra” del re-login. Esegue solo il login in risposta a un errore di autenticazione su una connessione RPC tentata.

Sapendo questo, possiamo dare una risposta parziale. Se il modello di utilizzo dell’applicazione è il login da un keytab e quindi eseguire le tipiche chiamate Hadoop RPC, probabilmente non è necessario eseguire il rollover del proprio codice di re-login. Il livello client RPC lo farà per te. “Typical Hadoop RPC” indica la stragrande maggioranza delle API Java per l’interazione con Hadoop, comprese le API di FileSystem HDFS, le presentazioni di YarnClient e MapReduce.

Tuttavia, alcuni modelli di utilizzo delle applicazioni non coinvolgono affatto la RPC Hadoop. Un esempio di questo sarebbe applicazioni che interagiscono esclusivamente con le API REST di Hadoop, come WebHDFS o le API REST YARN . In tal caso, il modello di autenticazione utilizza Kerberos tramite SPNEGO come descritto nella documentazione dell’autenticazione HTTP di Hadoop.

Sapendo questo, possiamo aggiungere altro alla nostra risposta. Se il modello di utilizzo dell’applicazione non utilizza affatto Hadoop RPC e si limita invece alle API REST, è necessario eseguire la propria logica di re-login. Questo è esattamente il motivo per cui WebHdfsFileSystem chiama UserGroupInformation#checkTGTAndReloginFromkeytab , proprio come hai notato. WebHdfsFileSystem sceglie di effettuare la chiamata immediatamente prima di ogni operazione. Questa è una buona strategia, perché UserGroupInformation#checkTGTAndReloginFromkeytab rinnova il ticket solo se è “vicino” alla scadenza. Altrimenti, la chiamata è no-op.

Come caso di utilizzo finale, consideriamo un processo interattivo, non effettuando l’accesso da un keytab, ma piuttosto richiedendo all’utente di eseguire kinit esternamente prima di avviare l’applicazione. Nella stragrande maggioranza dei casi, queste saranno applicazioni di breve durata, come i comandi Hadoop CLI. Tuttavia, in alcuni casi questi possono essere processi più lunghi. Per supportare processi con esecuzione più lunga, Hadoop avvia un thread in background per rinnovare il ticket Kerberos “close” alla scadenza. Questa logica è visibile in UserGroupInformation#spawnAutoRenewalThreadForUserCreds . C’è una distinzione importante qui se confrontata con la logica di re-login automatica fornita nel livello RPC. In questo caso, Hadoop ha solo la capacità di rinnovare il ticket e prolungarne la durata. I biglietti hanno una durata massima rinnovabile, come richiesto dall’infrastruttura Kerberos. Dopo questo, il biglietto non sarà più utilizzabile. Effettuare nuovamente il login in questo caso è praticamente imansible, poiché implicherebbe di nuovo richiedere all’utente una password e probabilmente si allontanerebbero dal terminale. Ciò significa che se il processo continua a funzionare oltre la scadenza del ticket, non sarà più in grado di autenticarsi.

Ancora una volta, possiamo usare queste informazioni per informare la nostra risposta generale. Se ti affidi a un utente per accedere in modo interattivo tramite kinit prima di avviare l’applicazione, e se sei sicuro che l’applicazione non durerà più a lungo della durata massima rinnovabile del ticket Kerberos, allora puoi fare affidamento su Hadoop internals per coprire il rinnovo periodico per te .

Se si utilizza l’accesso basato su keytab e non si è sicuri se il modello di utilizzo dell’applicazione può fare affidamento sul re-login automatico del layer Hadoop RPC, l’approccio conservativo è quello di eseguire il rollover. @SamsonScharfrichter ha dato una risposta eccellente qui su rotolare il tuo.

Strategia di rinnovo della connessione Kerberos HBase

Infine, dovrei aggiungere una nota sulla stabilità dell’API. Le linee guida sulla Apache Hadoop Compatibility discutono l’impegno della comunità di sviluppo Hadoop per la retrocompatibilità in dettaglio. L’interfaccia di UserGroupInformation è annotata LimitedPrivate ed Evolving . Tecnicamente, ciò significa che l’API di UserGroupInformation non è considerata pubblica e potrebbe evolversi in modi incompatibili con le versioni precedenti. In pratica, c’è già un sacco di codice che dipende dall’interfaccia di UserGroupInformation , quindi semplicemente non è fattibile per noi fare un cambio di rottura. Certamente all’interno dell’attuale linea di rilascio 2.x, non avrei alcuna paura che le firme dei metodi cambino da sotto di te e infrangano il tuo codice.

Ora che abbiamo tutte queste informazioni di base, rivisitiamo le vostre domande concrete.

Posso contare sui vari client Hadoop che chiamano checkTGTAndReloginFromKeytab ogni volta che è necessario?

Potete fare affidamento su questo se il modello di utilizzo della vostra applicazione è di chiamare i client Hadoop, che a loro volta utilizzano il framework RPC di Hadoop. Non puoi fare affidamento su questo se il modello di utilizzo dell’applicazione utilizza solo le API REST Hadoop.

Dovrei chiamare mai checkTGTAndReloginFromKeytab nel mio codice?

Probabilmente dovrai farlo se il modello di utilizzo dell’applicazione è esclusivamente per chiamare le API REST Hadoop invece delle chiamate RPC Hadoop. Non si otterrebbe il vantaggio del re-login automatico implementato nel client RPC di Hadoop.

In tal caso, dovrei farlo prima di ogni singola chiamata a ugi.doAs (…) o piuttosto impostare un timer e chiamarlo periodicamente (con quale frequenza)?

Va bene chiamare UserGroupInformation#checkTGTAndReloginFromKeytab proprio prima di ogni azione che deve essere autenticata. Se il ticket non è vicino alla scadenza, il metodo sarà un no-op. Se sei sospettoso che la tua infrastruttura Kerberos sia lenta e non vuoi che le operazioni client paghino il costo di latenza del re-login, allora sarebbe un buon motivo per farlo in un thread in background separato. Assicurati di stare un po ‘in anticipo sull’effettiva scadenza del biglietto. È ansible prendere in prestito la logica all’interno di UserGroupInformation per determinare se un ticket è “vicino” alla scadenza. In pratica, non ho mai visto personalmente che la latenza del re-login sia problematica.