私はHadoopにかなり慣れていません。ただし、私はサーバーのクラスターモードでJava 7を使用してhadoop 2.7.3を正常にセットアップできました。すべてが完全に正常に動作します。
しかし、Java 8に切り替えてdfsを起動しようとすると、エラーが発生します。
Exception in thread "main" Java.io.IOException: failure to login
at org.Apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.Java:824)
at org.Apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.Java:761)
at org.Apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.Java:634)
at org.Apache.hadoop.hdfs.tools.GetConf.run(GetConf.Java:315)
at org.Apache.hadoop.util.ToolRunner.run(ToolRunner.Java:70)
at org.Apache.hadoop.util.ToolRunner.run(ToolRunner.Java:84)
at org.Apache.hadoop.hdfs.tools.GetConf.main(GetConf.Java:332)
Caused by: javax.security.auth.login.LoginException: Java.lang.NullPointerException: invalid null input: name
at com.Sun.security.auth.UnixPrincipal.<init>(UnixPrincipal.Java:71)
at com.Sun.security.auth.module.UnixLoginModule.login(UnixLoginModule.Java:133)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:498)
at javax.security.auth.login.LoginContext.invoke(LoginContext.Java:755)
at javax.security.auth.login.LoginContext.access$000(LoginContext.Java:195)
at javax.security.auth.login.LoginContext$4.run(LoginContext.Java:682)
at javax.security.auth.login.LoginContext$4.run(LoginContext.Java:680)
at Java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.Java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.Java:587)
at org.Apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.Java:799)
at org.Apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.Java:761)
at org.Apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.Java:634)
at org.Apache.hadoop.hdfs.tools.GetConf.run(GetConf.Java:315)
at org.Apache.hadoop.util.ToolRunner.run(ToolRunner.Java:70)
at org.Apache.hadoop.util.ToolRunner.run(ToolRunner.Java:84)
at org.Apache.hadoop.hdfs.tools.GetConf.main(GetConf.Java:332)
at javax.security.auth.login.LoginContext.invoke(LoginContext.Java:856)
at javax.security.auth.login.LoginContext.access$000(LoginContext.Java:195)
at javax.security.auth.login.LoginContext$4.run(LoginContext.Java:682)
at javax.security.auth.login.LoginContext$4.run(LoginContext.Java:680)
at Java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.Java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.Java:587)
at org.Apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.Java:799)
... 6 more
Hadoopがたまたまワーカーのユーザー名を使用してログインできないようです。他のソースから調べて、環境変数HADOOP_USER_NAME
の追加、datanodeとnamenode全体の削除とリセットなどのガイダンスに従いましたが、この場合、どれも機能しません。
この問題の奇妙な点は、Java 7.に切り替えようとしたときに、Hadoopが以前と同じように正常に動作することです。しかし、 Java Hadoopはドキュメントに基づいて両方のバージョンと互換性があるため、バージョン間に違いがあります。また、信頼できるsshがクラスター内にすでに設定されています。
以下は私の.bashrc設定fyiです:
export Java_HOME="/scratch/dsat_server/jdk1.8.0_121"
export HADOOP_PREFIX="/scratch/dsat_server/hadoop-2.7.3"
export HADOOP_COMMON_LIB_NATIVE_DIR="$HADOOP_PREFIX/lib/native"
export HADOOP_CONF_DIR="$HADOOP_PREFIX/conf"
export HADOOP_OPTS="-Djava.net.preferIPv4Stack=truei-Djava.library.path=$HADOOP_PREFIX/lib"
Java 8でDockerコンテナーからhbaseクライアントを実行するときに同じ問題が発生しました。これはクラスcom.Sun.security.auth.module.UnixLoginModule
は、ネイティブコールを使用してUNIXユーザー名を取得します。私の場合、それはdockerでマップされておらず、クラスはNullPointerExceptionをスローします。これは、Hadoop自体のバグではありません。
OSユーザー名の検索をバイパスするようにhadoopに指示するために、すべての初期化の前に次のコード行を追加できました。
UserGroupInformation.setLoginUser(UserGroupInformation.createRemoteUser("hduser"));
あなたのケースでは、サーバーを実行しているので、コードを挿入するオプションは限られています。代わりに2つのオプションがあります。
IDEからのコードsparkコードの実行中に同じエラーに直面しました。
Exception in thread "main" Java.io.IOException: failure to login
at org.Apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.Java:822)
at org.Apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.Java:774)
at org.Apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.Java:647)
at org.Apache.spark.util.Utils$$anonfun$getCurrentUserName$1.apply(Utils.scala:2464)
at org.Apache.spark.util.Utils$$anonfun$getCurrentUserName$1.apply(Utils.scala:2464)
at scala.Option.getOrElse(Option.scala:121)
at org.Apache.spark.util.Utils$.getCurrentUserName(Utils.scala:2464)
at org.Apache.spark.SparkContext.<init>(SparkContext.scala:292)
at org.Apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2486)
at org.Apache.spark.sql.SparkSession$Builder$$anonfun$7.apply(SparkSession.scala:930)
at org.Apache.spark.sql.SparkSession$Builder$$anonfun$7.apply(SparkSession.scala:921)
at scala.Option.getOrElse(Option.scala:121)
at org.Apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:921)
at SimpleApp$.main(SimpleApp.scala:17)
at SimpleApp.main(SimpleApp.scala)
Caused by: javax.security.auth.login.LoginException:
Java.lang.NullPointerException: invalid null input: name
解決策は、メインコードに次のステートメントを追加しました。
UserGroupInformation.setLoginUser(UserGroupInformation.createRemoteUser("vyxx"))
Dockerイメージがjenkinsユーザーに対して適切に構成されていることを確認すれば、コードで特別な対策を講じる必要がないことがわかりました。 Debian/Ubuntuベースのイメージのjenkinsユーザーのイメージをセットアップするために使用するコードは次のとおりです。
# Add Jenkins user
groupadd --gid 1000 jenkins
useradd --uid 1000 --gid jenkins --Shell /bin/bash --home-dir /var/jenkins_home jenkins
mkdir /var/jenkins_home
chown 1000:1000 /var/jenkins_home
echo 'jenkins ALL=NOPASSWD: ALL' >> /etc/sudoers.d/50-jenkins
echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep