クラスターワーカーノード 間のトラフィックを暗号化する

プレビュー

この機能はパブリックプレビュー段階です。

重要

この記事で参照されている init スクリプトの例 では、DBFS に格納されているキーストアのハッシュから共有暗号化シークレットが導出されます。 DBFS のキーストア ファイルを更新してシークレットをローテーションする場合は、すべての稼働中のクラスターを再起動する必要があります。 そうしないと、共有シークレットに一貫性がないために Spark ワーカーが Spark ドライバーでの認証に失敗し、ジョブの速度が低下する可能性があります。 さらに、共有シークレットは DBFS に格納されるため、DBFS アクセス権を持つすべてのユーザーがノートブックを使用してシークレットを取得できます。

代わりに、次の AWS インスタンス タイプのいずれかを使用できます。これにより、追加の構成は必要なく、ワーカー ノード間でデータが自動的に暗号化されます。

  • 汎用: M-fleet, Md-fleet, M5dn, M5n, M5zn, M6i, M7i, M6id, M6in, M6idn, M6a, M7a

  • コンピュートが最適化されました: C5aC5adC5nC6iC6idC7iC6inC6aC7a

  • メモリ最適化:R-fleetRd-fleetR6iR7iR7izR6idR6inR6idnR6aR7a

  • ストレージ最適化:D3D3enP3dnR5dnR5nI4iI3en

  • アクセラレーテッド コンピューティング: G4dn, G5, P4d, P4de, P5

要件

この機能を使用するには、 エンタープライズ プランが必要です。 詳細については、Databricks アカウント チームにお問い合わせください。

initスクリプトの仕組み

重要

この記事で参照されている init スクリプトの例 では、DBFS に格納されているキーストアのハッシュから共有暗号化シークレットが導出されます。 DBFS のキーストア ファイルを更新してシークレットをローテーションする場合は、すべての稼働中のクラスターを再起動する必要があります。 そうしないと、共有シークレットに一貫性がないために Spark ワーカーが Spark ドライバーでの認証に失敗し、ジョブの速度が低下する可能性があります。 さらに、共有シークレットは DBFS に格納されるため、DBFS アクセス権を持つすべてのユーザーがノートブックを使用してシークレットを取得できます。

ユーザーのクエリと変換は通常、暗号化されたチャンネルを通じてクラスターに送信されます。 ただし、デフォルトでは、クラスター内のワーカー ノード間で交換されるデータは暗号化されません。 環境で、保存中か転送中かにかかわらず、常にデータを暗号化する必要がある場合は、TLS 1.3 接続上で AES 256 ビット暗号化を使用して、ワーカー ノード間のトラフィックを暗号化するようにクラスターを構成する init スクリプトを作成できます。

AES を使用すると、暗号化ルーチンでハードウェア アクセラレーションを利用できますが、暗号化されていないトラフィックと比較してパフォーマンスが低下します。 このペナルティにより、ノード間でシャッフルされるデータの量によっては、暗号化されたクラスターでクエリーにかかる時間が長くなる可能性があります。

ワーカー ノード間のトラフィックの暗号化を有効にするには、initスクリプトを使用して Spark 構成パラメーターを設定する必要があります。 クラスター スコープの initScript を 1 つのクラスターに使用するか、クラスタースコープの initスクリプトをクラスターポリシーに追加して、ワークスペース内のすべてのクラスターでワーカー間の暗号化を使用できます。

1 回、鍵ストア・ファイルを DBFS 内のディレクトリーにコピーします。 次に、暗号化設定を適用する initスクリプトを作成します。

initスクリプトは、次のタスクを実行する必要があります。

  1. JKS 鍵ストア・ファイルとパスワードを取得します。

  2. Spark エグゼキューターの構成を設定します。

  3. Spark ドライバーの構成を設定します。

SSL/HTTPS を有効にするために使用される JKS 鍵ストア・ファイルは、ワークスペースごとに動的に生成されます。 JKS 鍵ストア・ファイルのパスワードはハードコーディングされており、鍵ストアの機密性を保護するためのものではありません。

