SlideShare una empresa de Scribd logo
Spark + Kerberos
Noviembre 2016
Meetup
Jorge López-Malla Matute
INDEX
jlopezm@stratio.com
Abel Rincón Matarranz
arincon@stratio.com
Introducción al Big Data y la seguridad
● Seguridad Perimetral
1
3
Kerberos
● Introducción
● El protocolo
2
4Arquitectura Spark y Seguridad
● Standalone
● YARN/Mesos clietn
● Mesos Cluster
● YARN/Mesos y Kerberos.
● Spark y seguridad
RoadTrip
● Stratio Requirements
● Spark Package
● Añadiendo user a RDD
● Task/Scheduler
● Kerberos User
● SaveAs…
● Wrappers
● SparkSQL
● Spark 2.0
Presentación
Presentación
JORGE LÓPEZ-MALLA
Tras trabajar con algunas
metodologías tradicionales
empecé a centrarme en el
mundo del Big Data, del cual
me enamoré. Ahora soy
arquitecto Big Data en Stratio y
he puesto proyectos en
producción en distintas partes
del mundo.
SKILLS
Presentación
Presentación
ABEL RINCÓN MATARRANZ
SKILLS
Introducción al Big
Data y la seguridad1
Seguridad y Big Data
• La mayoría de las tecnologías Big Data se toman la seguridad como algo
secundario, en el mejor de los casos
• Una prueba de esto es: ¿habéis visto al claim de seguridad en estas tecnologías?
• Los cluster de Big Data normalmente relegan la seguridad en poner una barrera
alrededor del cluster.
• Desde que HDFS se integró con Kerberos, Kerberos es el protocolo de
autenticación por defecto para tecnologías Big Data
Introducción al Big Data y la seguridad
Seguridad Perimetral
Introducción al Big Data y la seguridad
Seguridad Perimetral
Introducción al Big Data y la seguridad
• Se establece una única máquina de acceso y se securiza la entrada a esa máquina
• Segundo inconveniente: Los datos no se pueden poder usar desde fuera
del cluster. Gran lastre con las herramientas de BI
y analiticas actuales.
• Primer inconveniente: No suelen permitir multitud de usuarios concurrente
operando a la vez en el cluster
Kerberos2
Kerberos
Kerberos
• ¿Qué es Kerberos?
○ Servicio de autenticación
■ Seguro
■ Single-sign-on
■ Basado en confianza
■ Autenticación mutua
Kerberos-Terminología
Kerberos
• Principal → Nombre (userName / serviceName)
• Realm → Entorno( DEMO.MEETUP.COM)
• Cliente/Servicio → usuario a nivel de kerberos
• KDC → servicio de distribución de claves
• TGT → contiene la sesión del cliente
• TGS → contiene la sesión del servicio
Kerberos Protocolo
Kerberos
1. Se especifica el nombre del cliente
2. Petición de TGT
3. KDC envía la clave de sesión con el TGT
4. El cliente manda el TGT y la petición de
TGS
5. KDC devuelve el TGS
6. El cliente manda el TGS al servicio
7. Se establece la conexión entre cliente y
servicio cifrada con la clave de sesión del
servicio
Kerberos-Impersonación
Kerberos
Arquitectura Spark3
Arquitectura Spark
• Un cluster de Spark puede ser gestionado de tres maneras distintas:
○ Standalone: Denominado así porque el propio Spark se gestiona su cluster.
■ Master y Workers.
■ No tiene ninguna implementación con Kerberos.
○ Mesos: Gestor de recursos por el que nace Spark.
■ Master y Agents.
■ Mesosphere añade una implementación con Kerberos.
○ YARN: Gestor de trabajos de Hadoop.
■ Resource Manager y Node Managers.
■ Tiene una implementación con Kerberos que depende de HDFS.
Arquitectura Spark
Standalone
Arquitectura Spark
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Driver
Master
Worker-1 Worker-2
Executor-0 Executor-1
Task-0 Task-1Task-2 Task-3
HDFS
Mesos/YARN - client
Arquitectura Spark
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Driver
Mesos Master/Resource Manager
Agent/
NodeManager-1
Executor-0 Executor-1
Task-0 Task-1Task-2 Task-3
HDFS
Agent/
NodeManager-2
Executor-0 Executor-1
Mesos - Cluster
Arquitectura Spark
Mesos Master
Agent-2
Executor-1 Executor-2
Task-0 Task-1Task-2 Task-3
HDFS
Agent-3
Executor-0 Executor-1
Agent-1
Executor-0
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Spark dispatcher
Driver
Driver
Mesos y Kerberos
Arquitectura Spark
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Driver
Mesos Master/Resource Manager
Agent/
NodeManager-1
Executor-0 Executor-1
Task-0 Task-1Task-2 Task-3
HDFS
Agent/
NodeManager-2
Executor-0 Executor-1
tgt/keytab 64
Spark y seguridad
• Kerberos no es la única medida de seguridad de Spark
• ACLs para modificación de Jobs.
• Securización de comunicaciones mediante TLS.
○ Driver con Executors -> Sólo en versiones anteriores a la 2.0.
○ File Server: files y broadcast -> todas las versiones.
○ Webs: Standalone Master/Slave, history Server y Application UI.
• La seguridad mejora en cada nueva versión de Spark.
Arquitectura Spark
Spark y Seguridad
Arquitectura Spark
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Driver
Mesos Master
Agent-1
Executor-0 Executor-1
Task Task-1
HDFS
Agent-2
Executor-0 Executor-1
encriptación TLS
Kerberos
file1
file1
file1
Spark y Seguridad
Arquitectura Spark
Main {
…..
….
sc = new SparkContext()
rdd1 = sc.textFile.map()
rdd1.saveAs….
}
Driver
Mesos Master
Agent-1
Executor-0 Executor-1
Task Task-1
HDFS
Agent-2
Executor-0 Executor-1
encriptación TLS
Kerberos
file1
file1
file1
Road Trip
4
XData
• XData es un framework distribuido con tecnología de Apache Spark.
• Tiene dos modos Server y librería.
• Puede usarse con herramientas BI, mediante una API Java/Scala y con una shell
interactiva.
• no hay tls y tienen plugin de AAA.
• Cuando usa un Cluster de Spark es agnóstico de Cluster Manager.
• Puede mezclar Streaming con Batch.
StratioRequirements
Road Trip
StratioRequirements
Impersonación en tiempo real
• Como Usuario Final de Crossdata necesito autenticarme contra el backend de
datos en mi nombre para tener una gestión de permisos individualizada en él.
• Crossdata en modo servidor tiene como particularidad, el uso de un contexto
“infinito”
• Crossdata usará un principal propio para el servicio
• Crossdata da soporte a varios usuarios sobre la misma sesión
• Spark se debe autenticar sobre hdfs como el usuario final no como crossdata
Road Trip
¿Por qué no nos valen las soluciones actuales?
• CrossData es agnóstico al cluster manager, ergo debería poder usar cualquiera de
los tres.
• Ninguna de las dos soluciones actuales (YARN ni Mesos) permite la
impersonación
• Sólo se permite un usuario por Executor/YARN Containner
• Además de autenticar en los Executors hay que autenticar en el Driver
• No deberíamos limitarnos a Hadoop ni a Kerberos.
StratioRequirements
Road Trip
Consideraciones Previas
• Se va a usar un Único Principal/Keytab y se usarán Usuarios Proxyficados
• Se tiene que permitir ejecuciones de varios usuarios en el mismo cluster con la
mínima intervención de los mismos
• La solución no puede ser dependiente de particularidades de Cluster Managers
StratioRequirements
Road Trip
• Primera Idea
○ El primer intento fue hacer un SecuredRDD.
○ Se añadiría al Spark Packages
○ Sólo se permite un usuario por Executor/YARN Containner
Spark Packages
Road Trip
• Resultado
○ Aunque podíamos autentificar en el Driver NO se puede hacer nada en los
Executor -> Hay que tocar el API de Task
○ Se aprende que hay que meter el usuario en los RDD para poder pasarlos del
Driver a los executors
Task/Scheduler
Road Trip
private[spark] abstract class Task[T](
val stageId: Int,
val stageAttemptId: Int,
val partitionId: Int,
internalAccumulators: Seq[Accumulator[Long]],
proxyUser: Option[String]) extends Serializable
with Logging{
class DAGScheduler(...){
…
…
val tasks: Seq[Task[_]] = try {
val stageUser = KerberosUser.getMaybeUser
stage match {
case stage: ShuffleMapStage =>
partitionsToCompute.map { id =>
val locs = taskIdToLocations(id)
val part = stage.rdd.partitions(id)
new ShuffleMapTask(stage.id, stage.latestInfo.attemptId,
taskBinary, part, locs, stage.internalAccumulators, stageUser)
}
case stage: ResultStage =>
val job = stage.activeJob.get
partitionsToCompute.map { id =>
val p: Int = stage.partitions(id)
val part = stage.rdd.partitions(p)
val locs = taskIdToLocations(id)
new ResultTask(stage.id, stage.latestInfo.attemptId,
taskBinary, part, locs, id, stage.internalAccumulators, stageUser)
}
}
Task/Scheduler
Road Trip
• Se vio que era necesario añadir un usuario a cada RDD para controlar los accesos
en Driver/Executor
• Primero se optó por añadir campos a los métodos que crean RDD provenientes
de Hadoop
• Primera prueba con usuarios dentro de RDDs:
○ Resultado:
Añadiendo Usuarios a RDD
Road Trip
¡Éxito!
• No termina de ser una solución “limpia”
○ Si se crea un método para crear RDDs lo deberíamos sobreescribir
• Se opta por añadir un método setUser a nivel de RDD que configura los usuarios
antes de calcular sus particiones
• Primera prueba con usuarios en un método de RDD:
○ Resultado:
Añadiendo Usuarios a RDD
Road Trip
¡Fracaso!
user = user1user = None
• Se necesita calcular el usario en el base RDD
Añadiendo Usuarios a RDD
Road Trip
scala:> sc.texFile(“numbers.txt”).map(string => string.toInt).setUser(“user1”).collect
HDFS
map setUser
user = None user = None user = user1
map setUser
user = None user = None
• Segunda prueba con usuarios en un método de RDD:
○ Resultado:
Añadiendo Usuarios a RDD
Road Trip
¡Éxito!
• Primera prueba con larga duración (Streaming)
○ Resultado: ¡Fracaso!
• Errores de renovación de credenciales
KerberosUser (Utils)
object KerberosUser extends Logging with UserCache {
private lazy val getConfiguration: Option[(String, String)] = {
val principal = env.conf.getOption("spark.executor.kerberos.principal")
val keytab = env.conf.getOption("spark.executor.kerberos.keytab")
(principal, keytab) match {
case (Some(p), Some(k)) => Option(p, k)
case _ => None
}
}
def setProxyUser(user: String): Unit = proxyUser = Option(user)
private def userFromKeyTab(proxyUser: Option[String]): Option[UserGroupInformation] = {
val keytab = getConfiguration.get._2
val realUser = Try(UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal.get, keytab)).toOption
realUser.get.setAuthenticationMethod(AuthenticationMethod.KERBEROS)
val user = (realUser, proxyUser) match {
case (Some(real), Some(proxy)) => Option(UserGroupInformation.createProxyUser(proxy, real))
case (Some(real), None) => realUser
case (None, None) => None
}
if (user.isDefined)
putCacheUser(proxyUser.getOrElse(principal.get),user)
user
}
Configuración
Set del proxy user
Decide si usa
el usuario real
o el proxy y
alimenta / usa
la caché de
usuarios
Road Trip
class PairRDDFunctions[K, V](self: RDD[(K, V)])
(implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null)
...
def saveAsHadoopDataset(conf: JobConf): Unit = self.withScope {
val internalSave: (JobConf => Unit) = (conf: JobConf) => {
// Rename this as hadoopConf internally to avoid shadowing (see SPARK-2038).
val hadoopConf = conf
...
val writeToFile = (context: TaskContext, iter: Iterator[(K, V)]) => {
….
}
self.context.runJob(self, writeToFile)
writer.commitJob()
}
KerberosUser.getUserByName(self.user) match {
case Some(user) => {
user.doAs(new PrivilegedExceptionAction[Unit]() {
@throws(classOf[Exception])
def run: Unit = internalSave(conf)
})
}
case None => internalSave(conf)
}
}
saveAs….
Road Trip
Método real de
guardado con Spark
wrapper de método de
guardar hecho por Spark
ejecución autentificada
con Kerberos
• Segunda prueba EndToEnd
○ Se prueba el mismo fichero con SparkSQL
○ Resultado: ¡Fracaso!
• Primera prueba EndToEnd
○ Se prueba una lectura de un fichero txt para luego escribirlo tras ordenarlo
en otro fichero
○ Resultado: ¡Éxito!
SparkSQL
Road Trip
• Al ser los Datasources de Spark “cajas negras” cada uno hace lo que considera
necesario para funcionar
○ Ej: Parquet lanza un trabajo de Spark sólo para leer el esquema.
• Ya no vale con tener un usuario dentro del RDD, tenemos que tener control
sobre el usuario actual (se cambia en SQL mediante Options)
• ¡Kerberos User!
• Idéntico resultado al guardar (Fallo)
• No sólo tenemos que controlar la carga de datos sino que también la ejecución
de queries
SparkSQL
Road Trip
• Métodos que requieren autentificarse con Kerberos:
DataframeReader:
■ load-> carga un RDD desde un Datasource
○ QueryExecution:
■ toRDD -> ejecuta un queryPlan y lo transforma en RDD[Row]
○ ResolvedDataSource:
■ apply -> crea un nuevo Resolved Datasource para poder leerlo.
SparkSQL
Road Trip
• Segunda prueba EndToEnd
○ Se prueba el mismo fichero con SparkSQL dos veces cambiando el usario
○ Resultado: ¡Éxito!
Wrappers (Utils)
def executeSecure[U, T](proxyUser: Option[String],
funct: (U => T),
inputParameters: U): T = {
KerberosUser.getUserByName(proxyUser) match {
case Some(user) => {
user.doAs(new PrivilegedExceptionAction[T]() {
@throws(classOf[Exception])
def run: T = {
funct(inputParameters)
}
})
}
case None => {
funct(inputParameters)
}
}
}
def executeSecure[T](exe: ExecutionWrp[T]): T = {
KerberosUser.getUser match {
case Some(user) => {
user.doAs(new PrivilegedExceptionAction[T]() {
@throws(classOf[Exception])
def run: T = {
exe.value
}
})
}
case None => exe.value
}
}
class ExecutionWrp[T](wrp: => T) {
lazy val value: T = wrp
}
Road Trip
• Cambios principales:
○ Los Task tiene un properties dentro -> NO SE TOCA SU API
○ La lectura de los Datasources en SQL se hace principalmente en una clase
○ Se intenta guardar el catálogo de SparkSQL en HDFS.
Spark 2.0.
Road Trip
Spark 2.0.
private[spark] abstract class Task[T](
val stageId: Int,
val stageAttemptId: Int,
val partitionId: Int,
internalAccumulators: Seq[Accumulator[Long]],
proxyUser: Option[String]) extends Serializable
with Logging{
Road Trip
Task
* @param localProperties copy of thread-local
properties set by the user on the driver side.
*/
private[spark] abstract class Task[T](
val stageId: Int,
val stageAttemptId: Int,
val partitionId: Int,
// The default value is only used in tests.
val metrics: TaskMetrics =
TaskMetrics.registered,
@transient var localProperties: Properties
= new Properties) extends Serializable {
Spark 2.0.
override def createDatabase(
dbDefinition: CatalogDatabase,
ignoreIfExists: Boolean): Unit = synchronized {
def inner: Unit = {
...
val location = new Path(dbDefinition.locationUri)
val fs = location.getFileSystem(hadoopConfig)
fs.mkdirs(location)
} catch {
case e: IOException =>
throw new SparkException(s"Unable to create database ${dbDefinition.name} as failed " +
s"to create its directory ${dbDefinition.locationUri}", e)
}
catalog.put(dbDefinition.name, new DatabaseDesc(dbDefinition))
}
}
KerberosFunction.executeSecure(KerberosUser.principal, new ExecutionWrp(inner))
}
Road Trip
InMemoryCatalog
crea directorio en
HDFS
def resolveRelation(checkPathExist: Boolean = true): BaseRelation = {
val caseInsensitiveOptions = new CaseInsensitiveMap(options)
val maybeUser = caseInsensitiveOptions.get("user") match {
case user if user.isDefined => user
case _ => KerberosUser.getMaybeUser
}
def inner: BaseRelation = {
...
// This is a non-streaming file based datasource.
case (format: FileFormat, _) =>
val allPaths = caseInsensitiveOptions.get("path") ++ paths
...
val fs = hdfsPath.getFileSystem(sparkSession.sessionState.newHadoopConf())
val qualified = hdfsPath.makeQualified(fs.getUri, fs.getWorkingDirectory)
...
}
}
val relation = KerberosFunction.executeSecure(maybeUser, new ExecutionWrp(inner))
relation
}
Spark 2.0. - DataSource
Road Trip
lee el usuario del
options del DF
crea directorio en
HDFS
Datasources con path
• Segunda prueba EndToEnd
○ Se prueba el mismo fichero con SparkSQL dos veces cambiando el usario
○ Resultado:
• Primera prueba EndToEnd
○ Se prueba una lectura de un fichero txt para luego escribirlo tras ordenarlo
en otro fichero
○ Resultado:
Spark 2.0
Road Trip
¡Éxito!
¡Éxito!
tgstgt
read.format(parquet).path(“/use
r1/b”).option(“user”, “user2”)
read.format(parquet).path(“b”).
option(“user”, “user2”)
toDF.saveAsParquet(“b”)textFile(“a”)
saveAsTextFile(“a”)
Imagen final
Road Trip
Driver Executor
sparkUser
user1
user2
HDFS
tgttgs
¿Se cumplen los requistos iniciales?
• Entrar en Apache Spark*
• Asociar la creación del RDD al “usuario activo”
• Kerberizar sólo las acciones que requieran ser Kerberizadas
• ¿Siempre Kerberos? ¿Por qué?
• Caché de usuarios distribuida
• La dominación mundial
Y después de esto, ¿qué viene?
Road Trip
Ruegos y preguntas
Ruegos y preguntas
¡Esto es todo amigos!
MUCHAS GRACIAS Y ANIMAROS A COMPARTIR CONOCIMIENTO
people@stratio.com
WE ARE HIRING
@StratioBD
Meetup spark + kerberos

Más contenido relacionado

PPTX
Bd nosql clave valor
ODP
Así que pusiste MongoDB. Dime ¿cómo lo administras?
KEY
Redis, base de datos NoSQL clave-valor
PPTX
Mongodb administración
KEY
Aplicaciones web altamente escalables con Redis
PDF
Dbdeployer
PDF
Taller girona
PPT
Nis Vs Ldap
Bd nosql clave valor
Así que pusiste MongoDB. Dime ¿cómo lo administras?
Redis, base de datos NoSQL clave-valor
Mongodb administración
Aplicaciones web altamente escalables con Redis
Dbdeployer
Taller girona
Nis Vs Ldap

La actualidad más candente (8)

PDF
Tec red modulo3-2
PDF
Redis: servidor de estructuras de datos
ODP
Pruebas del servicio web
PDF
Log -Analytics con Apache-Flume Elasticsearch HDFS Kibana
PDF
Kubernetes - #gdglimasummit
PDF
Mejores Prácticas Administración de Base de Datos Oracle
PPTX
Resilient Distributed Dataset - Analisis paper
PDF
Workshop Técnicas Replicacion I
Tec red modulo3-2
Redis: servidor de estructuras de datos
Pruebas del servicio web
Log -Analytics con Apache-Flume Elasticsearch HDFS Kibana
Kubernetes - #gdglimasummit
Mejores Prácticas Administración de Base de Datos Oracle
Resilient Distributed Dataset - Analisis paper
Workshop Técnicas Replicacion I
Publicidad

Similar a Meetup spark + kerberos (20)

PPT
69 claves para conocer Big Data
PPTX
Big Data & Seguridad - Un matrimonio de futuro
PDF
Análisis de datos con Apache Spark
PDF
Congreso Academy Journal Celaya 2017
PPTX
Spark: una chispa con la velocidad del rayo ¿el sustituto de Hadoop?
PDF
Primeros pasos con Apache Spark - Madrid Meetup
PDF
Primeros pasos con Spark - Spark Meetup Madrid 30-09-2014
PDF
6. SPARK.pdf
PPTX
PDF
Industry 4.0 y Big Data ¿Quién está accediendo a tus datos?
PDF
Industry 4.0 y Big Data. ¿Quién está accediendo a tus datos? - LibreCon 2016
PDF
Herramientas para computación distribuida. De Hadoop a Spark
PDF
Meetup Spark y la Combinación de sus Distintos Módulos
PDF
Apache Spark y Big Data
PDF
¿Por que cambiar de Apache Hadoop a Apache Spark?
PDF
Semana de la I+D - Proyecto OPOSSUM
PPTX
Meetup Fun[ctional] spark with scala
PDF
Fun[ctional] spark with scala
PPTX
1.2.1 Ecosistema de Big Data (on-premise).pptx
PPTX
OpenAnalytics Madrid 2014: Spark
69 claves para conocer Big Data
Big Data & Seguridad - Un matrimonio de futuro
Análisis de datos con Apache Spark
Congreso Academy Journal Celaya 2017
Spark: una chispa con la velocidad del rayo ¿el sustituto de Hadoop?
Primeros pasos con Apache Spark - Madrid Meetup
Primeros pasos con Spark - Spark Meetup Madrid 30-09-2014
6. SPARK.pdf
Industry 4.0 y Big Data ¿Quién está accediendo a tus datos?
Industry 4.0 y Big Data. ¿Quién está accediendo a tus datos? - LibreCon 2016
Herramientas para computación distribuida. De Hadoop a Spark
Meetup Spark y la Combinación de sus Distintos Módulos
Apache Spark y Big Data
¿Por que cambiar de Apache Hadoop a Apache Spark?
Semana de la I+D - Proyecto OPOSSUM
Meetup Fun[ctional] spark with scala
Fun[ctional] spark with scala
1.2.1 Ecosistema de Big Data (on-premise).pptx
OpenAnalytics Madrid 2014: Spark
Publicidad

Más de Jorge Lopez-Malla (10)

PDF
Geoposicionamiento Big Data o It's bigger on the inside Codemetion Madrid 2018
PPTX
Geoposicionamiento Big Data o It's bigger on the inside Commit conf 2018
PDF
Haz que tus datos sean sexys
PDF
Mesos con europa 2017
PDF
Spark meetup barcelona
PDF
Spark web meetup
PDF
Kerberizing spark. Spark Summit east
PDF
Codemotion 2016
PPTX
Meetup errores en proyectos Big Data
PDF
Apache Big Data Europa- How to make money with your own data
Geoposicionamiento Big Data o It's bigger on the inside Codemetion Madrid 2018
Geoposicionamiento Big Data o It's bigger on the inside Commit conf 2018
Haz que tus datos sean sexys
Mesos con europa 2017
Spark meetup barcelona
Spark web meetup
Kerberizing spark. Spark Summit east
Codemotion 2016
Meetup errores en proyectos Big Data
Apache Big Data Europa- How to make money with your own data

Último (20)

PDF
Maste clas de estructura metálica y arquitectura
PPTX
RAP01 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
PDF
5.1 Pinch y Bijker en libro Actos, actores y artefactos de Bunch Thomas (coor...
PDF
Liceo departamental MICRO BIT (1) 2.pdfbbbnn
PPTX
REDES INFORMATICAS REDES INFORMATICAS.pptx
PPTX
historia_web de la creacion de un navegador_presentacion.pptx
PDF
Estrategia de apoyo tecnología miguel angel solis
DOCX
Zarate Quispe Alex aldayir aplicaciones de internet .docx
PDF
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
PDF
Instrucciones simples, respuestas poderosas. La fórmula del prompt perfecto.
PPTX
Presentación PASANTIAS AuditorioOO..pptx
PDF
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
PPTX
Power Point Nicolás Carrasco (disertación Roblox).pptx
PPT
Que son las redes de computadores y sus partes
PPTX
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
PPTX
Sesion 1 de microsoft power point - Clase 1
PPTX
Presentación de Redes de Datos modelo osi
PDF
SAP Transportation Management para LSP, TM140 Col18
PPTX
Acronis Cyber Protect Cloud para Ciber Proteccion y Ciber Seguridad LATAM - A...
PPTX
IA de Cine - Como MuleSoft y los Agentes estan redefiniendo la realidad
Maste clas de estructura metálica y arquitectura
RAP01 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
5.1 Pinch y Bijker en libro Actos, actores y artefactos de Bunch Thomas (coor...
Liceo departamental MICRO BIT (1) 2.pdfbbbnn
REDES INFORMATICAS REDES INFORMATICAS.pptx
historia_web de la creacion de un navegador_presentacion.pptx
Estrategia de apoyo tecnología miguel angel solis
Zarate Quispe Alex aldayir aplicaciones de internet .docx
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
Instrucciones simples, respuestas poderosas. La fórmula del prompt perfecto.
Presentación PASANTIAS AuditorioOO..pptx
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
Power Point Nicolás Carrasco (disertación Roblox).pptx
Que son las redes de computadores y sus partes
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
Sesion 1 de microsoft power point - Clase 1
Presentación de Redes de Datos modelo osi
SAP Transportation Management para LSP, TM140 Col18
Acronis Cyber Protect Cloud para Ciber Proteccion y Ciber Seguridad LATAM - A...
IA de Cine - Como MuleSoft y los Agentes estan redefiniendo la realidad

Meetup spark + kerberos

  • 2. Jorge López-Malla Matute INDEX jlopezm@stratio.com Abel Rincón Matarranz arincon@stratio.com Introducción al Big Data y la seguridad ● Seguridad Perimetral 1 3 Kerberos ● Introducción ● El protocolo 2 4Arquitectura Spark y Seguridad ● Standalone ● YARN/Mesos clietn ● Mesos Cluster ● YARN/Mesos y Kerberos. ● Spark y seguridad RoadTrip ● Stratio Requirements ● Spark Package ● Añadiendo user a RDD ● Task/Scheduler ● Kerberos User ● SaveAs… ● Wrappers ● SparkSQL ● Spark 2.0
  • 3. Presentación Presentación JORGE LÓPEZ-MALLA Tras trabajar con algunas metodologías tradicionales empecé a centrarme en el mundo del Big Data, del cual me enamoré. Ahora soy arquitecto Big Data en Stratio y he puesto proyectos en producción en distintas partes del mundo. SKILLS
  • 5. Introducción al Big Data y la seguridad1
  • 6. Seguridad y Big Data • La mayoría de las tecnologías Big Data se toman la seguridad como algo secundario, en el mejor de los casos • Una prueba de esto es: ¿habéis visto al claim de seguridad en estas tecnologías? • Los cluster de Big Data normalmente relegan la seguridad en poner una barrera alrededor del cluster. • Desde que HDFS se integró con Kerberos, Kerberos es el protocolo de autenticación por defecto para tecnologías Big Data Introducción al Big Data y la seguridad
  • 7. Seguridad Perimetral Introducción al Big Data y la seguridad
  • 8. Seguridad Perimetral Introducción al Big Data y la seguridad • Se establece una única máquina de acceso y se securiza la entrada a esa máquina • Segundo inconveniente: Los datos no se pueden poder usar desde fuera del cluster. Gran lastre con las herramientas de BI y analiticas actuales. • Primer inconveniente: No suelen permitir multitud de usuarios concurrente operando a la vez en el cluster
  • 10. Kerberos Kerberos • ¿Qué es Kerberos? ○ Servicio de autenticación ■ Seguro ■ Single-sign-on ■ Basado en confianza ■ Autenticación mutua
  • 11. Kerberos-Terminología Kerberos • Principal → Nombre (userName / serviceName) • Realm → Entorno( DEMO.MEETUP.COM) • Cliente/Servicio → usuario a nivel de kerberos • KDC → servicio de distribución de claves • TGT → contiene la sesión del cliente • TGS → contiene la sesión del servicio
  • 12. Kerberos Protocolo Kerberos 1. Se especifica el nombre del cliente 2. Petición de TGT 3. KDC envía la clave de sesión con el TGT 4. El cliente manda el TGT y la petición de TGS 5. KDC devuelve el TGS 6. El cliente manda el TGS al servicio 7. Se establece la conexión entre cliente y servicio cifrada con la clave de sesión del servicio
  • 15. Arquitectura Spark • Un cluster de Spark puede ser gestionado de tres maneras distintas: ○ Standalone: Denominado así porque el propio Spark se gestiona su cluster. ■ Master y Workers. ■ No tiene ninguna implementación con Kerberos. ○ Mesos: Gestor de recursos por el que nace Spark. ■ Master y Agents. ■ Mesosphere añade una implementación con Kerberos. ○ YARN: Gestor de trabajos de Hadoop. ■ Resource Manager y Node Managers. ■ Tiene una implementación con Kerberos que depende de HDFS. Arquitectura Spark
  • 16. Standalone Arquitectura Spark Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Driver Master Worker-1 Worker-2 Executor-0 Executor-1 Task-0 Task-1Task-2 Task-3 HDFS
  • 17. Mesos/YARN - client Arquitectura Spark Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Driver Mesos Master/Resource Manager Agent/ NodeManager-1 Executor-0 Executor-1 Task-0 Task-1Task-2 Task-3 HDFS Agent/ NodeManager-2 Executor-0 Executor-1
  • 18. Mesos - Cluster Arquitectura Spark Mesos Master Agent-2 Executor-1 Executor-2 Task-0 Task-1Task-2 Task-3 HDFS Agent-3 Executor-0 Executor-1 Agent-1 Executor-0 Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Spark dispatcher Driver Driver
  • 19. Mesos y Kerberos Arquitectura Spark Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Driver Mesos Master/Resource Manager Agent/ NodeManager-1 Executor-0 Executor-1 Task-0 Task-1Task-2 Task-3 HDFS Agent/ NodeManager-2 Executor-0 Executor-1 tgt/keytab 64
  • 20. Spark y seguridad • Kerberos no es la única medida de seguridad de Spark • ACLs para modificación de Jobs. • Securización de comunicaciones mediante TLS. ○ Driver con Executors -> Sólo en versiones anteriores a la 2.0. ○ File Server: files y broadcast -> todas las versiones. ○ Webs: Standalone Master/Slave, history Server y Application UI. • La seguridad mejora en cada nueva versión de Spark. Arquitectura Spark
  • 21. Spark y Seguridad Arquitectura Spark Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Driver Mesos Master Agent-1 Executor-0 Executor-1 Task Task-1 HDFS Agent-2 Executor-0 Executor-1 encriptación TLS Kerberos file1 file1 file1
  • 22. Spark y Seguridad Arquitectura Spark Main { ….. …. sc = new SparkContext() rdd1 = sc.textFile.map() rdd1.saveAs…. } Driver Mesos Master Agent-1 Executor-0 Executor-1 Task Task-1 HDFS Agent-2 Executor-0 Executor-1 encriptación TLS Kerberos file1 file1 file1
  • 24. XData • XData es un framework distribuido con tecnología de Apache Spark. • Tiene dos modos Server y librería. • Puede usarse con herramientas BI, mediante una API Java/Scala y con una shell interactiva. • no hay tls y tienen plugin de AAA. • Cuando usa un Cluster de Spark es agnóstico de Cluster Manager. • Puede mezclar Streaming con Batch. StratioRequirements Road Trip
  • 25. StratioRequirements Impersonación en tiempo real • Como Usuario Final de Crossdata necesito autenticarme contra el backend de datos en mi nombre para tener una gestión de permisos individualizada en él. • Crossdata en modo servidor tiene como particularidad, el uso de un contexto “infinito” • Crossdata usará un principal propio para el servicio • Crossdata da soporte a varios usuarios sobre la misma sesión • Spark se debe autenticar sobre hdfs como el usuario final no como crossdata Road Trip
  • 26. ¿Por qué no nos valen las soluciones actuales? • CrossData es agnóstico al cluster manager, ergo debería poder usar cualquiera de los tres. • Ninguna de las dos soluciones actuales (YARN ni Mesos) permite la impersonación • Sólo se permite un usuario por Executor/YARN Containner • Además de autenticar en los Executors hay que autenticar en el Driver • No deberíamos limitarnos a Hadoop ni a Kerberos. StratioRequirements Road Trip
  • 27. Consideraciones Previas • Se va a usar un Único Principal/Keytab y se usarán Usuarios Proxyficados • Se tiene que permitir ejecuciones de varios usuarios en el mismo cluster con la mínima intervención de los mismos • La solución no puede ser dependiente de particularidades de Cluster Managers StratioRequirements Road Trip
  • 28. • Primera Idea ○ El primer intento fue hacer un SecuredRDD. ○ Se añadiría al Spark Packages ○ Sólo se permite un usuario por Executor/YARN Containner Spark Packages Road Trip • Resultado ○ Aunque podíamos autentificar en el Driver NO se puede hacer nada en los Executor -> Hay que tocar el API de Task ○ Se aprende que hay que meter el usuario en los RDD para poder pasarlos del Driver a los executors
  • 29. Task/Scheduler Road Trip private[spark] abstract class Task[T]( val stageId: Int, val stageAttemptId: Int, val partitionId: Int, internalAccumulators: Seq[Accumulator[Long]], proxyUser: Option[String]) extends Serializable with Logging{
  • 30. class DAGScheduler(...){ … … val tasks: Seq[Task[_]] = try { val stageUser = KerberosUser.getMaybeUser stage match { case stage: ShuffleMapStage => partitionsToCompute.map { id => val locs = taskIdToLocations(id) val part = stage.rdd.partitions(id) new ShuffleMapTask(stage.id, stage.latestInfo.attemptId, taskBinary, part, locs, stage.internalAccumulators, stageUser) } case stage: ResultStage => val job = stage.activeJob.get partitionsToCompute.map { id => val p: Int = stage.partitions(id) val part = stage.rdd.partitions(p) val locs = taskIdToLocations(id) new ResultTask(stage.id, stage.latestInfo.attemptId, taskBinary, part, locs, id, stage.internalAccumulators, stageUser) } } Task/Scheduler Road Trip
  • 31. • Se vio que era necesario añadir un usuario a cada RDD para controlar los accesos en Driver/Executor • Primero se optó por añadir campos a los métodos que crean RDD provenientes de Hadoop • Primera prueba con usuarios dentro de RDDs: ○ Resultado: Añadiendo Usuarios a RDD Road Trip ¡Éxito!
  • 32. • No termina de ser una solución “limpia” ○ Si se crea un método para crear RDDs lo deberíamos sobreescribir • Se opta por añadir un método setUser a nivel de RDD que configura los usuarios antes de calcular sus particiones • Primera prueba con usuarios en un método de RDD: ○ Resultado: Añadiendo Usuarios a RDD Road Trip ¡Fracaso!
  • 33. user = user1user = None • Se necesita calcular el usario en el base RDD Añadiendo Usuarios a RDD Road Trip scala:> sc.texFile(“numbers.txt”).map(string => string.toInt).setUser(“user1”).collect HDFS map setUser user = None user = None user = user1 map setUser user = None user = None
  • 34. • Segunda prueba con usuarios en un método de RDD: ○ Resultado: Añadiendo Usuarios a RDD Road Trip ¡Éxito! • Primera prueba con larga duración (Streaming) ○ Resultado: ¡Fracaso! • Errores de renovación de credenciales
  • 35. KerberosUser (Utils) object KerberosUser extends Logging with UserCache { private lazy val getConfiguration: Option[(String, String)] = { val principal = env.conf.getOption("spark.executor.kerberos.principal") val keytab = env.conf.getOption("spark.executor.kerberos.keytab") (principal, keytab) match { case (Some(p), Some(k)) => Option(p, k) case _ => None } } def setProxyUser(user: String): Unit = proxyUser = Option(user) private def userFromKeyTab(proxyUser: Option[String]): Option[UserGroupInformation] = { val keytab = getConfiguration.get._2 val realUser = Try(UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal.get, keytab)).toOption realUser.get.setAuthenticationMethod(AuthenticationMethod.KERBEROS) val user = (realUser, proxyUser) match { case (Some(real), Some(proxy)) => Option(UserGroupInformation.createProxyUser(proxy, real)) case (Some(real), None) => realUser case (None, None) => None } if (user.isDefined) putCacheUser(proxyUser.getOrElse(principal.get),user) user } Configuración Set del proxy user Decide si usa el usuario real o el proxy y alimenta / usa la caché de usuarios Road Trip
  • 36. class PairRDDFunctions[K, V](self: RDD[(K, V)]) (implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null) ... def saveAsHadoopDataset(conf: JobConf): Unit = self.withScope { val internalSave: (JobConf => Unit) = (conf: JobConf) => { // Rename this as hadoopConf internally to avoid shadowing (see SPARK-2038). val hadoopConf = conf ... val writeToFile = (context: TaskContext, iter: Iterator[(K, V)]) => { …. } self.context.runJob(self, writeToFile) writer.commitJob() } KerberosUser.getUserByName(self.user) match { case Some(user) => { user.doAs(new PrivilegedExceptionAction[Unit]() { @throws(classOf[Exception]) def run: Unit = internalSave(conf) }) } case None => internalSave(conf) } } saveAs…. Road Trip Método real de guardado con Spark wrapper de método de guardar hecho por Spark ejecución autentificada con Kerberos
  • 37. • Segunda prueba EndToEnd ○ Se prueba el mismo fichero con SparkSQL ○ Resultado: ¡Fracaso! • Primera prueba EndToEnd ○ Se prueba una lectura de un fichero txt para luego escribirlo tras ordenarlo en otro fichero ○ Resultado: ¡Éxito! SparkSQL Road Trip
  • 38. • Al ser los Datasources de Spark “cajas negras” cada uno hace lo que considera necesario para funcionar ○ Ej: Parquet lanza un trabajo de Spark sólo para leer el esquema. • Ya no vale con tener un usuario dentro del RDD, tenemos que tener control sobre el usuario actual (se cambia en SQL mediante Options) • ¡Kerberos User! • Idéntico resultado al guardar (Fallo) • No sólo tenemos que controlar la carga de datos sino que también la ejecución de queries SparkSQL Road Trip
  • 39. • Métodos que requieren autentificarse con Kerberos: DataframeReader: ■ load-> carga un RDD desde un Datasource ○ QueryExecution: ■ toRDD -> ejecuta un queryPlan y lo transforma en RDD[Row] ○ ResolvedDataSource: ■ apply -> crea un nuevo Resolved Datasource para poder leerlo. SparkSQL Road Trip • Segunda prueba EndToEnd ○ Se prueba el mismo fichero con SparkSQL dos veces cambiando el usario ○ Resultado: ¡Éxito!
  • 40. Wrappers (Utils) def executeSecure[U, T](proxyUser: Option[String], funct: (U => T), inputParameters: U): T = { KerberosUser.getUserByName(proxyUser) match { case Some(user) => { user.doAs(new PrivilegedExceptionAction[T]() { @throws(classOf[Exception]) def run: T = { funct(inputParameters) } }) } case None => { funct(inputParameters) } } } def executeSecure[T](exe: ExecutionWrp[T]): T = { KerberosUser.getUser match { case Some(user) => { user.doAs(new PrivilegedExceptionAction[T]() { @throws(classOf[Exception]) def run: T = { exe.value } }) } case None => exe.value } } class ExecutionWrp[T](wrp: => T) { lazy val value: T = wrp } Road Trip
  • 41. • Cambios principales: ○ Los Task tiene un properties dentro -> NO SE TOCA SU API ○ La lectura de los Datasources en SQL se hace principalmente en una clase ○ Se intenta guardar el catálogo de SparkSQL en HDFS. Spark 2.0. Road Trip
  • 42. Spark 2.0. private[spark] abstract class Task[T]( val stageId: Int, val stageAttemptId: Int, val partitionId: Int, internalAccumulators: Seq[Accumulator[Long]], proxyUser: Option[String]) extends Serializable with Logging{ Road Trip Task * @param localProperties copy of thread-local properties set by the user on the driver side. */ private[spark] abstract class Task[T]( val stageId: Int, val stageAttemptId: Int, val partitionId: Int, // The default value is only used in tests. val metrics: TaskMetrics = TaskMetrics.registered, @transient var localProperties: Properties = new Properties) extends Serializable {
  • 43. Spark 2.0. override def createDatabase( dbDefinition: CatalogDatabase, ignoreIfExists: Boolean): Unit = synchronized { def inner: Unit = { ... val location = new Path(dbDefinition.locationUri) val fs = location.getFileSystem(hadoopConfig) fs.mkdirs(location) } catch { case e: IOException => throw new SparkException(s"Unable to create database ${dbDefinition.name} as failed " + s"to create its directory ${dbDefinition.locationUri}", e) } catalog.put(dbDefinition.name, new DatabaseDesc(dbDefinition)) } } KerberosFunction.executeSecure(KerberosUser.principal, new ExecutionWrp(inner)) } Road Trip InMemoryCatalog crea directorio en HDFS
  • 44. def resolveRelation(checkPathExist: Boolean = true): BaseRelation = { val caseInsensitiveOptions = new CaseInsensitiveMap(options) val maybeUser = caseInsensitiveOptions.get("user") match { case user if user.isDefined => user case _ => KerberosUser.getMaybeUser } def inner: BaseRelation = { ... // This is a non-streaming file based datasource. case (format: FileFormat, _) => val allPaths = caseInsensitiveOptions.get("path") ++ paths ... val fs = hdfsPath.getFileSystem(sparkSession.sessionState.newHadoopConf()) val qualified = hdfsPath.makeQualified(fs.getUri, fs.getWorkingDirectory) ... } } val relation = KerberosFunction.executeSecure(maybeUser, new ExecutionWrp(inner)) relation } Spark 2.0. - DataSource Road Trip lee el usuario del options del DF crea directorio en HDFS Datasources con path
  • 45. • Segunda prueba EndToEnd ○ Se prueba el mismo fichero con SparkSQL dos veces cambiando el usario ○ Resultado: • Primera prueba EndToEnd ○ Se prueba una lectura de un fichero txt para luego escribirlo tras ordenarlo en otro fichero ○ Resultado: Spark 2.0 Road Trip ¡Éxito! ¡Éxito!
  • 47. • Entrar en Apache Spark* • Asociar la creación del RDD al “usuario activo” • Kerberizar sólo las acciones que requieran ser Kerberizadas • ¿Siempre Kerberos? ¿Por qué? • Caché de usuarios distribuida • La dominación mundial Y después de esto, ¿qué viene? Road Trip
  • 49. ¡Esto es todo amigos! MUCHAS GRACIAS Y ANIMAROS A COMPARTIR CONOCIMIENTO