65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Microsoft Azure 上构建安全的 Kubeflow 管道

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2023 年 12 月 18 日

CPOL

10分钟阅读

viewsIcon

5264

利用虚拟机上的 Intel® Software Guard Extensions 部署安全、加速的机器学习流水线

许多机器学习应用程序必须确保底层代码和数据的机密性和完整性。直到最近,安全性主要集中在加密静态数据(即存储中的数据)或传输中数据(即在网络上传输的数据),但并未关注正在使用的数据(即主内存中的数据)。Intel® Software Guard Extensions (Intel® SGX) 提供了一组指令,允许您安全地处理和保护应用程序代码和数据。Intel SGX 通过在 CPU 内创建受信任的执行环境来实现这一点。这允许容器中的用户级代码分配私有内存区域(称为 enclave)来执行应用程序代码。

借助 Microsoft Azure* 机密计算平台,您可以部署 Windows* 和 Linux 虚拟机 (VM),利用 Intel SGX 提供的安全性和机密性。本教程将展示如何为 Azure Kubernetes* Services (AKS) 集群设置 Intel SGX 节点。然后,我们将安装 Kubeflow*,这是一个用于 Kubernetes 的机器学习工具包,您可以使用它来构建和部署可扩展的机器学习流水线。最后,我们将演示如何使用Intel® Optimization for XGBoost*、Intel® oneAPI Data Analytics Library (oneDAL) 和Intel® Extension for Scikit-learn* 来加速模型训练和推理。

此优化模块是Intel® Cloud Optimization Modules for Microsoft Azure的一部分,该模块是一组云原生、开源的参考架构,旨在促进在主流云提供商(包括 Amazon Web Services* (AWS)、Microsoft Azure 和 Google Cloud Platform* (GCP))上构建和部署 Intel 优化 AI 解决方案。每个模块或参考架构都包含所有必要的说明和源代码。

此优化模块的云解决方案架构使用 AKS 集群,其中核心组件是 Intel SGX VM。AKS 集群附加了 Azure Container Registry,以便 Kubeflow 流水线可以构建容器化的 Python* 组件。这些 Azure 资源在 Azure Resource Group 中进行管理。然后,Kubeflow 软件层安装在 AKS 集群上。当 Kubeflow 流水线运行时,每个流水线 pod 都将被分配到一个 Intel SGX 节点。云解决方案架构如图 1 所示。

图 1. Kubeflow* 流水线架构图(图片来自作者)

准备工作

在开始本教程之前,请确保您已下载并安装了先决条件。然后,在一个新的终端窗口中,运行以下命令以使用 Azure 命令行界面与您的 Microsoft Azure 帐户进行交互式登录。

az login

接下来,创建一个将保存我们解决方案 Azure 资源的资源组。我们将把资源组命名为 intel-aks-kubeflow,并将位置设置为 eastus

# Set the names of the Resource Group and Location
export RG=intel-aks-kubeflow
export LOC=eastus
 
# Create the Azure Resource Group
az group create -n $RG -l $LOC

为了设置带有保密计算节点的 AKS 集群,我们将首先创建一个系统节点池并启用保密计算附加组件。保密计算附加组件将为集群配置一个 DaemonSet,以确保每个符合条件的 VM 节点运行一个 Azure 设备插件 pod 的副本,用于 Intel SGX。以下命令将使用来自Dv5 系列的标准 VM 来配置一个节点池,该 VM 使用第三代 Intel® Xeon® 处理器。这是将托管 AKS 系统 pod(如 CoreDNSmetrics-server)的节点。以下命令还将启用集群的托管标识并配置一个标准的 Azure 负载均衡器。

# Set the name of the AKS cluster
export AKS=aks-intel-sgx-kubeflow
 
# Create the AKS system node pool
az aks create --name $AKS \
--resource-group $RG \
--node-count 1 \
--node-vm-size Standard_D4_v5 \
--enable-addons confcom \
--enable-managed-identity \
--generate-ssh-keys -l $LOC \
--load-balancer-sku standard

