Spark セキュリティ

Spark セキュリティ: 知っておくべきこと

認証などのセキュリティ機能は、デフォルトでは有効になっていません。インターネットまたは信頼できないネットワークに公開されているクラスタをデプロイする場合、権限のないアプリケーションがクラスタ上で実行されないように、クラスタへのアクセスを保護することが重要です。

Sparkは複数のデプロイメントタイプをサポートしており、それぞれが異なるレベルのセキュリティをサポートしています。すべてのデプロイメントタイプがすべての環境で安全であるとは限らず、デフォルトでは安全ではありません。環境、Sparkがサポートしている内容を評価し、Sparkデプロイメントを保護するための適切な対策を講じてください。

セキュリティに関する懸念事項には、さまざまな種類があります。Sparkは必ずしもすべてのことから保護するわけではありません。Sparkがサポートしている機能の一部を以下に示します。また、使用しているデプロイメントの種類のデプロイメントドキュメントで、デプロイメント固有の設定を確認してください。文書化されていないものは、Sparkではサポートされていません。

Spark RPC (Sparkプロセス間の通信プロトコル)

認証

Sparkは現在、共有シークレットを使用したRPCチャネルの認証をサポートしています。認証は、`spark.authenticate`設定パラメータを設定することで有効にできます。

共有シークレットの生成と配布に使用される正確なメカニズムは、デプロイメントによって異なります。以下に指定がない限り、シークレットは`spark.authenticate.secret`設定オプションを設定することによって定義する必要があります。その場合、同じシークレットがそのSparkアプリケーションとデーモンすべてで共有されるため、特にマルチテナントクラスタでは、これらのデプロイメントのセキュリティが制限されます。

REST送信サーバーとMesosClusterDispatcherは認証をサポートしていません。REST APIとMesosClusterDispatcher(デフォルトではそれぞれポート6066と7077)へのすべてのネットワークアクセスが、ジョブを送信することが信頼されているホストに制限されていることを確認する必要があります。

YARN

YARN上のSparkの場合、Sparkは共有シークレットの生成と配布を自動的に処理します。各アプリケーションは一意の共有シークレットを使用します。YARNの場合、この機能は、シークレットの配布を安全にするためにYARN RPC暗号化が有効になっていることに依存しています。

プロパティ名デフォルト意味バージョン
spark.yarn.shuffle.server.recovery.disabled false セキュリティ要件が高く、シークレットがデータベースに保存されないことを好むアプリケーションの場合は、trueに設定します。このようなアプリケーションのシャッフルデータは、External Shuffle Serviceの再起動後には回復されません。 3.5.0

Kubernetes

Kubernetesでは、Sparkは各アプリケーションに固有の認証シークレットも自動的に生成します。シークレットは、環境変数を使用してexecutorポッドに伝播されます。これは、Sparkアプリケーションが実行されている名前空間でポッドをリストできるユーザーは誰でも、認証シークレットを見ることができることを意味します。Spark認証が安全であることを保証するために、Kubernetes管理者によってアクセス制御ルールが適切に設定されている必要があります。

プロパティ名デフォルト意味バージョン
spark.authenticate false Sparkが内部接続を認証するかどうか。 1.0.0
spark.authenticate.secret なし 認証に使用される秘密鍵。この設定をいつ設定する必要があるかについては、上記を参照してください。 1.0.0

または、ユーザーがポッドにマウントするファイルとKubernetesシークレットを使用して、認証シークレットをマウントできます。

