Implementación de la autenticación de seguridad del marco Spark
Con el uso de clústeres de big data, la seguridad de big data ha recibido cada vez más atención. Al utilizar un clúster de big data seguro, el trabajo de operación y mantenimiento debe ser más complicado que el de un clúster normal.
La seguridad del clúster generalmente se basa en el clúster Kerberos para completar la autenticación de seguridad. Para conocer los principios básicos de Kerberos, consulte: Un diagrama para comprender el proceso de acceso a Kerberos
Cuando la aplicación Spark (modo On Yarn) accede de forma segura al clúster de Hadoop, necesita acceder a varios componentes/procesos. como ResourceManager y NodeManager, NameNode, DataNode, Kafka, Hmaster, HregionServer, MetaStore, etc. Especialmente en aplicaciones de larga duración como sparkStreaming, StructedStreaming, etc., cómo garantizar la validez a largo plazo de los usuarios después de ser autenticados, la seguridad/autenticación es más compleja.
La aplicación Spark envía al usuario a kdc para completar la autenticación del usuario y obtener un ticket para el servicio correspondiente antes de acceder al servicio correspondiente. Dado que la aplicación Spark implica el cliente de hilo, el controlador, el maestro de la aplicación, el ejecutor y otros servicios durante la ejecución, cada proceso debe ser iniciado y ejecutado por el mismo usuario. Esto implica el problema de utilizar el mismo ticket de usuario para acceder a varios servicios en múltiples procesos. Analiza brevemente esto basado en Spark2.3.
Las aplicaciones Spark solo se pueden enviar después de que el usuario esté autenticado, por lo que la lógica para realizar la autenticación de inicio de sesión relacionada con la autenticación Kerberos está incluida en Yarnclient/driver. Sin embargo, otros procesos, como applicationMaster, ejecutor, etc., deben autenticarse. La aplicación se inicia después de ser enviada por el usuario. Estos procesos no pueden realizar la autenticación Kerberos, pero utilizan el mecanismo de token de Hadoop para completar la autenticación, lo que reduce la presión. en el servicio Kerberos, al tiempo que mejora la eficiencia del acceso.
La clase base de implementación del token de Hadoop es org.apache.hadoop.security.token. Por ejemplo, NMTokenIdentifier, AMRMTokenIdentifier, AuthenticationTokenIdentifier y otros tokenIdentifiers diferentes se pueden utilizar para diferenciar tokens para diferentes tipos de servicios.
Yarnclient se refiere al token enviado al ResourceManager para enviar aplicaciones de hilo. En Spark, hay dos aplicaciones que envían solicitudes a Yarn: Yarn-Client y Yarn-cluster. La lógica del cliente Yarn es ligeramente diferente en estos dos modos de envío de aplicaciones.
Mecanismo de autenticación de inicio de sesión de usuario de Spark en un escenario de aplicación hadoop seguro
En el método submitApplication del cliente, envíe la aplicación y luego cree amContext para preparar los recursos locales. el archivo local se cargará en HDFS, incluido el archivo keytab, y se generará el archivo de configuración spark_conf .properties para que lo use.
El archivo de configuración contendrá la configuración de la tabla de claves
donde amKeytabFileName se establece de la siguiente manera en setUpCredentials, especificando el valor del archivo de tabla de claves más un sufijo de cadena aleatorio, dependiendo del enfoque de uso de am; consulte la siguiente sección.
Obtenga el token del componente relevante. Nota: El token aquí no es el token relacionado con la interacción del servicio Yarn. Solo se refiere al token que interactúa con los servicios HDFS, HBASE y Hive.
}
Los servicios a los que Spark accede con frecuencia mediante el mecanismo de token incluyen hive, hbase, hdfs y los tokens correspondientes. Tomando hdfs como ejemplo, el tokenProvider correspondiente es el siguiente:
Tomando HbaseDelegationTokenProvider como ejemplo, el método contieneTOken de la clase TokenUtil de hbase se llama principalmente a través de la reflexión, y el método contieneDelegationTokens correspondiente es el siguiente: p>
PD: Los usuarios que obtienen tokens de HBase necesitan permisos de ejecución en la tabla hbase:meta; de lo contrario, no podrán obtener el token con éxito
Después de obtener el token, el token será configúrelo en amContainer y colóquelo en appContext
En el modo cliente de hilo, el controlador se inicia en el proceso de cliente de hilo, que también necesita acceder a la capa empresarial y los componentes relacionados del clúster (como HDFS). El controlador garantiza que el token del nodo del controlador sea válido leyendo el archivo de credenciales actualizado de am en la ruta hdfs.
En el modo de clúster de Yarn, el controlador se ejecuta en la JVM de applicationMaster y su seguridad la maneja Am.
ApplicationMaster es el núcleo de la programación/administración de aplicaciones de Yarn y necesita trabajar con RM /NM y otras interacciones para ejecutar la aplicación. Las interacciones se autentican mediante tokens y la validación se realiza mediante el marco interno de Yarn. Al observar los registros de am, se muestra que los tokens se usan incluso en escenarios no seguros (no kerberos), y las interacciones con hdfs, hbase y otros servicios usan tokens, que deben ser implementados por el marco Spark.
Después de recibir el ApplicationSubmissionContext enviado por la aplicación, ResourceManager configura el método de ejecución de AmLauncher.java para generar "YARN_AM_RM_TOKEN" para la comunicación con rm. AM_RM_TOKEN, este token se utiliza para que am se comunique con RM"
Después de iniciar Am, solicitará un contenedor al ResourceManager y se comunicará con el NodeManager correspondiente para iniciar el contenedor.
Al observar la clase AMRClientImpl, puede ver que AM enviará una solicitud de asignación al RM y, después de que el RM reciba la solicitud, colocará el token del nodo NM al que está asignado el contenedor en la respuesta y lo devolverá a el AM. El NMToken se guarda y se determina si es necesario actualizarlo.
YARN_AM_RM_TOKEN
RM responde a la solicitud de ubicación a través de ApplicationMasterService
AM establece el token del usuario actual en ContainerLaunchContext cuando se prepara para iniciar el contenedor
Compruebe si el token de Am es Cómo configurarlo en ContainerLaunchContext. p>
Vea el comando de inicio de Am de la siguiente manera. Puede ver que hay un archivo de configuración específico, que se genera para Yarnclient y se carga en hdfs, y NodeManager lo copia desde hdfs a la ruta local. uso del contenedor:
Vea el archivo de configuración, puede ver los siguientes elementos de configuración:
La siguiente figura muestra los archivos de recursos utilizados por el proceso am.
Como se muestra en la figura anterior, aunque am se ejecuta en un clúster, los recursos relacionados con la autenticación ya están implementados en tiempo de ejecución. A continuación se analizará su lógica de seguridad en ejecución
En ApplicationMaster, los tokens se actualizarán periódicamente, los archivos se escribirán en directorios relevantes en hdfs y los archivos antiguos se limpiarán para que los utilice cada ejecutor.
Después de que se inicie ApplicationMaster, inicie sesión e inicie un hilo dameon llamado am-kerberos-renewer para iniciar sesión regularmente y garantizar la validez de la autenticación del usuario
private val ugi = {
val original = UserGroupInformation.getCurrentUser()
Inicie el hilo AMCredentialRenewerStarter en am para programar el inicio de sesión de autenticación y la lógica de actualización del token
En ScheduleLoginFromKeytab
La lógica central es la siguiente
Ciclo de programación:
Proceso de programación:
La autenticación del ejecutor también utiliza el mecanismo de token. Una vez que se inicia el ejecutor, comienza según ${spark.yarn.credentials.file} que se establece cuando se inicia el controlador. Actualización del token:
La actualización del token en el ejecutor leerá los archivos en el directorio {timeStamp}-${nextSuffix} en el directorio hdfs y los leerá en el caché para garantizar que el token de actualización se use. .
El mecanismo del marco Spark para la autenticación Kerberos y el uso de tokens para interactuar con otros servicios es relativamente sencillo de usar, solo necesita agregar --principal appuserName - a la línea de comando spark-submit al enviar su aplicación. -keytab /ruta/a/usuario.keytab.