请注意,如果您已经设置了 Azure Container Registry,则可以通过添加参数 --attach-acr <registry-name> 来将其附加到集群。

一旦系统节点池部署完毕,我们将把 Intel SGX 节点池添加到集群中。以下命令将配置两个四核 Intel SGX 节点,来自 Azure 的DCSv3 系列。我们已向此节点池添加了一个节点标签,键为 intelvm,值为 sgx。此键值对将在 Kubernetes nodeSelector 中引用,以将 Kubeflow 流水线 pod 分配给 Intel SGX 节点。

az aks nodepool add --name intelsgx \
--resource-group $RG \
--cluster-name $AKS \
--node-vm-size Standard_DC4s_v3 \
--node-count 2 \
--labels intelvm=sgx

一旦保密节点池设置完毕,请获取集群访问凭据,并使用以下命令将它们合并到您的本地 .kube/config 文件中

az aks get-credentials -n $AKS -g $RG

我们可以通过执行以下命令来验证集群凭据是否已正确设置。此命令应返回您的 AKS 集群名称。

kubectl config current-context

为了确保 Intel SGX VM 节点已成功创建,请运行

kubectl get nodes

您应该会看到两个以 aks-intelsgx 开头的代理节点正在运行。为了确保 DaemonSet 已成功创建,请运行

kubectl get pods -A

kube-system 命名空间中,您应该会看到两个以 sgxplugin 开头的 pod 正在运行。如果您看到上述 pod 和节点池正在运行,则表示您的 AKS 集群现已准备好运行保密应用程序,我们可以开始安装 Kubeflow。

安装 Kubeflow

要在 AKS 集群上安装 Kubeflow,请先克隆 Kubeflow Manifests GitHub 存储库。

git clone https://github.com/kubeflow/manifests.git

将目录更改为新克隆的 manifests 目录。

cd manifests

作为可选步骤,您可以使用以下命令更改访问 Kubeflow 仪表板的默认密码

python3 -c 'from passlib.hash import bcrypt; import getpass; print(bcrypt.using(rounds=12, ident="2y").hash(getpass.getpass()))'

导航到 dex 目录中的 config-map.yaml 文件,并在配置文件大约第 22 行附近的哈希值中粘贴新生成的密码。

nano common/dex/base/config-map.yaml
staticPasswords:
    - email: user@example.com
      hash:

接下来,将 Istio* 入站网关从 ClusterIP 更改为 LoadBalancer。这将配置一个外部 IP 地址,我们可以使用该地址从浏览器访问仪表板。导航到 common/istio-1-16/istio-install/base/patches/service.yaml,并在大约第 7 行将规范类型更改为 LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: istio-ingressgateway
  namespace: istio-system
spec:
  type: LoadBalancer

对于 AKS 集群,我们还需要从 Istio Webhook 中禁用 AKS admission enforcer。导航到 Istio install.yaml 文件,并在大约第 2694 行添加以下注释。

nano common/istio-1-16/istio-install/base/install.yaml
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: istio-sidecar-injector
  annotations:
    admissions.enforcer/disabled: 'true'
  labels:

接下来,我们将更新 Istio 网关以配置传输层安全 (TLS) 协议。这将允许我们通过 HTTPS 访问仪表板。导航到 kf-istio-resources.yaml 文件,并在文件末尾大约第 14 行粘贴以下内容

nano common/istio-1-16/kubeflow-istio-resources/base/kf-istio-resources.yaml
tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

现在我们已准备好安装 Kubeflow。我们将使用 kustomize 来通过一个命令安装组件。您也可以单独安装组件

while ! kustomize build example | awk '!/well-defined/' | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

所有组件的安装可能需要几分钟时间,有些组件可能在第一次尝试时失败。这是 Kubernetes 和 kubectl 工作方式的固有特性(例如,CR 必须在 CRD 就绪后创建)。解决方法是简单地重新运行命令直到成功。组件安装完成后,使用以下命令验证所有 pod 是否都在运行