プロパティ名デフォルト意味バージョン
spark.authenticate.secret.file なし 接続の保護に使用する秘密鍵を指すパス。ファイルの内容が安全に生成されていることを確認してください。このファイルは、他の設定でこれがオーバーライドされない限り(下記参照)、ドライバーとexecutorの両方でロードされます。 3.0.0
spark.authenticate.secret.driver.file `spark.authenticate.secret.file`の値 指定した場合、Sparkドライバーがシークレットを読み込む場所をオーバーライドします。クライアントモードで、シークレットファイルの場所がポッドとドライバーが実行されているノードで異なる場合に便利です。これを指定する場合は、`spark.authenticate.secret.executor.file`を指定して、ドライバーとexecutorの両方がファイルを使用して秘密鍵を読み込めるようにする必要があります。ドライバー上のファイルの内容がexecutor上のファイルの内容と同一であることを確認してください。 3.0.0
spark.authenticate.secret.executor.file `spark.authenticate.secret.file`の値 指定した場合、Spark executorがシークレットを読み込む場所をオーバーライドします。クライアントモードで、シークレットファイルの場所がポッドとドライバーが実行されているノードで異なる場合に便利です。これを指定する場合は、`spark.authenticate.secret.driver.file`を指定して、ドライバーとexecutorの両方がファイルを使用して秘密鍵を読み込めるようにする必要があります。ドライバー上のファイルの内容がexecutor上のファイルの内容と同一であることを確認してください。 3.0.0

ファイルを使用する場合、Sparkはこれらのファイルをコンテナにマウントしないことに注意してください。秘密ファイルがコンテナに安全にデプロイされ、ドライバーの秘密ファイルがexecutorの秘密ファイルと一致することを確認するのは、ユーザーの責任です。

暗号化

Sparkは、RPC接続にAESベースの暗号化をサポートしています。暗号化を有効にするには、RPC認証も有効にして適切に設定する必要があります。AES暗号化はApache Commons Cryptoライブラリを使用し、Sparkの設定システムでは、上級ユーザーがそのライブラリの設定にアクセスできます。

SASLベースの暗号化のサポートもありますが、非推奨と見なされるべきです。2.2.0より古いバージョンのSparkからシャッフルサービスと通信する場合には、まだ必要です。

次の表に、この機能の設定に使用できるさまざまなオプションを示します。

プロパティ名デフォルト意味バージョン
spark.network.crypto.enabled false 2.2.0で追加された新しい認証プロトコルを含む、AESベースのRPC暗号化を有効にします。 2.2.0
spark.network.crypto.config.* なし 使用する暗号実装など、commons-cryptoライブラリの構成値。設定名は、`commons.crypto`プレフィックスのないcommons-crypto構成の名前である必要があります。 2.2.0
spark.network.crypto.saslFallback true Sparkの内部メカニズムを使用した認証が失敗した場合に、SASL認証にフォールバックするかどうか。これは、アプリケーションが内部Spark認証プロトコルをサポートしていない古いシャッフルサービスに接続している場合に便利です。シャッフルサービス側では、この機能を無効にすると、古いクライアントが認証できなくなります。 2.2.0
spark.authenticate.enableSaslEncryption false SASLベースの暗号化通信を有効にします。 2.2.0
spark.network.sasl.serverAlwaysEncrypt false SASL認証を使用するポートの暗号化されていない接続を無効にします。これは、認証が有効になっているが、SASLベースの暗号化を要求しないクライアントからの接続を拒否します。 1.4.0

ローカルストレージの暗号化

Sparkは、ローカルディスクに書き込まれた一時データの暗号化をサポートしています。これは、シャッフルファイル、シャッフルスピル、およびディスクに保存されたデータブロック(キャッシングとブロードキャスト変数の両方)をカバーします。`saveAsHadoopFile`や`saveAsTable`などのAPIを使用してアプリケーションによって生成された出力データの暗号化はカバーしていません。また、ユーザーが明示的に作成した一時ファイルをカバーしていない場合もあります。

次の設定は、ディスクに書き込まれたデータの暗号化を有効にすることをカバーしています

プロパティ名デフォルト意味バージョン
spark.io.encryption.enabled false ローカルディスクI/O暗号化を有効にします。現在、Mesosを除くすべてのモードでサポートされています。この機能を使用する場合は、RPC暗号化を有効にすることを強くお勧めします。 2.1.0
spark.io.encryption.keySizeBits 128 IO暗号化キーのサイズ(ビット単位)。サポートされている値は128、192、256です。 2.1.0
spark.io.encryption.keygen.algorithm HmacSHA1 IO暗号化キーの生成時に使用するアルゴリズム。サポートされているアルゴリズムについては、Java暗号化アーキテクチャ標準アルゴリズム名ドキュメントのKeyGeneratorセクションで説明されています。 2.1.0
spark.io.encryption.commons.config.* なし 使用する暗号実装など、commons-cryptoライブラリの構成値。設定名は、`commons.crypto`プレフィックスのないcommons-crypto構成の名前である必要があります。 2.1.0

