このトピックでは、BigDL Privacy Preserving Machine Learning (BigDL PPML) を使用して、分散型のエンドツーエンドで安全なApache Sparkビッグデータ分析アプリケーションをIntelで実行する方法について説明します。®TDX対応のg8iインスタンス。
背景情報
データとコンピューティングリソースをクラウドに移行する企業が増えています。 データのプライバシーと機密性の保護は、ビッグデータ分析と機械学習にとって重要であり、データサイエンティストとクラウドサービスプロバイダーにとって共通の課題となります。
BigDL PPMLを使用して、Alibaba Cloud TDXインスタンス上で標準のビッグデータおよびAIアプリケーション (Apache Spark、Apache Flink、Tensorflow、PyTorchなど) を実行することができます。 詳細については、「BigDL-PPML」をご参照ください。
インテル ®Trusted Domain Extension (インテル)®TDX) は、データを保護するためのハードウェア支援セキュリティを提供します。 ファームウェアやホストのセキュリティステータスに依存せず、物理マシン上に機密コンピューティング環境を構築できます。
Alibaba Cloud g8iインスタンスはIntel ®TDXの機密コンピューティング機能を提供し、ハードウェアによる保護を備えたより安全で信頼できる機密環境を作成する、TDX対応インスタンス (以下、TDXインスタンスと呼ぶ) をします。 TDXインスタンスは、マルウェア攻撃に関連するリスクを軽減し、高度なデータプライバシーとアプリケーションの整合性を実現します。
BigDL PPMLは、インテルに基づいて开発されたソリューションです®TDXをしてデータ分析とAIアプリケーションを保護します。
アーキテクチャ
BigDL PPMLを使用することで、Apache Spark、Apache Flink、Tensorflow、PyTorchなどの既存の分散ビッグデータ分析およびAIアプリケーションを、コードを変更することなく機密環境で実行できます。 ビッグデータ分析とAIアプリケーションは、コンピューティングとメモリがIntelによって保護されているTDXインスタンスに基づくKubernetesクラスターで実行されます®TDXだ BigDL PPMLは、下層の分散アプリケーションに対して次のエンドツーエンドのセキュリティメカニズムを有効にします。
TDXインスタンスに基づくKubernetesクラスターで信頼できるクラスター環境を提供および証明するセキュリティメカニズム。
キー管理サービス (KMS): キーを管理し、キーを使用して分散データを暗号化および復号化します。
安全な分散コンピューティングと通信。
BigDL PPMLは、Intelに基づいてデプロイされたKubernetesクラスターでエンドツーエンドのビッグデータとAIパイプラインを保護します®上の図に示すように、TDXが有効なインスタンスをします。 すべてのデータは暗号化され、データレイクとデータウェアハウスに保存されます。
BigDL PPMLワーカーは、暗号化された入力データを読み込み、リモート認証を実行するかKMSを使用してデータキーを取得し、そのキーを使用してTDXインスタンスの入力データを復号化します。
BigDL PPMLワーカーは、ビッグデータおよびAIコンピューティングフレームワークを使用して、分散方式でデータを前処理し、モデルをトレーニングし、モデルを使用して推論を実行します。
BigDL PPMLワーカーは、最終結果、出力データ、またはモデルを暗号化して分散ストレージに書き込みます。
ノード間で送信されるデータは、データのエンドツーエンドのセキュリティとプライバシーを確保するために、Advanced Encryption Standard (AES) やTransport Layer securityなどのセキュリティプロトコルに基づいて転送中に暗号化されます。
手順
このセクションでは、TDXインスタンスで分散型のエンドツーエンドのセキュアなビッグデータ分析アプリケーションを実行する方法について説明します。 この例では、Apache Sparkビッグデータ分析アプリケーションとSimple Queryの例が使用されています。 ビッグデータとAIアプリケーションの使用方法については、「BigDL PPMLチュートリアルと例」をご参照ください。
手順1: Kubernetesクラスターとランタイム環境のデプロイ
このトピックでは、マスターノードと2つのワーカーノードで構成されるKubernetesクラスターを使用します。 クラスター内のノードの数は、購入したTDXインスタンスの数と同じである必要があります。 ビジネス要件に基づいて、特定の数のノードで構成されるKubernetesクラスターを作成できます。
インテルの作成®TDX対応のg8iインスタンス。
詳細については、「カスタム起動タブでインスタンスを作成する」をご参照ください。 次のパラメータに注意してください。
インスタンスタイプ: Simple Queryの例をサポートするインスタンスタイプを選択します。 Simple Queryの例をサポートするには、インスタンスタイプに32以上のvCPUと64 GiBのメモリが必要です。 このトピックでは、ecs.g8i.8xlargeインスタンスタイプを使用します。
イメージ: Alibaba Cloud Linux 3.2104 LTS 64ビットを選択します。
パブリックIPアドレス: パブリックIPv4アドレスの割り当てを選択します。
数量: 3を入力します。
インスタンスに接続します。
詳細については、「接続方法」をご参照ください。
Kubernetesクラスターをデプロイし、セキュリティ設定を設定します。
g8iインスタンスにKubernetesクラスターをデプロイします。
詳細については、「kubeadmを使用したクラスターの作成」をご参照ください。
次のコマンドを実行して、Kubernetesクラスターのマスターノードでセキュリティ設定 (ロールベースのアクセス制御設定) を設定します。
kubectl create serviceaccount spark kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=default:spark --namespace=default
PersistentVolumeを作成します。
rootユーザーとして次のコマンドを実行し、pv-volume.yamlファイルを作成します。
vim pv-volume.yaml
I
キーを押して挿入モードに入ります。次のコンテンツをpv-volume.yamlに追加します。
apiVersion: v1 kind: PersistentVolume metadata: name: task-pv-volume labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"
Esc
キーを押し、:wq
と入力して変更を保存し、挿入モードを終了します。次のコマンドを実行してPersistentVolumeを作成し、PersistentVolumeを表示します。
kubectl apply -f pv-volume.yaml kubectl get pv task-pv-volume
PersistentVolumeClaimを作成します。
rootユーザーとして次のコマンドを実行し、pv-claim.yamlファイルを作成します。
vim pv-claim.yaml
I
キーを押して挿入モードに入ります。次のコンテンツをpv-claim.yamlに追加します。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: task-pv-claim spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 3Gi
Esc
キーを押し、:wq
と入力して変更を保存し、挿入モードを終了します。次のコマンドを実行してPersistentVolumeClaimを作成し、PersistentVolumeClaimを表示します。
kubectl apply -f pv-claim.yaml kubectl get pvc task-pv-claim
を取得します
ステップ2: トレーニングデータの暗号化
Kubernetesクラスターの各ノードで次のコマンドを実行し、BigDL PPMLイメージを取得します。
このイメージは、標準のApache Sparkアプリケーションの実行に使用され、データの暗号化および復号化機能を提供します。
docker pull intelanalytics/bigdl-ppml-trusted-bigdata-gramine-reference-16g:2.3.0-SNAPSHOT
トレーニングデータセットファイルpeople.csvを生成します。
Kubernetesクラスターのマスターノードで次のコマンドを実行し、トレーニングスクリプトgenerate_people_csv.pyをダウンロードします。
wget https://github.com/intel-analytics/BigDL/raw/main/ppml/scripts/generate_people_csv.py
次のコマンドを実行して、トレーニングデータセットファイルpeople.csvを生成します。
python generate_people_csv.py </save/path/of/people.csv> <num_lines>
説明people.csvファイルを生成するパスに </save/path/of/people.csv> を設定します。 この例では、/home/userパスが使用されます。
<num_lines> をpeople.csvの行数に設定します。 この例では、ライン数は500である。
次のコマンドを実行して、people.csvを特定のディレクトリに移動します。
sudo scp /home/user/people.csv /mnt/data/simplekms/
重要/home/user
を実際のディレクトリに置き換えます。この例では、
/mnt/data/simplekms/
ディレクトリが使用されています。/mnt/data/simplekms/
ディレクトリには、暗号化および復号化されたデータが格納されます。
Kubernetesクラスターのマスターノードで次のコマンドを実行し、bigdl-ppml-clientコンテナーを実行します。
コンテナは、トレーニングデータの暗号化と復号に使用されます。
説明bigdl-ppml-clientコンテナーを実行するユーザーに基づいて、
/home/user/kuberconfig:/root/.kube/config
を置き換えます。rootユーザーがコンテナーを実行している場合は、/home/user/kuberconfig:/root/.kube/configを
/root/kuberconfig:/root/.kube/config
に置き換えます。testユーザーなどの一般的なユーザーがコンテナーを実行する場合は、/home/user/kuberconfig:/root/.kube/configを
/home/test/kuberconfig:/root/.kube/config
に置き換えます。
export K8S_MASTER=k8s://$(kubectl cluster-info | grep 'https.*6443' -o -m 1) echo The k8s master is $K8S_MASTER . export SPARK_IMAGE=intelanalytics/bigdl-ppml-trusted-bigdata-gramine-reference-16g:2.3.0-SNAPSHOT sudo docker run -itd --net=host \ -v /etc/kubernetes:/etc/kubernetes \ -v /home/user/kuberconfig:/root/.kube/config \ -v /mnt/data:/mnt/data \ -e RUNTIME_SPARK_MASTER=$K8S_MASTER \ -e RUNTIME_K8S_SPARK_IMAGE=$SPARK_IMAGE \ -e RUNTIME_PERSISTENT_VOLUME_CLAIM=task-pv-claim \ --name bigdl-ppml-client \ $SPARK_IMAGE bash docker exec -it bigdl-ppml-client bash
Kubernetesクラスターのマスターノードでpeople.csvを暗号化します。
次のコマンドを実行して、アプリケーションID (APPID) とAPIキー (APIKEY) に基づいてプライマリキー (primarykey) を生成します。
単純なKMSを使用して、1〜12文字の長さのアプリケーションIDとAPIキーを生成できます。 この例では、APPIDの値は98463816 **** であり、APIKEYの値は15780936 **** である。 -- primaryKeyPathは、主キーを格納するディレクトリを指定します。
java -cp '/ppml/spark-3.1.3/conf/:/ppml/spark-3.1.3/jars/*:/ppml/bigdl-2.3.0-SNAPSHOT/jars/*' \ com.intel.analytics.bigdl.ppml.examples.GeneratePrimaryKey \ --primaryKeyPath /mnt/data/simplekms/primaryKey \ --kmsType SimpleKeyManagementService \ --simpleAPPID 98463816**** \ --simpleAPIKEY 15780936****
暗号化スクリプトencrypt.pyを作成します。
次のコマンドを実行して、
/mnt/data/simplekms
ディレクトリに切り替えます。cd /mnt/data/simplekms
次のコマンドを実行して、encrypt.pyファイルを作成して開きます。
sudo vim encrypt.py
I
キーを押して挿入モードに入ります。次のコンテンツをencrypt.pyファイルに追加します。
# encrypt.py from bigdl.ppml.ppml_context import * args = {"kms_type": "SimpleKeyManagementService", "app_id": "98463816****", "api_key": "15780936****", "primary_key_material": "/mnt/data/simplekms/primaryKey" } sc = PPMLContext("PPMLTest", args) csv_plain_path = "/mnt/data/simplekms/people.csv" csv_plain_df = sc.read(CryptoMode.PLAIN_TEXT) \ .option("header", "true") \ .csv(csv_plain_path) csv_plain_df.show() output_path = "/mnt/data/simplekms/encrypted-input" sc.write(csv_plain_df, CryptoMode.AES_CBC_PKCS5PADDING) \ .mode('overwrite') \ .option("header", True) \ .csv(output_path)
Esc
キーを押し、:wq
と入力して変更を保存し、挿入モードを終了します。
bigdl-ppml-clientコンテナーで次のコマンドを実行し、APPID、APIKEY、およびprimarykeyを使用してpeople.csvを暗号化します。
暗号化されたデータは、
/mnt/data/simplekms/encrypted-output
ディレクトリに保存されます。java \ -cp '/ppml/spark-3.1.3/conf/:/ppml/spark-3.1.3/jars/*:/ppml/bigdl-2.3.0-SNAPSHOT/jars/*' \ -Xmx1g org.apache.spark.deploy.SparkSubmit \ --master 'local[4]' \ --conf spark.network.timeout=10000000 \ --conf spark.executor.heartbeatInterval=10000000 \ --conf spark.python.use.daemon=false \ --conf spark.python.worker.reuse=false \ --py-files /ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-ppml-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip,/ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip,/ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-dllib-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip \ /mnt/data/simplekms/encrypt.py
Kubernetesクラスターの各ワーカーノードで次のコマンドを実行し、マスターノードから各ワーカーノードに
/mnt/data/simplekms
をコピーします。cd /mnt/data sudo scp -r user@192.168.XXX.XXX:/mnt/data/simplekms .
説明userをマスターノードの実際のユーザー名に置き換え、. XXX.XXXをマスターノードの実際のIPアドレスに192.168ます。
ステップ3: BigDL PPMLベースのビッグデータ分析の例を実行する
bigdl-ppml-clientコンテナーで、Apache SparkジョブをKubernetesクラスターに送信し、Simple Queryの例を実行します。
説明spark.driver.host=192.168.XXX.XXXで、192.168.XXX.XXXをマスターノードの実際のIPアドレスに置き換えます。
${SPARK_HOME}/bin/spark-submit \ --master $RUNTIME_SPARK_MASTER \ --deploy-mode client \ --name spark-simplequery-tdx \ --conf spark.driver.memory=4g \ --conf spark.executor.cores=4 \ --conf spark.executor.memory=4g \ --conf spark.executor.instances=2 \ --conf spark.driver.host=192.168.XXX.XXX \ --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \ --conf spark.cores.max=8 \ --conf spark.kubernetes.container.image=$RUNTIME_K8S_SPARK_IMAGE \ --class com.intel.analytics.bigdl.ppml.examples.SimpleQuerySparkExample \ --conf spark.network.timeout=10000000 \ --conf spark.executor.heartbeatInterval=10000000 \ --conf spark.kubernetes.executor.deleteOnTermination=false \ --conf spark.driver.extraClassPath=local://${BIGDL_HOME}/jars/* \ --conf spark.executor.extraClassPath=local://${BIGDL_HOME}/jars/* \ --conf spark.kubernetes.file.upload.path=/mnt/data \ --conf spark.kubernetes.driver.volumes.persistentVolumeClaim.${RUNTIME_PERSISTENT_VOLUME_CLAIM}.options.claimName=${RUNTIME_PERSISTENT_VOLUME_CLAIM} \ --conf spark.kubernetes.driver.volumes.persistentVolumeClaim.${RUNTIME_PERSISTENT_VOLUME_CLAIM}.mount.path=/mnt/data \ --conf spark.kubernetes.executor.volumes.persistentVolumeClaim.${RUNTIME_PERSISTENT_VOLUME_CLAIM}.options.claimName=${RUNTIME_PERSISTENT_VOLUME_CLAIM} \ --conf spark.kubernetes.executor.volumes.persistentVolumeClaim.${RUNTIME_PERSISTENT_VOLUME_CLAIM}.mount.path=/mnt/data \ --jars local:///ppml/bigdl-2.3.0-SNAPSHOT/jars/bigdl-ppml-spark_3.1.3-2.3.0-SNAPSHOT.jar \ local:///ppml/bigdl-2.3.0-SNAPSHOT/jars/bigdl-ppml-spark_3.1.3-2.3.0-SNAPSHOT.jar \ --inputPartitionNum 8 \ --outputPartitionNum 8 \ --inputEncryptModeValue AES/CBC/PKCS5Padding \ --outputEncryptModeValue AES/CBC/PKCS5Padding \ --inputPath /mnt/data/simplekms/encrypted-input \ --outputPath /mnt/data/simplekms/encrypted-output \ --primaryKeyPath /mnt/data/simplekms/primaryKey \ --kmsType SimpleKeyManagementService \ --simpleAPPID 98463816**** \ --simpleAPIKEY 15780936****
マスターノードのApache Sparkジョブのステータスを表示します。
次のコマンドを実行して、ドライバーとエグゼキュータの名前とステータスを表示します。
kubectl get pod
Apache Sparkジョブが完了すると、STATUSの値が
[実行中]
から[完了]
に変わります。次のコマンドを実行して、ポッドのログを表示します。
kubectl logs simplequery-xxx-exec-1
説明simplequery-xxx-exec-1を、前の手順で取得した名前の対応する値に置き換えます。
Apache Sparkジョブが完了すると、ポッドのログに
Finished
が表示されます。
ステップ4: 結果の復号化
をアップロードします。各ワーカーノードの暗号化出力ディレクトリに格納されているメタ
ファイルとpart-XXXX.csv.cbc
ファイルをマスターノードの暗号化出力ディレクトリに格納します。ファイルがアップロードされた後、次の図に示すように、マスターノードの暗号化された出力ディレクトリにデータが含まれます。
マスターノードの
/mnt/data/simplekms
ディレクトリにdecrypt.pyファイルを作成します。次のコマンドを実行して、
/mnt/data/simplekms
ディレクトリに切り替えます。cd /mnt/data/simplekms
次のコマンドを実行して、decrypt.pyファイルを作成して開きます。
sudo vim decrypt.py
I
キーを押して挿入モードに入ります。decrypt.pyファイルに次のコンテンツを追加します。
bigdl.ppml.ppml_context import * からの
from bigdl.ppml.ppml_context import * args = {"kms_type": "SimpleKeyManagementService", "app_id": "98463816****", "api_key": "15780936****", "primary_key_material": "/mnt/data/simplekms/primaryKey" } sc = PPMLContext("PPMLTest", args) encrypted_csv_path = "/mnt/data/simplekms/encrypted-output" csv_plain_df = sc.read(CryptoMode.AES_CBC_PKCS5PADDING) \ .option("header", "true") \ .csv(encrypted_csv_path) csv_plain_df.show() output_path = "/mnt/data/simplekms/decrypted-output" sc.write(csv_plain_df, CryptoMode.PLAIN_TEXT) \ .mode('overwrite') \ .option("header", True)\ .csv(output_path)
Esc
キーを押し、:wq
と入力して変更を保存し、挿入モードを終了します。
Kubernetesクラスターのマスターノードで次のコマンドを実行し、
encrypted_csv_path
ディレクトリに格納されているデータを復号します。APPID、APIKEY、およびprimarykeyは、データを復号化するために使用される。 復号化されたデータファイル
part-XXXX.csv
は、/mnt/data/simplekms/decrypted-output
ディレクトリに格納されます。java \ -cp '/ppml/spark-3.1.3/conf/:/ppml/spark-3.1.3/jars/*:/ppml/bigdl-2.3.0-SNAPSHOT/jars/*' \ -Xmx1g org.apache.spark.deploy.SparkSubmit \ --master 'local[4]' \ --conf spark.network.timeout=10000000 \ --conf spark.executor.heartbeatInterval=10000000 \ --conf spark.python.use.daemon=false \ --conf spark.python.worker.reuse=false \ --py-files /ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-ppml-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip,/ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip,/ppml/bigdl-2.3.0-SNAPSHOT/python/bigdl-dllib-spark_3.1.3-2.3.0-SNAPSHOT-python-api.zip \ /mnt/data/simplekms/decrypt.py
次の図に示すように、復号化されたデータがWindowsで表示されます。