java hadoop kerberos

java - ¿Debo llamar a ugi.checkTGTAndReloginFromKeytab() antes de cada acción en hadoop?



kerberos (1)

¡Hadoop committer aquí! Esta es una excelente pregunta.

Desafortunadamente, es difícil dar una respuesta definitiva a esto sin profundizar en los patrones de uso particulares de la aplicación. En cambio, puedo ofrecer pautas generales y describir cuándo Hadoop se encargaría de la renovación del ticket o volvería a iniciar sesión automáticamente desde una pestaña, y cuándo no lo haría.

El caso de uso principal para la autenticación Kerberos en el ecosistema de Hadoop es el marco RPC de Hadoop, que utiliza SASL para la autenticación. La mayoría de los procesos de daemon en el ecosistema de Hadoop manejan esto haciendo una sola llamada UserGroupInformation#loginUserFromKeytab a UserGroupInformation#loginUserFromKeytab al inicio del proceso. Ejemplos de esto incluyen el HDFS DataNode, que debe autenticar sus llamadas RPC al NameNode, y el YARN NodeManager, que debe autenticar sus llamadas al ResourceManager. ¿Cómo es que los demonios como DataNode pueden iniciar sesión una vez al inicio del proceso y luego seguir ejecutándose durante meses, mucho más allá de los tiempos de caducidad de tickets típicos?

Dado que este es un caso de uso tan común, Hadoop implementa un mecanismo de reingreso automático directamente dentro de la capa del cliente RPC. El código para esto es visible en el método RPC Client#handleSaslConnectionFailure :

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

Puede pensar en esto como una "evaluación perezosa" de reinicio de sesión. Solo vuelve a ejecutar el inicio de sesión en respuesta a un error de autenticación en un intento de conexión RPC.

Sabiendo esto, podemos dar una respuesta parcial. Si el patrón de uso de su aplicación es iniciar sesión desde una pestaña clave y luego realizar llamadas típicas de Hadoop RPC, entonces es probable que no necesite rodar su propio código de reinicio de sesión. La capa de cliente RPC lo hará por usted. "Típico RPC de Hadoop" se refiere a la gran mayoría de las API de Java para interactuar con Hadoop, incluidas la API HDFS FileSystem , las presentaciones de Job YarnClient y MapReduce.

Sin embargo, algunos patrones de uso de aplicaciones no involucran a Hadoop RPC en absoluto. Un ejemplo de esto serían las aplicaciones que interactúan únicamente con las API REST de Hadoop, como WebHDFS o las API REST de YARN . En ese caso, el modelo de autenticación utiliza Kerberos a través de SPNEGO como se describe en la documentación de autenticación HTTP de Hadoop.

Sabiendo esto, podemos agregar más a nuestra respuesta. Si el patrón de uso de su aplicación no utiliza Hadoop RPC en absoluto y, en cambio, se adhiere únicamente a las API REST, entonces debe lanzar su propia lógica de reinicio de sesión. Esto es exactamente por qué WebHdfsFileSystem llama a UserGroupInformation#checkTGTAndReloginFromkeytab , tal como lo notó. WebHdfsFileSystem elige hacer la llamada justo antes de cada operación. Esta es una buena estrategia, porque UserGroupInformation#checkTGTAndReloginFromkeytab solo renueva el ticket si está "cerca" de caducar. De lo contrario, la llamada es no operativa.

Como caso de uso final, consideremos un proceso interactivo, no iniciar sesión desde una pestaña clave, sino más bien requerir que el usuario ejecute kinit externamente antes de iniciar la aplicación. En la gran mayoría de los casos, estas serán aplicaciones de ejecución corta, como los comandos Hadoop CLI. Sin embargo, en algunos casos, estos pueden ser procesos de ejecución más larga. Para admitir procesos de ejecución más larga, Hadoop inicia un subproceso en segundo plano para renovar el ticket Kerberos "cerrar" hasta el vencimiento. Esta lógica es visible en UserGroupInformation#spawnAutoRenewalThreadForUserCreds . Aquí hay una distinción importante en comparación con la lógica de reinicio de sesión automática proporcionada en la capa RPC. En este caso, Hadoop solo tiene la capacidad de renovar el ticket y extender su vida útil. Los tickets tienen una vida útil renovable máxima, según lo dicta la infraestructura de Kerberos. Después de eso, el boleto ya no será utilizable. Volver a iniciar sesión en este caso es prácticamente imposible, ya que implicaría volver a solicitar una contraseña al usuario, y probablemente se alejaron de la terminal. Esto significa que si el proceso continúa más allá del vencimiento del ticket, ya no podrá autenticarse.