Web UI

認証と承認

Web UIの認証を有効にするには、javaxサーブレットフィルターを使用します。デプロイする認証方法を実装するフィルターが必要です。Sparkは組み込みの認証フィルターを提供していません。

Sparkは、認証フィルターが存在する場合、UIへのアクセス制御もサポートしています。各アプリケーションは、独自の個別のアクセス制御リスト(ACL)で設定できます。Sparkは、「表示」権限(アプリケーションのUIを表示できるユーザー)と「変更」権限(実行中のアプリケーションでジョブを強制終了するなどの操作を実行できるユーザー)を区別します。

ACLは、ユーザーまたはグループのいずれかに対して設定できます。設定エントリは、入力としてカンマ区切りのリストを受け入れます。つまり、複数のユーザーまたはグループに必要な権限を与えることができます。これは、共有クラスタで実行していて、自分で開始していないアプリケーションを監視する必要がある管理者または開発者のセットがある場合に使用できます。特定のACLに追加されたワイルドカード(`*`)は、すべてのユーザーがそれぞれの権限を持つことを意味します。デフォルトでは、アプリケーションを送信するユーザーのみがACLに追加されます。

グループメンバーシップは、設定可能なグループマッピングプロバイダーを使用して確立されます。マッパーは、以下の表で説明されている`spark.user.groups.mapping`設定オプションを使用して設定されます。

次のオプションは、Web UIの認証を制御します

プロパティ名デフォルト意味バージョン
spark.ui.allowFramingFrom SAMEORIGIN `X-Frame-Options`を介して、特定の名前付きURIのフレーミングを許可します。デフォルトでは、同じ起点からのみ許可します。 1.6.0
spark.ui.filters なし フィルターの設定方法については、Spark UI設定を参照してください。 1.0.0
spark.acls.enable false UI ACLを有効にするかどうか。有効にした場合、ユーザーがアプリケーションを表示または変更するためのアクセス許可を持っているかどうかを確認します。これにはユーザーの認証が必要になるため、認証フィルターがインストールされていない場合、このオプションは何もしません。 1.1.0
spark.admin.acls なし Sparkアプリケーションへの表示および変更アクセス権を持つユーザーのカンマ区切りリスト。 1.1.0
spark.admin.acls.groups なし Sparkアプリケーションへの表示および変更アクセス権を持つグループのカンマ区切りリスト。 2.0.0
spark.modify.acls なし Sparkアプリケーションへの変更アクセス権を持つユーザーのカンマ区切りリスト。 1.1.0
spark.modify.acls.groups なし Spark アプリケーションへの変更アクセス権を持つグループのカンマ区切りリスト。 2.0.0
spark.ui.view.acls なし Spark アプリケーションへの表示アクセス権を持つユーザーのカンマ区切りリスト。 1.0.0
spark.ui.view.acls.groups なし Spark アプリケーションへの表示アクセス権を持つグループのカンマ区切りリスト。 2.0.0
spark.user.groups.mapping org.apache.spark.security.ShellBasedGroupsMappingProvider ユーザーのグループリストは、このプロパティで設定可能な、`org.apache.spark.security.GroupMappingServiceProvider` トレイトで定義されたグループマッピングサービスによって決定されます。
デフォルトでは、Unix シェルベースの実装が使用され、ホスト OS からこの情報を収集します。
注: この実装は Unix/Linux ベースの環境のみをサポートしています。Windows 環境は現在サポートされていません**。ただし、上記のトレイトを実装することで、新しいプラットフォーム/プロトコルをサポートできます。
2.0.0