kubectl get pods -A

可选:如果您为 Kubeflow 创建了新密码,请重新启动 dex pod 以确保它正在使用更新后的密码。

kubectl rollout restart deployment dex -n auth

最后,为 TLS 协议创建一个自签名证书,使用 Istio 负载均衡器的外部 IP 地址。要获取外部 IP 地址,请使用以下命令

kubectl get svc -n istio-system

创建 Istio 证书并复制以下内容

nano certificate.yaml
apiVersion: cert-manager.io/v1 
kind: Certificate 
metadata: 
  name: istio-ingressgateway-certs 
  namespace: istio-system 
spec: 
  secretName: istio-ingressgateway-certs 
  ipAddresses: 
    - <Istio IP address>  
  isCA: true 
  issuerRef: 
    name: kubeflow-self-signing-issuer 
    kind: ClusterIssuer 
    group: cert-manager.io

然后,应用证书

kubectl apply -f certificate.yaml

验证证书是否已成功创建

kubectl get certificate -n istio-system

现在,我们准备启动 Kubeflow 仪表板。要登录到仪表板,请在浏览器中输入 Istio IP 地址。首次访问仪表板时,您可能会收到警告。这是因为我们使用的是自签名证书。如果您有 SSL CA 证书,可以替换它,或者点击“高级”并“继续前往网站”。此时应出现 DEX 登录屏幕。输入您的用户名和密码。Kubeflow 的默认用户名是 user@example.com,默认密码是 12341234

登录 Kubeflow 仪表板后,我们现在可以部署 Kubeflow 流水线了。本模块中的 Kubeflow 流水线源自 Intel 与 Accenture 合作构建的贷款违约风险预测 AI 参考套件。通过重构代码,提高了模块化程度,更适合 Kubeflow 流水线。该流水线构建 XGBoost 模型来预测借款人的贷款违约风险,并使用Intel Optimization for XGBoost和 oneDAL 来加速模型训练和推理。完整流水线的图形表示如图 2 所示。

图 2. XGBoost* Kubeflow* 流水线图(图片由作者提供)

Kubeflow 流水线由以下七个组件组成

  • 加载数据:从流水线运行参数中指定的 URL 加载数据集(credit_risk_dataset.csv),并进行合成数据增强。下载 Kaggle 信用风险数据集。
  • 创建训练集和测试集:将数据分成训练集和测试集,大约为 75:25 的比例,用于模型评估。
  • 预处理特征:使用独热编码转换训练集和测试集的分类特征,此外还填充缺失值并对数值特征进行幂变换。
  • 训练 XGBoost 模型:此组件利用 Intel Optimization for XGBoost 提供的加速来训练模型。
  • 将 XGBoost 模型转换为 daal4py:将 XGBoost 模型转换为经过推理优化的 daal4py 分类器。
  • daal4py 推理:使用经过推理优化的 daal4py 分类器计算预测并评估模型性能。它返回每个类别的精确度、召回率和 F1 分数的输出摘要,以及模型的曲线下面积 (AUC) 和准确度分数。
  • 绘制接收器工作特性 (ROC) 曲线:对测试数据进行模型验证,并生成 ROC 曲线图。

流水线的代码可以在名为 intel-xgboost-daal4py-pipeline-azure.py 的 GitHub 存储库的 src 文件夹中找到。在运行 Python 脚本之前,请确保您已安装 Kubeflow Pipelines SDK 的 2.0 或更高版本。要更新您的 SDK 版本,您可以使用

pip install -U kfp

为了确保每个流水线 pod 都被分配到 Intel SGX 节点,已将 Kubernetes nodeSelector 添加到流水线中。在调度 pod 时,节点选择器将查找具有匹配键/值对的节点。使用我们添加到 Intel SGX 节点池的节点标签,以下代码会将数据预处理流水线任务 preprocess_features_op 分配给 Intel SGX 节点。