Nuevamente, podemos usar esta información para informar nuestra respuesta general. Si confía en que un usuario inicie sesión de forma interactiva a través de kinit antes de iniciar la aplicación, y si está seguro de que la aplicación no durará más que la vida útil renovable máxima del ticket Kerberos, puede confiar en los componentes internos de Hadoop para cubrir la renovación periódica para usted .

Si está utilizando un inicio de sesión basado en una tabla de claves y no está seguro de si el patrón de uso de su aplicación puede basarse en el reinicio de sesión automático de la capa RPC de Hadoop, entonces el enfoque conservador es el suyo. @SamsonScharfrichter dio una excelente respuesta aquí sobre tirar la tuya.

Estrategia de renovación de conexión de HBase Kerberos

Finalmente, debería agregar una nota sobre la estabilidad de la API. Las pautas de Apache Hadoop Compatibility analizan el compromiso de la comunidad de desarrollo de Hadoop con la compatibilidad con versiones anteriores con todo detalle. La interfaz de UserGroupInformation está anotada LimitedPrivate y Evolving . Técnicamente, esto significa que la API de UserGroupInformation no se considera pública, y podría evolucionar de formas incompatibles con versiones anteriores. Como cuestión práctica, ya existe una gran cantidad de código que depende de la interfaz de UserGroupInformation , por lo que simplemente no es factible que UserGroupInformation un cambio importante. Ciertamente, dentro de la línea de lanzamiento 2.x actual, no tendría miedo de que las firmas de métodos cambien debajo de usted y rompan su código.

Ahora que tenemos toda esta información de fondo, revisemos sus preguntas concretas.

¿Puedo confiar en los diversos clientes de Hadoop a los que llaman checkTGTAndReloginFromKeytab cuando sea necesario?

Puede confiar en esto si el patrón de uso de su aplicación es llamar a los clientes de Hadoop, que a su vez utilizan el marco RPC de Hadoop. No puede confiar en esto si el patrón de uso de su aplicación solo llama a las API REST de Hadoop.

¿Debería llamar alguna vez checkTGTAndReloginFromKeytab yo mismo en mi código?

Es probable que tenga que hacer esto si el patrón de uso de su aplicación es únicamente para llamar a las API REST de Hadoop en lugar de las llamadas RPC de Hadoop. No obtendría el beneficio del reingreso automático implementado dentro del cliente RPC de Hadoop.

Si es así, ¿debo hacerlo antes de cada llamada a ugi.doAs (...) o más bien configurar un temporizador y llamarlo periódicamente (con qué frecuencia)?

Está bien llamar a UserGroupInformation#checkTGTAndReloginFromKeytab justo antes de cada acción que deba autenticarse. Si el ticket no está a punto de caducar, entonces el método será no operativo. Si sospecha que su infraestructura de Kerberos es lenta y no desea que las operaciones del cliente paguen el costo de latencia de reinicio de sesión, entonces esa sería una razón para hacerlo en un hilo de fondo separado. Solo asegúrese de adelantarse un poco al tiempo de vencimiento real del boleto. Puede tomar prestada la lógica dentro de UserGroupInformation para determinar si un ticket está "cerca" de caducar. En la práctica, nunca he visto que la latencia del reingreso sea problemática.

En mi aplicación de servidor, me estoy conectando al clúster Hadoop seguro de Kerberos desde mi aplicación java. Estoy usando varios componentes como el sistema de archivos HDFS, Oozie, Hive, etc. Al iniciar la aplicación, llamo

UserGroupInformation.loginUserFromKeytabAndReturnUGI( ... );

Esto me UserGroupInformation instancia de UserGroupInformation y la guardo para toda la vida de la aplicación. Cuando hago una acción privilegiada, las ugi.doAs(action) con ugi.doAs(action) .

Esto funciona bien, pero me pregunto si debería renovar el ticket kerberos en UserGroupInformation y UserGroupInformation . Encontré un método UserGroupInformation.checkTGTAndReloginFromKeytab() que parece hacer la renovación del ticket cada vez que se acerca el vencimiento. También descubrí que este método está siendo llamado por varias herramientas de Hadoop como WebHdfsFileSystem por ejemplo.

Ahora, si quiero que mi aplicación de servidor (posiblemente ejecutándose durante meses o incluso años) nunca experimente el vencimiento del ticket, ¿cuál es el mejor enfoque? Para proporcionar preguntas concretas:

  1. ¿Puedo confiar en los diversos clientes de Hadoop a los que llaman checkTGTAndReloginFromKeytab cuando sea necesario?
  2. ¿Debería llamar alguna vez checkTGTAndReloginFromKeytab yo mismo en mi código?
  3. Si es así, ¿debo hacerlo antes de cada llamada a ugi.doAs(...) o más bien configurar un temporizador y llamarlo periódicamente (con qué frecuencia)?