YARN では、アプリケーションの送信時に表示および変更 ACL が YARN サービスに提供され、YARN インターフェースを介してそれぞれの権限を持つユーザーを制御します。

Spark History Server ACL

SHS Web UI の認証は、サーブレットフィルターを使用して、通常のアプリケーションと同じ方法で有効になります。

SHS で認証を有効にするには、いくつかの追加オプションを使用します

プロパティ名デフォルト意味バージョン
spark.history.ui.acls.enable false 履歴サーバーでアプリケーションを表示するユーザーを認証するために ACL をチェックするかどうかを指定します。有効にすると、個々のアプリケーションが `spark.ui.acls.enable` に設定した内容に関係なく、アクセス制御チェックが実行されます。アプリケーションの所有者は、常に自身のアプリケーションを表示する権限を持ち、アプリケーションの実行時に `spark.ui.view.acls` で指定されたユーザーと `spark.ui.view.acls.groups` で指定されたグループもそのアプリケーションを表示する権限を持ちます。無効にすると、履歴サーバーを介して利用可能なアプリケーション UI に対してアクセス制御チェックは行われません。 1.0.1
spark.history.ui.admin.acls なし 履歴サーバー内のすべての Spark アプリケーションへの表示アクセス権を持つユーザーのカンマ区切りリスト。 2.1.1
spark.history.ui.admin.acls.groups なし 履歴サーバー内のすべての Spark アプリケーションへの表示アクセス権を持つグループのカンマ区切りリスト。 2.1.1

SHS は、通常のアプリケーションと同様に、グループマッピングプロバイダーを設定するために同じオプションを使用します。この場合、グループマッピングプロバイダーは SHS によってサーバーされるすべての UI に適用され、個々のアプリケーション設定は無視されます。

SSL設定

SSL の設定は階層的に構成されています。ユーザーは、プロトコル固有の設定で上書きされない限り、サポートされているすべての通信プロトコルに使用されるデフォルトの SSL 設定を構成できます。これにより、ユーザーは各プロトコルを個別に設定する機能を無効にすることなく、すべてのプロトコルの共通設定を簡単に提供できます。次の表は、SSL 設定の名前空間を示しています

設定名前空間 コンポーネント
spark.ssl デフォルトの SSL 設定。これらの値は、名前空間レベルで明示的に上書きされない限り、以下のすべての名前空間に適用されます。
spark.ssl.ui Spark アプリケーション Web UI
spark.ssl.standalone スタンドアロンマスター/ワーカー Web UI
spark.ssl.historyServer 履歴サーバー Web UI

使用可能な SSL オプションの完全な内訳は以下にあります。`${ns}` プレースホルダーは、上記のいずれかの名前空間に置き換える必要があります。

プロパティ名デフォルト意味
${ns}.enabled false SSL を有効にします。有効にすると、`${ns}.ssl.protocol` が必須です。
${ns}.port なし SSL サービスが listen するポート。
ポートは、特定の名前空間設定内で定義する必要があります。この設定を読み取るとき、デフォルトの名前空間は無視されます。
設定されていない場合、SSL ポートは同じサービスの非 SSL ポートから派生します。「0」の値は、サービスを一時ポートにバインドさせます。
${ns}.enabledAlgorithms なし 暗号のカンマ区切りリスト。指定された暗号は JVM でサポートされている必要があります。
プロトコルの参照リストは、Java セキュリティガイドの「JSSE Cipher Suite Names」セクションにあります。Java 8 のリストは、このページにあります。
注: 設定されていない場合、JRE のデフォルトの暗号スイートが使用されます。
${ns}.keyPassword なし キーストア内の秘密鍵のパスワード。
${ns}.keyStore なし キーストアファイルへのパス。パスは、プロセスが開始されたディレクトリからの絶対パスまたは相対パスです。
${ns}.keyStorePassword なし キーストアのパスワード。
${ns}.keyStoreType JKS キーストアのタイプ。
${ns}.protocol なし 使用する TLS プロトコル。プロトコルは JVM でサポートされている必要があります。
プロトコルの参照リストは、Java セキュリティガイドの「Additional JSSE Standard Names」セクションにあります。Java 8 のリストは、このページにあります。
${ns}.needClientAuth false クライアント認証を必須とするかどうか。
${ns}.trustStore なし トラストストアファイルへのパス。パスは、プロセスが開始されたディレクトリからの絶対パスまたは相対パスです。
${ns}.trustStorePassword なし トラストストアのパスワード。
${ns}.trustStoreType JKS トラストストアのタイプ。