from kfp import kubernetes
 
kubernetes.add_node_selector(task = preprocess_features_op,
label_key = 'intelvm', label_value = 'sgx')

流水线组件

流水线中的第一个组件 load_data 从流水线运行参数中提供的 URL 下载信用风险数据集,并合成地将数据增强到指定大小。新数据集将作为输出工件保存在 Kubeflow MinIO volume 中。然后,该数据集被读入组件的下一步 create_train_test_set,该步骤将数据分割成大约 75:25 的比例用于模型评估。然后,训练集和测试集 X_trainy_trainX_testy_test 将作为输出数据集工件保存。

preprocess_features 组件中,创建了一个数据预处理流水线来为 XGBoost 模型准备数据。此组件从 MinIO 存储加载 X_trainX_test 文件,并使用独热编码转换分类特征,填充缺失值,并对数值特征进行幂变换。

下一个组件训练 XGBoost 模型。在 Intel CPU 上使用 XGBoost 可以利用 oneAPI 提供的软件加速,而无需进行任何代码更改。在对一百万个增量训练更新的初步测试中,Intel Optimization for XGBoost v1.4.2 相对于标准 XGBoost v0.81 提供了高达 1.54 倍的加速。(您可以在 GitHub 上查看贷款违约风险预测参考套件的所有性能结果。)以下代码片段实现在 train_xgboost_model 组件中

# Create the XGBoost DMatrix, which is optimized for memory efficiency and training speed
dtrain = xgb.DMatrix(X_train.values, y_train.values)
 
# Define model parameters
params = {"objective": "binary:logistic",
     "eval_metric": "logloss",
     "nthread": 4,  # num_cpu
     "tree_method": "hist",
     "learning_rate": 0.02,
     "max_depth": 10,
     "min_child_weight": 6,
     "n_jobs": 4,  # num_cpu
     "verbosity": 1}
 
# Train initial XGBoost model
clf = xgb.train(params = params, dtrain = dtrain, num_boost_round = 500)

为了进一步优化模型预测速度,我们在 convert_xgboost_to_daal4py 组件中将训练好的 XGBoost 模型转换为经过推理优化的 daal4py 分类器。daal4py 是 oneDAL 的 Python API。在对一百万个批次推理的测试中,oneDAL 提供了高达 4.44 倍的加速。您可以仅用一行代码将 XGBoost 模型转换为 daal4py

# Convert XGBoost model to daal4py
daal_model = d4p.get_gbt_model_from_xgboost(clf)

然后,在 daal4py_inference 组件中使用 daal4py 模型在测试集上评估模型的性能。

# Compute both class labels and probabilities
daal_prediction = d4p.gbt_classification_prediction(
     nClasses = 2, 
     resultsToEvaluate = "computeClassLabels|computeClassProbabilities"
).compute(X_test, daal_model)

我们通过调用上面的代码中的 gbt_classification_prediction 方法来计算二元类别标签和概率。您也可以使用此函数计算对数概率。此组件将以 CSV 格式返回分类报告,以及两个 Kubeflow 指标工件:曲线下面积和模型的准确度。这些可以在 metrics 工件的“可视化”选项卡中查看。

在流水线的最后一个组件 plot_roc_curve 中,我们加载了带有概率和真实类别标签的预测数据,以使用来自Intel Extension for Scikit-Learn的 CPU 加速版本来计算 ROC 曲线。当流水线运行完成后,结果将作为 Kubeflow ClassificationMetric Artifact 存储,可以在 roc_curve_daal4py 工件的“可视化”选项卡中查看(图 3)。

图 3. 分类器的 ROC 曲线

后续步骤

您可以在 GitHub 上访问完整的源代码。如果您在实现过程中需要帮助,请注册参加办公时间。您可以在Intel Cloud Optimization Modules 上了解更多信息,并在Intel® DevHub Discord 服务器上与我们聊天,以继续与同行开发者互动。

© . All rights reserved.