次に、これら 3 つのタスクを実装してクラスター暗号化構成を生成する initスクリプトの例を示します。

例 initスクリプト

#!/bin/bash

set -euo pipefail

keystore_dbfs_file="/dbfs/<keystore-directory>/jetty_ssl_driver_keystore.jks"

## Wait till keystore file is available via Fuse

max_attempts=30
while [ ! -f ${keystore_dbfs_file} ];
do
  if [ "$max_attempts" == 0 ]; then
    echo "ERROR: Unable to find the file : $keystore_dbfs_file .Failing the script."
    exit 1
  fi
  sleep 2s
  ((max_attempts--))
done
## Derive shared internode encryption secret from the hash of the keystore file
sasl_secret=$(sha256sum $keystore_dbfs_file | cut -d' ' -f1)


if [ -z "${sasl_secret}" ]; then
  echo "ERROR: Unable to derive the secret.Failing the script."
  exit 1
fi

# The JKS keystore file used for enabling SSL/HTTPS
local_keystore_file="$DB_HOME/keys/jetty_ssl_driver_keystore.jks"
# Password of the JKS keystore file. This jks password is hardcoded and is not intended to protect the confidentiality
# of the keystore. Do not assume the keystore file itself is protected.
local_keystore_password="gb1gQqZ9ZIHS"

## Updating spark-branch.conf is only needed for driver

if [[ $DB_IS_DRIVER = "TRUE" ]]; then
  driver_conf=${DB_HOME}/driver/conf/spark-branch.conf
  echo "Configuring driver conf at $driver_conf"

  if [ ! -e $driver_conf ] ; then
    touch $driver_conf
  fi

cat << EOF >>  $driver_conf
  [driver] {
    // Configure inter-node authentication
  "spark.authenticate" = true
  "spark.authenticate.secret" = "$sasl_secret"
  // Configure AES encryption
  "spark.network.crypto.enabled" = true
  "spark.network.crypto.saslFallback" = false
  // Configure SSL
  "spark.ssl.enabled" = true
  "spark.ssl.keyPassword" = "$local_keystore_password"
  "spark.ssl.keyStore" = "$local_keystore_file"
  "spark.ssl.keyStorePassword" = "$local_keystore_password"
  "spark.ssl.protocol" ="TLSv1.3"
  "spark.ssl.standalone.enabled" = true
  "spark.ssl.ui.enabled" = true
  }
EOF
  echo "Successfully configured driver conf at $driver_conf"
fi

# Setting configs in spark-defaults.conf for the spark master and worker

spark_defaults_conf="$DB_HOME/spark/conf/spark-defaults.conf"
echo "Configuring spark defaults conf at $spark_defaults_conf"
if [ ! -e $spark_defaults_conf ] ; then
  touch $spark_defaults_conf
fi

cat << EOF >>  $spark_defaults_conf
spark.authenticate true
spark.authenticate.secret $sasl_secret
spark.network.crypto.enabled true
spark.network.crypto.saslFallback false

spark.ssl.enabled true
spark.ssl.keyPassword $local_keystore_password
spark.ssl.keyStore $local_keystore_file
spark.ssl.keyStorePassword $local_keystore_password
spark.ssl.protocol TLSv1.3
spark.ssl.standalone.enabled true
spark.ssl.ui.enabled true
EOF

echo "Successfully configured spark defaults conf at $spark_defaults_conf"

ドライバー・ノードとワーカー・ノードの初期化が完了すると、これらのノード間のすべてのトラフィックが鍵ストア・ファイルを使用して暗号化されます。

ノートブックの例: 暗号化 initスクリプト をインストールする

次のノートブックは、キーストアファイルをコピーし、DBFS に initスクリプトを生成します。 initスクリプトを使用して、暗号化を有効にした新しいクラスターを作成できます。

暗号化 initスクリプト ノートブック をインストールする

ノートブックを新しいタブで開く

ワーカー・ノード 間の暗号化の無効化

ワーカー・ノード間の暗号化を無効にするには、クラスター構成からinitスクリプトを削除してから、クラスターを再起動します。