Spark は、Hadoop Credential Providers から `${ns}.keyPassword`、`${ns}.keyStorePassword`、`${ns}.trustStorePassword` を取得することもサポートしています。ユーザーはパスワードを資格情報ファイルに保存し、次のように異なるコンポーネントからアクセスできるようにすることができます。

hadoop credential create spark.ssl.keyPassword -value password \
    -provider jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks

資格情報プロバイダーの場所を設定するには、Spark で使用される Hadoop 設定で `hadoop.security.credential.provider.path` 設定オプションを設定します。次のようにします。

  <property>
    <name>hadoop.security.credential.provider.path</name>
    <value>jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks</value>
  </property>

または、SparkConf "spark.hadoop.hadoop.security.credential.provider.path=jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks" を使用します。

キーストアの準備

キーストアは `keytool` プログラムで生成できます。Java 8 用のこのツールのリファレンスドキュメントはこちらです。Spark スタンドアロンデプロイメントモードのキーストアとトラストストアを設定するための最も基本的な手順は次のとおりです。

YARNモード

クラスタモードで実行されているドライバーにローカルのトラストストアまたはキーストアファイルを提供するには、`--files` コマンドライン引数(または同等の `spark.files` 設定)を使用してアプリケーションと一緒に配布できます。ファイルはドライバーの作業ディレクトリに配置されるため、TLS 設定は絶対パスなしでファイル名を参照する必要があります。

このようにローカルキーストアを配布するには、ファイルを HDFS(またはクラスタで使用される他の同様の分散ファイルシステム)にステージングする必要がある場合があるため、基盤となるファイルシステムをセキュリティを考慮して設定することをお勧めします(認証とワイヤ暗号化を有効にするなど)。

スタンドアロンモード

ユーザーは、マスターとワーカーのキーストアと設定オプションを提供する必要があります。これらは、`SPARK_MASTER_OPTS` および `SPARK_WORKER_OPTS` 環境変数、または単に `SPARK_DAEMON_JAVA_OPTS` に適切な Java システムプロパティを添付することで設定する必要があります。

ユーザーは、エグゼキュータがワーカープロセスから継承された SSL 設定を使用することを許可できます。これは、`spark.ssl.useNodeLocalConf` を `true` に設定することで実現できます。その場合、クライアント側でユーザーが提供した設定は使用されません。

Mesosモード

Mesos 1.3.0 以降は、ファイルベースと環境ベースの両方のシークレットとして `Secrets` プリミティブをサポートしています。Spark では、それぞれ `spark.mesos.driver.secret.filenames` と `spark.mesos.driver.secret.envkeys` を使用して、ファイルベースと環境変数ベースのシークレットを指定できます。

シークレットストアバックエンドに応じて、`spark.mesos.driver.secret.names` と `spark.mesos.driver.secret.values` 設定プロパティを使用して、それぞれ参照または値でシークレットを渡すことができます。

参照タイプのシークレットはシークレットストアによって提供され、名前(例:`/mysecret`)で参照されます。値タイプのシークレットはコマンドラインで渡され、適切なファイルまたは環境変数に変換されます。

HTTPセキュリティヘッダー

Apache Spark は、クロスサイトスクリプティング(XSS)、クロスフレームスクリプティング(XFS)、MIME スニッフィングの防止、および HTTP Strict Transport Security の適用に役立つ HTTP ヘッダーを含めるように設定できます。

