Я пытаюсь запустить Spark в Kubernetes с целью обработки данных из кластера Kerberized Hadoop. Мое приложение состоит из простых преобразований SparkSQL. Хотя я могу успешно запустить процесс на одном модуле драйвера, я не могу сделать это при попытке использовать каких-либо исполнителей. Вместо этого я получаю:
org.apache.hadoop.security.AccessControlException: SIMPLE
аутентификация не включена. В наличии: [ТОКЕН, КЕРБЕРОС]
Поскольку среда Hadoop имеет Kerberized, я предоставил действительную таблицу ключей, а также core-site.xml, hive-site.xml, hadoop-site.xml, mapred-site.xml и yarn-site. xml и файл krb5.conf внутри образа докера.
Я установил настройки среды следующим способом:
trait EnvironmentConfiguration {
def configureEnvironment(): Unit = {
val conf = new Configuration
conf.set("hadoop.security.authentication", "kerberos")
conf.set("hadoop.security.authorization", "true")
conf.set("com.sun.security.auth.module.Krb5LoginModule", "required")
System.setProperty("java.security.krb5.conf", ConfigurationProperties.kerberosConfLocation)
UserGroupInformation.loginUserFromKeytab(ConfigurationProperties.keytabUser, ConfigurationProperties.keytabLocation)
UserGroupInformation.setConfiguration(conf)
}
Я также передаю файлы * -site.xml следующим способом:
trait SparkConfiguration {
def createSparkSession(): SparkSession = {
val spark = SparkSession.builder
.appName("MiniSparkK8")
.enableHiveSupport()
.master("local[*]")
.config("spark.sql.hive.metastore.version", ConfigurationProperties.hiveMetastoreVersion)
.config("spark.executor.memory", ConfigurationProperties.sparkExecutorMemory)
.config("spark.sql.hive.version", ConfigurationProperties.hiveVersion)
.config("spark.sql.hive.metastore.jars",ConfigurationProperties.hiveMetastoreJars)
spark.sparkContext.hadoopConfiguration.addResource(new Path(ConfigurationProperties.coreSiteLocation))
spark.sparkContext.hadoopConfiguration.addResource(new Path(ConfigurationProperties.hiveSiteLocation))
spark.sparkContext.hadoopConfiguration.addResource(new Path(ConfigurationProperties.hdfsSiteLocation))
spark.sparkContext.hadoopConfiguration.addResource(new Path(ConfigurationProperties.yarnSiteLocation))
spark.sparkContext.hadoopConfiguration.addResource(new Path(ConfigurationProperties.mapredSiteLocation))
}
}
Я запускаю весь процесс с помощью следующей команды spark-submit:
spark-submit ^
--master k8s://https://kubernetes.example.environment.url:8443 ^
--deploy-mode cluster ^
--name mini-spark-k8 ^
--class org.spark.Driver ^
--conf spark.executor.instances=2 ^
--conf spark.kubernetes.namespace=<company-openshift-namespace> ^
--conf spark.kubernetes.container.image=<company_image_registry.image> ^
--conf spark.kubernetes.driver.pod.name=minisparkk8-cluster ^
--conf spark.kubernetes.authenticate.driver.serviceAccountName=spark ^
local:///opt/spark/examples/target/MiniSparkK8-1.0-SNAPSHOT.jar ^
/opt/spark/mini-spark-conf.properties
Приведенных выше конфигураций достаточно для запуска моего приложения spark и успешного подключения к кластеру Kerberized Hadoop. Хотя команда spark submit объявляет о создании двух модулей-исполнителей, этого не происходит, потому что я установил master в local[*]
. Следовательно, создается только один модуль, который может подключиться к кластеру Kerberized Hadoop и успешно выполнить мои преобразования Spark для таблиц Hive.
Однако, когда я удаляю .master(local[*])
, создаются два модуля-исполнителя. Из логов видно, что эти исполнители успешно подключаются к модулю драйверов, и им назначены задачи. После этого момента они оба не потерпят неудачу с упомянутой выше ошибкой, что приведет к завершению работы модулей с ошибками исполнителя.
И это несмотря на то, что у исполнителей уже есть все необходимые файлы для создания успешного соединения с Kerberized Hadoop внутри их образа. Я считаю, что исполнители не используют keytab, что они сделали бы, если бы они работали с JAR. Вместо этого они выполняют задачи, данные им из драйвера.
Из журналов видно, что драйверу удается правильно аутентифицировать себя с помощью keytab для пользователя, USER123
:
INFO SecurityManager: 54 - SecurityManager: аутентификация отключена;
пользовательский интерфейс отключен; пользователи с разрешениями на просмотр: Set (spark, USER123);
группы с разрешениями на просмотр: Set (); пользователи с правами на изменение:
Комплект (свеча, USER123); группы с правами на изменение: Set ()
С другой стороны, вы получаете следующее из журнала исполнителя, вы видите, что пользователь, USER123 не аутентифицирован:
INFO SecurityManager: 54 - SecurityManager: аутентификация отключена;
пользовательский интерфейс отключен; пользователи с разрешениями на просмотр: Set (искра); группы
с разрешениями на просмотр: Set (); пользователи с правами на изменение:
Набор (искры); группы с правами на изменение: Set ()
Я посмотрел на различные источники, в том числе здесь . В нем упоминается, что HIVE_CONF_DIR
необходимо определить, но я могу видеть из моей программы (которая печатает переменные окружения), что эта переменная отсутствует, в том числе, когда модулю драйвера удается аутентифицировать себя и нормально запустить процесс spark.
Я попытался запустить следующее добавленное к предыдущей команде spark-submit:
--conf spark.kubernetes.kerberos.enabled=true ^
--conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf ^
--conf spark.kubernetes.kerberos.keytab=/var/keytabs/USER123.keytab ^
--conf spark.kubernetes.kerberos.principal=USER123@REALM ^
Но это не имело значения.
Мой вопрос: как я могу заставить исполнителей аутентифицировать себя с помощью keytab, который они имеют на своем изображении? Я надеюсь, что это позволит им выполнять свои делегированные задачи.