클러스터 작업자 노드 간의 트래픽 암호화

Important

이 문서에서 참조하는 init 스크립트 예시는 DBFS에 저장된 키 저장소의 해시에서 공유 암호화 비밀을 파생합니다. DBFS에서 키 저장소 파일을 업데이트하여 비밀을 교체하는 경우 실행 중인 모든 클러스터를 다시 시작해야 합니다. 그렇지 않으면 Spark 작업자가 일치하지 않는 공유 비밀로 인해 Spark 드라이버로 인증하지 못해 작업 속도가 느려질 수 있습니다. 또한 공유 비밀은 DBFS에 저장되기 때문에 DBFS 액세스 권한이 있는 모든 사용자는 Notebook을 사용하여 비밀을 검색할 수 있습니다.

요구 사항

  • 이 기능을 사용하려면 Premium 플랜이 필요합니다. 자세한 내용은 Databricks 계정 팀에 문의하세요.

init 스크립트 작동 방식

Important

이 문서에서 참조하는 init 스크립트 예시는 DBFS에 저장된 키 저장소의 해시에서 공유 암호화 비밀을 파생합니다. DBFS에서 키 저장소 파일을 업데이트하여 비밀을 교체하는 경우 실행 중인 모든 클러스터를 다시 시작해야 합니다. 그렇지 않으면 Spark 작업자가 일치하지 않는 공유 비밀로 인해 Spark 드라이버로 인증하지 못해 작업 속도가 느려질 수 있습니다. 또한 공유 비밀은 DBFS에 저장되기 때문에 DBFS 액세스 권한이 있는 모든 사용자는 Notebook을 사용하여 비밀을 검색할 수 있습니다.

사용자 쿼리 및 변환은 일반적으로 암호화된 채널을 통해 클러스터로 전송됩니다. 그러나 기본적으로 클러스터의 작업자 노드 간에 교환되는 데이터는 암호화되지 않습니다. 환경에서 미사용 또는 전송 중이든 항상 데이터를 암호화해야 하는 경우 TLS 1.3 연결을 통해 AES 256비트 암호화를 사용하여 작업자 노드 간의 트래픽을 암호화하도록 클러스터를 구성하는 init 스크립트를 만들 수 있습니다.

참고 항목

AES를 사용하면 암호화 루틴에서 하드웨어 가속을 활용할 수 있지만 암호화되지 않은 트래픽에 비해 성능이 저하됩니다. 이 패널티로 인해 노드 간에 섞인 데이터의 양에 따라 암호화된 클러스터에서 쿼리가 더 오래 걸릴 수 있습니다.

작업자 노드 간의 트래픽 암호화를 사용하도록 설정하려면 init 스크립트를 통해 Spark 구성 매개 변수를 설정해야 합니다. 작업 영역의 모든 클러스터가 작업자-작업자 암호화를 사용하도록 하려면 단일 클러스터에 대해 클러스터 범위 init 스크립트 를 사용하거나 클러스터 정책에 클러스터 범위 init 스크립트를 추가할 수 있습니다.

한 번, 키 저장소 파일을 DBFS의 디렉터리에 복사합니다. 그런 다음 암호화 설정을 적용하는 init 스크립트를 만듭니다.

init 스크립트는 다음 작업을 수행해야 합니다.

  1. JKS 키 저장소 파일 및 암호를 가져옵니다.
  2. Spark 실행기 구성을 설정합니다.
  3. Spark 드라이버 구성을 설정합니다.

참고 항목

SSL/HTTPS 사용하도록 설정에 사용되는 JKS 키 저장소 파일은 각 작업 영역에 대해 동적으로 생성됩니다. JKS 키 저장소 파일의 암호는 하드코딩되어 있으며 키 저장소의 기밀성을 보호하기 위한 것이 아닙니다.

다음은 클러스터 암호화 구성을 생성하기 위해 이러한 세 가지 작업을 구현하는 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"

드라이버 및 작업자 노드의 초기화가 완료되면 이러한 노드 간의 모든 트래픽이 키 저장소 파일을 사용하여 암호화됩니다.

Notebook 예제: 암호화 init 스크립트 설치

다음 Notebook은 키 저장소 파일을 복사하고 DBFS에서 init 스크립트를 생성합니다. init 스크립트를 사용하여 암호화가 사용하도록 설정된 새 클러스터를 만들 수 있습니다.

암호화 init 스크립트 Notebook 설치

전자 필기장 가져오기

작업자 노드 간 암호화 사용하지 않도록 설정

작업자 노드 간의 암호화를 사용하지 않도록 설정하려면 클러스터 구성에서 init 스크립트를 제거한 다음 클러스터를 다시 시작합니다.