プロパティ名デフォルト意味バージョン
spark.ui.xXssProtection 1; mode=block HTTP X-XSS-Protection レスポンスヘッダーの値。以下から適切な値を選択できます
  • `0` (XSS フィルタリングを無効にします)
  • `1` (XSS フィルタリングを有効にします。クロスサイトスクリプティング攻撃が検出された場合、ブラウザはページをサニタイズします。)
  • `1; mode=block` (XSS フィルタリングを有効にします。攻撃が検出された場合、ブラウザはページのレンダリングを阻止します。)
2.3.0
spark.ui.xContentTypeOptions.enabled true 有効にすると、X-Content-Type-Options HTTP レスポンスヘッダーが "nosniff" に設定されます。 2.3.0
spark.ui.strictTransportSecurity なし HTTP Strict Transport Security (HSTS) レスポンスヘッダーの値。以下から適切な値を選択し、それに応じて `expire-time` を設定できます。このオプションは、SSL/TLS が有効になっている場合にのみ使用されます。
  • max-age=<expire-time>
  • max-age=<expire-time>; includeSubDomains
  • max-age=<expire-time>; preload
2.3.0

ネットワークセキュリティのためのポート設定

一般的に、Spark クラスタとそのサービスはパブリックインターネットにデプロイされません。これらは一般にプライベートサービスであり、Spark をデプロイする組織のネットワーク内でのみアクセス可能である必要があります。Spark サービスが使用するホストとポートへのアクセスは、サービスにアクセスする必要があるオリジンホストに制限する必要があります。

以下は、Spark が通信に使用する主要なポートと、それらのポートを設定する方法です。

スタンドアロンモードのみ

送信元送信先デフォルトポート目的設定備考
ブラウザ スタンドアロンマスター 8080 Web UI 8080
Web UI
spark.master.ui.port / SPARK_MASTER_WEBUI_PORT
ブラウザ Jetty ベース。スタンドアロンモードのみ。 8081 Web UI スタンドアロンワーカー
8081
spark.master.ui.port / SPARK_MASTER_WEBUI_PORT
Web UI
Jetty ベース。スタンドアロンモードのみ。
スタンドアロンマスター 7077 spark.worker.ui.port / SPARK_WORKER_WEBUI_PORT
ドライバー / アプリケーション
7077 クラスタにジョブを送信 / クラスタに参加
SPARK_MASTER_PORT スタンドアロンマスター 6066 ランダムにポートを選択するには「0」に設定します。スタンドアロンモードのみ。 外部サービス 6066
スタンドアロンマスター Jetty ベース。スタンドアロンモードのみ。 REST API 経由でクラスタにジョブを送信 spark.master.rest.port このサービスを有効/無効にするには、`spark.master.rest.enabled` を使用します。スタンドアロンモードのみ。 クラスタにジョブを送信 / クラスタに参加

すべてのクラスタマネージャー

送信元送信先デフォルトポート目的設定備考
ブラウザ (ランダム) 4040 Web UI エグゼキュータのスケジュール SPARK_WORKER_PORT
ブラウザ アプリケーション 18080 Web UI 4040 SPARK_WORKER_PORT
Web UI
スタンドアロンマスター
spark.ui.port REST API 経由でクラスタにジョブを送信 Jetty ベース
履歴サーバー
18080 Web UI
spark.history.ui.port spark.history.ui.port REST API 経由でクラスタにジョブを送信 エグゼキュータ / ドライバー (ランダム) アプリケーションに接続 / エグゼキュータの状態変更を通知

Kerberos

spark.driver.port

ランダムにポートを選択するには「0」に設定します。

エグゼキュータ / ドライバー

(ランダム)

ブロックマネージャーポート

アプリケーションが他のセキュアなHadoopファイルシステムと対話する必要がある場合、起動時にそれらのURIをSparkに明示的に提供する必要があります。これは、以下の設定セクションで説明されているspark.kerberos.access.hadoopFileSystemsプロパティに、それらをリストすることで行われます。

