AWS上のPPSへのパスベースのルーティング¶
DataRobot MLOpsにより、ポータブル予測サーバー(PPS)を使用して、Kubernetesクラスター(マネージドまたはセルフマネージドAIプラットフォーム)にDataRobotのモデルをデプロイできます。 PPSは、監視エージェントとDataRobotモデルを含むDockerコンテナであり、Kubernetesなどのコンテナオーケストレーションツールを使用してデプロイできます。 その後、MLOpsのモニタリングとガバナンスの機能を使用できます。
同じKubernetesクラスターに複数のPPSをデプロイする場合、すべてのPPSへのエントリーポイントを1つのIPアドレスにしたいことがよくあります。 これに対する典型的なアプローチはパスベースのルーティングで、さまざまなKubernetes Ingressコントローラーを使用して実現できます。 既存のアプローチには、Traefik、HAProxy、NGINXなどがあります。
以下のセクションでは、Amazon EKSにデプロイされたPPSへのパスベースのルーティングに、NGINX Ingressコントローラーを使用する方法について説明します。
開始する前に¶
AWSおよび基盤となるサービスとやり取りするには、いくつかの前提条件があります。 これらのツールの一部(またはすべて)がすでにインストールおよび設定されている場合は、対応する手順をスキップできます。 詳細な手順については、Amazon EKSの開始方法 – eksctlを参照してください。
必要なツールのインストール¶
-
AWS CLI(バージョン2)をインストールします。
-
AWS CLIの認証情報を設定します。
-
eksctlをインストールします。
-
kubectl(KubernetesクラスターのCLI)をインストールして設定します。
-
ツールが正常にインストールされたことを確認します。
PPSコンテナの設定¶
この手順は、DataRobot AutoMLモデル用のPPSコンテナを作成してローカルでテストし、それらをAmazon Elastic Container Registry(ECR)にプッシュしたことを前提としています。 詳細については、モデルをAWS EKSにデプロイするを参照してください。
この基本ステップは、線形回帰と画像分類のユースケースのモデルで作成された2つのPPSに基づいており、それぞれKaggleの住宅価格データセットとFood-101データセットを使用しています。
最初のPPS(住宅価格)には、eXtreme Gradient Boosted Trees Regressor(Gamma Loss)モデルが含まれています。 2番目のPPS(画像二値分類 - hot dog not hot dog)には、トレーニングスケジュールモデルを使用したSqueezeNet Image Pretrained Featurizer + Keras Slim Residual Neural Network Classifierが含まれています。
後者のモデルは、DataRobot Visual Artificial Intelligence (AI)機能を使用してトレーニングされています。
Amazon EKSクラスターの作成¶
ECRに保存されたDockerイメージを使用して、Amazon EKSクラスターをスピンアップできます。 EKSクラスターには、次のいずれかを備えたVPCが必要です。
- 2つのパブリックサブネットと2つのプライベートサブネット
- 3つのパブリックサブネット
Amazon EKSでは、少なくとも2つのアベイラビリティーゾーンにサブネットが必要です。 パブリックサブネットとプライベートサブネットを持つVPCをお勧めします。Kubernetesがパブリックサブネットにパブリックロードバランサーを作成して、プライベートサブネット内のノードで実行されるポッドへのトラフィックを制御できるようにします。
-
(オプション)VPCに2つのパブリックサブネットと2つのプライベートサブネットを作成または選択します。 パブリックサブネットに対して「パブリックIPv4アドレスの自動割り当て」が有効になっていることを確認します。
備考
対応する
--vpc-private-subnets
および--vpc-public-subnets
パラメーターを指定しない場合、eksctlツールは必要なすべてのサブネットをバックグラウンドで作成します。 -
クラスターを作成します。
eksctl create cluster \ --name multi-app \ --vpc-private-subnets=subnet-XXXXXXX,subnet-XXXXXXX \ --vpc-public-subnets=subnet-XXXXXXX,subnet-XXXXXXX \ --nodegroup-name standard-workers \ --node-type t3.medium \ --nodes 2 \ --nodes-min 1 \ --nodes-max 3 \ --ssh-access \ --ssh-public-key my-public-key.pub \ --managed
備考
* `--managed`パラメーターを使用すると、[Amazon EKSマネージド型ノードグループ](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html){ target=_blank }が有効になります。 この機能は、Amazon EKS Kubernetesクラスターのノード(EC2インスタンス)のプロビジョニングとライフサイクル管理を自動化します。 クラスター用に最適化されたノードグループをプロビジョニングできます。 EKSは、最新バージョンのKubernetesとホストOSでノードを最新の状態に保ちます。 **eksctl**ツールでは、コマンドラインフラグまたは設定ファイルを使用して、特定のサイズとインスタンスタイプファミリーを選択できます。
* `--ssh-public-key`はオプションですが、クラスターでノードグループを作成するときに指定することを強くお勧めします。 このオプションは、マネージド型ノードグループ内のノードへのSSHアクセスを有効にします。 SSHアクセスを有効にすると、インスタンスに接続して、問題がある場合に診断情報を収集できます。 ノードグループの作成後にリモートアクセスを有効にすることはできません。
クラスターのプロビジョニングには通常10~15分かかり、結果は次のようになります。
![](../../images/int_damdmoa_large_009.png)
-
クラスターの準備ができたら、kubectlの設定が正しいかどうかテストします。
kubectl get svc
NGINX Ingressコントローラーをデプロイする¶
AWS Elastic Load Balancingは、3種類のロードバランサーをサポートしています。Application Load Balancer(ALB)、Network Load Balancer(NLB)、およびClassic Load Balancer(CLB)です。 詳細については、Elastic Load Balancingの機能を参照してください。
NGINX IngressコントローラーはAWSでNLBを使用します。 NLBは、極めて高いパフォーマンスが必要な場合のTCP、UDP、TLSトラフィックの負荷分散に最適です。 接続レベル(OSIモデルのレイヤー4)で動作するNLBは、トラフィックをAmazon VPC内のターゲットにルーティングし、超低レイテンシーを維持しながら毎秒数百万のリクエストを処理できます。 また、NLBは、突発的で不安定なトラフィックパターンに対処できるよう最適化されています。
NGINX Ingressコントローラーのデプロイ(このマニフェストファイルもNLBを起動):
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-
nginx/master/deploy/static/provider/aws/deploy.yaml
Kubernetesへのサービスの作成とデプロイ¶
-
Kubernetes名前空間を作成します。
kubectl create namespace aws-tlb-namespace
-
次の内容をローカルマシン(この場合は
house-regression-deployment.yaml
)のyaml
ファイルに保存し、プロジェクトの値を置き換えます。以下に例を示します。apiVersion: apps/v1 kind: Deployment metadata: name: house-regression-deployment namespace: aws-tlb-namespace labels: app: house-regression-app spec: replicas: 3 selector: matchLabels: app: house-regression-app template: metadata: labels: app: house-regression-app spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 containers: - name: house-regression-model image: <your_image_in_ECR> ports: - containerPort: 80
-
次の内容をローカルマシン(この場合は
house-regression-service.yaml
)のyaml
ファイルに保存し、プロジェクトの値を置き換えます。以下に例を示します。apiVersion: v1 kind: Service metadata: name: house-regression-service namespace: aws-tlb-namespace labels: app: house-regression-app spec: selector: app: house-regression-app ports: - protocol: TCP port: 8080 targetPort: 8080 type: NodePort
-
Kubernetesサービスとデプロイを作成します。
kubectl apply -f house-regression-deployment.yaml kubectl apply -f house-regression-service.yaml
-
次の内容をローカルマシン(この場合は
hot-dog-deployment.yaml
)のyaml
ファイルに保存し、プロジェクトの値を置き換えます。以下に例を示します。apiVersion: apps/v1 kind: Deployment metadata: name: hot-dog-deployment namespace: aws-tlb-namespace labels: app: hot-dog-app spec: replicas: 3 selector: matchLabels: app: hot-dog-app template: metadata: labels: app: hot-dog-app spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 containers: - name: hot-dog-model image: <your_image_in_ECR> ports: - containerPort: 80
-
次の内容をローカルマシン(この場合は
hot-dog-service.yaml
)のyaml
ファイルに保存し、プロジェクトの値を置き換えます。以下に例を示します。apiVersion: v1 kind: Service metadata: name: hot-dog-service namespace: aws-tlb-namespace labels: app: hot-dog-app spec: selector: app: hot-dog-app ports: - protocol: TCP port: 8080 targetPort: 8080 type: NodePort
-
Kubernetesサービスとデプロイを作成します。
kubectl apply -f hot-dog-deployment.yaml kubectl apply -f hot-dog-service.yaml
-
名前空間に存在するすべてのリソースを表示します。
kubectl get all -n aws-tlb-namespace
パスベースのルーティング用のIngressリソースの作成とデプロイ¶
-
次の内容をローカルマシン(この場合は
nginx-redirect-ingress.yaml
)のyaml
ファイルに保存し、プロジェクトの値を置き換えます。以下に例を示します。apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx-redirect-ingress namespace: aws-tlb-namespace annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 labels: app: nginx-redirect-ingress spec: rules: - http: paths: - path: /house-regression(/|$)(.*) backend: serviceName: house-regression-service servicePort: 8080 - path: /hot-dog(/|$)(.*) backend: serviceName: hot-dog-service servicePort: 8080
備考
nginx.ingress.kubernetes.io/rewrite-target
注釈は、リクエストをバックエンドポッドに転送する前にURLを書き換えます。 その結果、パス/house-regression/some-house-pathと/hot-dog/some-dog-pathは、それぞれ/some-house-pathと/some-dog-pathに変換されます。 -
パスベースルーティングのIngressを作成します。
kubectl apply -f nginx-redirect-ingress.yaml
-
Ingressが正常に作成されたことを確認します。
kubectl get ingress/nginx-redirect-ingress -n aws-tlb-namespace
-
(オプション)次を使用すると、このイングレスに関する詳細な出力にアクセスできます。
kubectl describe ingress/nginx-redirect-ingress -n aws-tlb-namespace
次の2つのスコアリング要求の出力で
Address
の値に注意してください。 -
house-regressionモデルをスコアリングします。
curl -X POST http://<ADDRESS>/house-regression/predictions -H "Content-Type: text/csv" --data-binary @kaggle_house_test_dataset_10.csv
-
hot-dogモデルをスコアリングします。
curl -X POST http://<ADDRESS>/hot-dog/predictions -H "Content-Type: text/csv; charset=UTF-8" --data-binary @for_pred.csv
備考
for_pred.csv
は、ヘッダー付きの1つの列を含むCSVファイルです。 その列のコンテンツは、Base64でエンコードされた画像です。予測用の元の写真(ここからダウンロード済み):
画像はホットドッグであると予測されます。
予測用の別の写真(ここからダウンロード済み):
画像はホットドッグではないと予測されます。
削除¶
-
サンプルサービス、デプロイ、ポッド、名前空間を削除します。
kubectl delete namespace aws-tlb-namespace kubectl delete namespace ingress-nginx
-
クラスターを削除します。
eksctl delete cluster --name multi-app
まとめ¶
同じIPアドレスの背後にいくつかのKubernetesサービスをデプロイすると、必要なロードバランサーの数を最小限に抑え、アプリケーションのメンテナンスを容易にすることができます。 Kubernetes Ingressコントローラーを適用すると、それが可能になります。
このチュートリアルでは、Amazon EKSプラットフォームにデプロイされたいくつかのポータブル予測サーバー(PPS)へのパスベースのルーティングを展開する方法について説明しました。 このソリューションは、NGINX Ingressコントローラーを介して実装されています。