Sparkは、Javaサービスメカニズム(java.util.ServiceLoaderを参照)を使用したカスタム委任トークンプロバイダーもサポートしています。org.apache.spark.security.HadoopDelegationTokenProviderの実装は、jarのMETA-INF/servicesディレクトリにある対応するファイルにそれらの名前をリストすることで、Sparkで使用できるようにすることができます。

委任トークンのサポートは、現在、YARNモードとMesosモードでのみサポートされています。詳細については、デプロイメント固有のページを参照してください。

以下のオプションは、この機能をよりきめ細かく制御できます。

プロパティ名デフォルト意味バージョン
spark.security.credentials.${service}.enabled true セキュリティが有効になっている場合に、サービスの資格情報を取得するかどうかを制御します。デフォルトでは、サポートされているすべてのサービスの資格情報は、それらのサービスが構成されているときに取得されますが、実行されているアプリケーションと何らかの形で競合する場合、その動作を無効にすることができます。 2.3.0
spark.kerberos.access.hadoopFileSystems (なし) SparkアプリケーションがアクセスするセキュアなHadoopファイルシステムのカンマ区切りリスト。たとえば、spark.kerberos.access.hadoopFileSystems=hdfs://nn1.com:8032,hdfs://nn2.com:8032, webhdfs://nn3.com:50070などです。Sparkアプリケーションは、リストされているファイルシステムにアクセスできる必要があり、Kerberosは、それらにアクセスできるように適切に構成されている必要があります(同じレルム内、または信頼できるレルム内)。Sparkは、SparkアプリケーションがそれらのリモートHadoopファイルシステムにアクセスできるように、各ファイルシステムのセキュリティトークンを取得します。 3.0.0

ユーザーは、リソーススケジューラでのKerberos委任トークンの更新を除外できます。現在、これはYARNでのみサポートされています。設定については、Spark on YARNの実行ページを参照してください。

長時間実行アプリケーション

実行時間が、アクセスする必要があるサービスで設定されている委任トークンの最大有効期間を超えると、長時間実行されるアプリケーションで問題が発生する可能性があります。

この機能は、どこでも利用できるわけではありません。特に、YARNとKubernetes(クライアントモードとクラスタモードの両方)、およびクライアントモードを使用している場合のMesosでのみ実装されています。

Sparkは、これらのアプリケーションの新しいトークンを自動的に作成することをサポートしています。この機能を有効にするには、2つの方法があります。

Keytabの使用

Sparkにプリンシパルとキータブを提供することにより(たとえば、spark-submit--principalおよび--keytabパラメータを使用)、アプリケーションは、委任トークンを無期限に取得するために使用できる有効なKerberosログインを維持します。

クラスタモードでキータブを使用する場合、Sparkドライバを実行しているマシンにコピーされることに注意してください。YARNの場合、これはキータブのステージングエリアとしてHDFSを使用することを意味するため、少なくともYARNとHDFSの両方を暗号化で保護することを強くお勧めします。

チケットキャッシュの使用

Sparkの設定でspark.kerberos.renewal.credentialsccacheに設定することにより、ローカルKerberosチケットキャッシュが認証に使用されます。Sparkは、更新可能な期間中はチケットを更新された状態に保ちますが、有効期限が切れた後は、新しいチケットを取得する必要があります(たとえば、kinitを実行することにより)。

Sparkが使用できる更新されたチケットキャッシュを維持するのは、ユーザーの責任です。

チケットキャッシュの場所は、KRB5CCNAME環境変数を設定することでカスタマイズできます。

Kubernetesとの安全な連携

Kerberosの背後にあるHadoopベースのサービスと通信する場合、Sparkは非ローカルプロセスが認証できるように委任トークンを取得する必要があることがわかりました。Kubernetesのこれらの委任トークンは、DriverとそのExecutorによって共有されるSecretsに格納されます。そのため、Kerberosジョブを送信するには3つの方法があります。

いずれの場合も、環境変数HADOOP_CONF_DIRまたはspark.kubernetes.hadoop.configMapNameを定義する必要があります。

また、KDCはコンテナ内から見える必要があることに注意することも重要です。

ユーザーがHadoop構成ファイルを含むリモートのHADOOP_CONFディレクトリを使用する場合、spark.kubernetes.hadoop.configMapNameを既存のConfigMapに設定することで実現できます。

  1. ローカルチケットキャッシュにTGTを格納する$kinitを使用して送信する
    /usr/bin/kinit -kt <keytab_file> <username>/<krb5 realm>
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    
  2. ローカルキータブとプリンシパルを使用して送信する
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kerberos.keytab=<KEYTAB_FILE> \
     --conf spark.kerberos.principal=<PRINCIPAL> \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    
  3. 名前空間内にすでに存在する委任トークンを含む、事前に設定されたシークレットを使用して送信する
    /opt/spark/bin/spark-submit \
     --deploy-mode cluster \
     --class org.apache.spark.examples.HdfsTest \
     --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
     --conf spark.executor.instances=1 \
     --conf spark.app.name=spark-hdfs \
     --conf spark.kubernetes.container.image=spark:latest \
     --conf spark.kubernetes.kerberos.tokenSecret.name=<SECRET_TOKEN_NAME> \
     --conf spark.kubernetes.kerberos.tokenSecret.itemKey=<SECRET_ITEM_KEY> \
     --conf spark.kubernetes.kerberos.krb5.path=/etc/krb5.conf \
     local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
     <HDFS_FILE_LOCATION>
    

3b. (3)のように送信しますが、事前に作成されたkrb5 ConfigMapと事前に作成されたHADOOP_CONF_DIR ConfigMapを指定します

/opt/spark/bin/spark-submit \
    --deploy-mode cluster \
    --class org.apache.spark.examples.HdfsTest \
    --master k8s://<KUBERNETES_MASTER_ENDPOINT> \
    --conf spark.executor.instances=1 \
    --conf spark.app.name=spark-hdfs \
    --conf spark.kubernetes.container.image=spark:latest \
    --conf spark.kubernetes.kerberos.tokenSecret.name=<SECRET_TOKEN_NAME> \
    --conf spark.kubernetes.kerberos.tokenSecret.itemKey=<SECRET_ITEM_KEY> \
    --conf spark.kubernetes.hadoop.configMapName=<HCONF_CONFIG_MAP_NAME> \
    --conf spark.kubernetes.kerberos.krb5.configMapName=<KRB_CONFIG_MAP_NAME> \
    local:///opt/spark/examples/jars/spark-examples_<VERSION>.jar \
    <HDFS_FILE_LOCATION>

イベントロギング

アプリケーションでイベントロギングを使用している場合、イベントログが保存されるディレクトリ(spark.eventLog.dir)は、適切な権限で手動で作成する必要があります。ログファイルを保護するには、ディレクトリの権限をdrwxrwxrwxtに設定する必要があります。ディレクトリの所有者とグループは、Spark History Serverを実行しているスーパーユーザーに対応している必要があります。

これにより、すべてのユーザーがディレクトリに書き込むことができますが、権限のないユーザーがファイルを読み取ったり、削除したり、名前を変更したりすることを防ぎます(所有者である場合を除く)。イベントログファイルは、ユーザーとグループのみが読み取りおよび書き込みアクセス権を持つように、Sparkによって作成されます。

クライアントモードでのドライバログの永続化

アプリケーションがspark.driver.log.persistToDfs.enabledを有効にしてクライアントモードでドライバログを永続化する場合、ドライバログが保存されるディレクトリ(spark.driver.log.dfsDir)は、適切な権限で手動で作成する必要があります。ログファイルを保護するには、ディレクトリの権限をdrwxrwxrwxtに設定する必要があります。ディレクトリの所有者とグループは、Spark History Serverを実行しているスーパーユーザーに対応している必要があります。

これにより、すべてのユーザーがディレクトリに書き込むことができますが、権限のないユーザーがファイルを読み取ったり、削除したり、名前を変更したりすることを防ぎます(所有者である場合を除く)。ドライバログファイルは、ユーザーとグループのみが読み取りおよび書き込みアクセス権を持つように、Sparkによって作成されます。