NTNX>日記

個人的な趣味による Nutanix Community Edition 日記。Japanese のみですみません。

NAI 2.4 の推論エンドポイントむけデモ アプリを NKP で起動してみる。

NAI 2.4 の推論エンドポイントむけに作成したデモ アプリを、Nutanix  Kubernetes Platform(NKP)で作成した Kubernetes クラスタで起動してみます。

 

今回の内容です。

 

今回の環境

使用するデモ アプリは、下記の投稿で作成したものです。

NKP による Kubernetes クラスタは作成ずみです。以前に作成したデモ アプリを、下記のように NKP の Kubernetes クラスタで起動します。

 

1. 作業マシンの準備

作業用の Linux マシン(Ubuntu)に、kubectl をインストールして、Kubernetes クラスタに接続できるようにします。

今回の作業用マシンは Ubuntu 24.04 です。

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.3 LTS"

 

作業中の確認などで使用するため、tree と jq をインストールします。

$ sudo apt install tree jq -y

 

CLI ツールのインストール先として、$HOME/bin ディレクトリを作成しておきます。このディレクトリは、再ログインすると $PATH 環境変数に追加されます。

$ mkdir $HOME/bin

 

kubectl をダウンロードしてインストール($PATH のディレクトリに保存)します。

$ curl -sL -o $HOME/bin/kubectl https://dl.k8s.io/release/v1.32.3/bin/linux/amd64/kubectl
$ chmod +x $HOME/bin/kubectl

 

kubectl が実行できることを確認しておきます。

$ kubectl version --client
Client Version: v1.32.3
Kustomize Version: v5.5.0

 

NKP の kubeconfig ファイルをダウンロードして、$HOME/.kube/config という名前で保存しておきます。

ls -l $HOME/.kube/config

 

NKP の Kubernetes クラスタに接続できることを確認しておきます。

$ kubectl get nodes
NAME                            STATUS   ROLES           AGE     VERSION
nkpw02-5jkcf-wx4bc              Ready    control-plane   7d19h   v1.33.2
nkpw02-md-0-9xs7f-nhlcz-dbdwd   Ready              7d19h   v1.33.2

 

2. Kubernetes でのアプリの起動

アプリを構成する Kubernetes リソースを記載した YAML ファイルを作成して、kubectl で Kubernetes クラスタに適用します。

 

2-1. マニフェスト(YAML ファイル)の作成

今回は、ConfigMap、Secret、Deployment、Service を作成します。それぞれ、独立した YAML ファイルを用意しておきます。

まず、YAML ファイルを格納するディレクトリを作成します。

$ mkdir -p nai-demo-chat/yaml

 

テキスト エディタなどで YAML ファイルを作成します。

$ vi nai-demo-chat/yaml/configmap.yaml
$ vi nai-demo-chat/yaml/secret.yaml
$ vi nai-demo-chat/yaml/deployment.yaml
$ vi nai-demo-chat/yaml/service.yaml

 

ディレクトリとファイルの構成は、下記のようになります。

$ tree ./nai-demo-chat/yaml/ --charset=ascii
./nai-demo-chat/yaml/
|-- configmap.yaml
|-- deployment.yaml
|-- secret.yaml
`-- service.yaml

1 directory, 4 files

 

それぞれの YAML ファイルは、下記のように作成してあります。

 

ConfigMap

configmap.yaml

gist.github.com

 

Secret

secret.yaml

gist.github.com

 

Deployment

deployment.yaml

  • L20:前回の投稿 で作成したデモ アプリのコンテナ イメージを指定しています。(ghcr.io/gowatana/nai-demo-chat:v0.0.1)

gist.github.com

 

Service

service.yaml

  • L14:AI チャット アプリは、80 番ポートで公開します。

gist.github.com

 

2-2. アプリの起動

アプリを起動する Namespace(今回は demo)を作成します。

$ kubectl create namespace demo
namespace/demo created

 

kubectl apply で、YAML ファイルをもとに Kubernetes リソースを作成します。

ConfigMap を作成します。

$ kubectl apply -f ./nai-demo-chat/yaml/configmap.yaml -n demo
configmap/nai-demo-config created
$ kubectl get -f ./nai-demo-chat/yaml/configmap.yaml -n demo
NAME              DATA   AGE
nai-demo-config   2      10s

 

Secert を作成します。

$ kubectl apply -f ./nai-demo-chat/yaml/secret.yaml -n demo
secret/nai-demo-secret created
$ kubectl get -f ./nai-demo-chat/yaml/secret.yaml -n demo
NAME              TYPE     DATA   AGE
nai-demo-secret   Opaque   1      5s

 

Secret は、kubectl create secret でも作成できます。

kubectl create secret generic nai-demo-secret -n demo \
--from-literal NAI_API_KEY=d8cb366b-d68d-4f9e-8a65-7075e137977e

 

Deployment を作成します。

$ kubectl apply -f ./nai-demo-chat/yaml/deployment.yaml -n demo
deployment.apps/nai-demo-chat created
$ kubectl get -f ./nai-demo-chat/yaml/deployment.yaml -n demo
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
nai-demo-chat   1/1     1            1           46s 

 

Service を作成します。

$ kubectl apply -f ./nai-demo-chat/yaml/service.yaml -n demo
service/nai-demo-chat created
$ kubectl get -f ./nai-demo-chat/yaml/service.yaml -n demo
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
nai-demo-chat   LoadBalancer   10.101.215.6   172.22.5.213   80:30258/TCP   6s

 

ディレクトリに YAML ファイルをまとめて格納してある場合は、kubectl apply の「-f」でディレクトリも指定できます。

ディレクトリに、YAML ファイル一式が配置されていることを確認します。

$ ls -1 ./nai-demo-chat/yaml/
configmap.yaml
deployment.yaml
secret.yaml
service.yaml

 

kubectl apply を実行します。

$ kubectl apply -f ./nai-demo-chat/yaml/ -n demo
configmap/nai-demo-config created
deployment.apps/nai-demo-chat created
secret/nai-demo-secret created
service/nai-demo-chat created

 

Pod が起動される(STATUS が Running になる)まで待ちます。

$ kubectl get pod -n demo
NAME                             READY   STATUS    RESTARTS   AGE
nai-demo-chat-5b89b9c6d4-5499j   1/1     Running   0          58s

 

Service リソースで用意された、Load Blancer の IP アドレスを確認します。ここで EXTERNAL-IP に表示される IP アドレスに Web ブラウザでアクセスすると、AI チャットの画面が表示されるはずです。

$ kubectl get svc -n demo
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
nai-demo-chat   LoadBalancer   10.96.131.102   172.22.5.213   80:31582/TCP   64s

 

2-3. アプリの削除

アプリが起動できたことを確認したら、作成したリソースを kubectl delete で削除しておきます。

Service を削除します。

kubectl delete -f ./nai-demo-chat/yaml/service.yaml -n demo

 

Deployment を削除します。

kubectl delete -f ./nai-demo-chat/yaml/deployment.yaml -n demo

 

Secret を削除します。

kubectl delete -f ./nai-demo-chat/yaml/secret.yaml -n demo

 

ConfigMap を削除します。

kubectl delete -f ./nai-demo-chat/yaml/configmap.yaml -n demo

 

下記のように YAML ファイルを格納したディレクトリを指定すれば、まとめて削除できます。

$ kubectl delete -f ./nai-demo-chat/yaml/ -n demo
configmap "nai-demo-config" deleted
deployment.apps "nai-demo-chat" deleted
secret "nai-demo-secret" deleted
service "nai-demo-chat" deleted

 

Namespace も削除しておきます。

$ kubectl delete namespace demo

 

3. Helm Chart の作成

Kubernetes の YAML マニフェストをもとに Helm Chart を作成して、そこからアプリをインストールします。

 

3-1. Helm のインストール

Helm の tar.gz アーカイブ ファイルをダウンロードします。

$ curl -kOL https://get.helm.sh/helm-v3.19.0-linux-amd64.tar.gz

 

ファイルを展開して、$HOME/bin ディレクトリにインストールします。

$ tar zxvf helm-v3.19.0-linux-amd64.tar.gz
$ install linux-amd64/helm $HOME/bin/

 

tar.gz と不要になった展開ファイルは削除しておきます。

$ rm -rf linux-amd64/
$ rm helm-v3.19.0-linux-amd64.tar.gz

 

helm コマンドが実行可能になったことを確認しておきます。

$ helm version
version.BuildInfo{Version:"v3.19.0", GitCommit:"3d8990f0836691f0229297773f3524598f46bda6", GitTreeState:"clean", GoVersion:"go1.24.7"}

 

3-2. Helm Chart の作成

まず、作業用ディレクトリを作成しておきます。

$ mkdir helm

Helm Chart のひな型を作成します。

$ helm create helm/nai-demo
Creating helm/nai-demo

 

下記のようにディレクトリとファイルが作成されます。

$ tree helm/nai-demo/ --charset=ascii
helm/nai-demo/
|-- Chart.yaml
|-- charts
|-- templates
|   |-- NOTES.txt
|   |-- _helpers.tpl
|   |-- deployment.yaml
|   |-- hpa.yaml
|   |-- httproute.yaml
|   |-- ingress.yaml
|   |-- service.yaml
|   |-- serviceaccount.yaml
|   `-- tests
|       `-- test-connection.yaml
`-- values.yaml

4 directories, 11 files

 

今回は使用しないファイルを削除します。

$ rm -rf helm/nai-demo/templates/{tests,hpa.yaml,httproute.yaml,ingress.yaml,serviceaccount.yaml}

 

そして、あらかじめ用意しておいた YAML ファイルを、templates ディレクトリ配下にテンプレートむけに編集して配置します。

結果的に、下記のようなファイル構成になります。

$ tree ./helm/nai-demo/ --charset=ascii
./helm/nai-demo/
|-- Chart.yaml
|-- charts
|-- templates
|   |-- NOTES.txt
|   |-- _helpers.tpl
|   |-- configmap.yaml
|   |-- deployment.yaml
|   |-- secret.yaml
|   `-- service.yaml
`-- values.yaml

3 directories, 8 file

 

それぞれの YAML テンプレート ファイルは、下記のように作成してあります。

 

Chart.yaml

helm/nai-demo/Chart.yaml

gist.github.com

 

values.yaml

values.yaml ファイルの末尾(L93)に追記した secret.NAI_API_KEY の API キーは、このまま公開しても問題ないようにダミー文字列にしてあります。

config:
  NAI_ENDPOINT_NAME: "gemma-ep-01"
  NAI_ENDPOINT_URL: "https://10.1.7.122/api/v1/chat/completions"

secret:
  NAI_API_KEY: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

 

helm/nai-demo/values.yaml

gist.github.com

 

configmap.yaml

helm/nai-demo/templates/configmap.yaml

gist.github.com

 

secret.yaml

helm/nai-demo/templates/secret.yaml

gist.github.com

 

deployment.yaml

helm/nai-demo/templates/deployment.yaml

gist.github.com

 

service.yaml

helm/nai-demo/templates/service.yaml

gist.github.com

 

NOTES.txt

YMAL ファイルではありませんが、helm install や helm status 実行時に表示されるノートのテンプレートファイルを、下記のように編集しておきます。

helm/nai-demo/templates/NOTES.txt

gist.github.com

 

Helm Chart の内容に問題がないか確認しておきます。

$ helm lint ./helm/nai-demo/
==> Linting ./helm/nai-demo/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

 

3-3. Helm Chart のインストール(ローカル Chart)

Helm Chart を使用して、デモ アプリをインストールします。ここでは、「nai-demo」という名前でインストールしています。今回は、わかりやすさを優先して「--set」オプションで API Key も指定してしまっています。

helm install nai-demo ./helm/nai-demo \
-n nai-demo --create-namespace \
--set config.NAI_ENDPOINT_NAME="gemma-ep-01" \
--set config.NAI_ENDPOINT_URL="https://10.1.7.122/api/v1/chat/completions" \
--set secret.NAI_API_KEY="d8cb366b-d68d-4f9e-8a65-7075e137977e"

 

実際にコマンドを実行すると、下記のようになります。

$ helm install nai-demo ./helm/nai-demo \
-n nai-demo --create-namespace \
--set config.NAI_ENDPOINT_NAME="gemma-ep-01" \
--set config.NAI_ENDPOINT_URL="https://10.1.7.122/api/v1/chat/completions" \
--set secret.NAI_API_KEY="d8cb366b-d68d-4f9e-8a65-7075e137977e"
NAME: nai-demo
LAST DEPLOYED: Thu Oct 16 11:04:28 2025
NAMESPACE: nai-demo
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get the application URL by running these commands:
  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        You can watch its status by running 'kubectl get --namespace nai-demo svc -w nai-demo'

  $ export SERVICE_IP=$(kubectl get svc --namespace nai-demo nai-demo -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
  $ echo http://$SERVICE_IP:80

 

helm list を実行すると、下記のように表示されます。

$ helm list -n nai-demo
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
nai-demo        nai-demo        1               2025-10-16 11:04:28.673148192 +0000 UTC deployed        nai-demo-0.0.1  0.0.1

 

デモ アプリにアクセスできる LoadBlancer Service の URL は、下記のように確認できます。

$ SERVICE_IP=$(kubectl get svc --namespace nai-demo nai-demo -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
$ echo http://$SERVICE_IP:80
http://172.22.5.213:80

 

3-4. アプリの削除

インストール時に指定した、「nai-demo」という名前を指定して、helm uninstall を実行します。

$ helm uninstall nai-demo -n nai-demo
release "nai-demo" uninstalled

 

Namespace も削除しておきます。

$ kubectl delete namespace nai-demo
namespace "nai-demo" deleted

 

4. Helm Chart の公開

Helm Chart の .tgz パッケージを作成して、OCI レジストリに Push します。OCI レジストリは、今回はコンテナ レジストリと同じく GitHub Container Registry を使用しています。

 

4-1. Helm Chart パッケージの作成

helm package を実行して、.tgz(tar + gzip)ファイルを作成します。

$ helm package ./helm/nai-demo/
Successfully packaged chart and saved it to: /home/gowatana/nai-demo-0.0.1.tgz

 

4-2. Helm Chart の Push

OCI レジストリに、Helm Chart を Push します。

helm コマンドで、GitHub Container Registry(ghcr.io)にログインします。

$ helm registry login ghcr.io
Username: gowatana
Password:
Login Succeeded

 

.tgz ファイルを、Push します。宛先の ghcr.io/gowatana リポジトリは、私の個人リポジトリです。

$ helm push nai-demo-0.0.1.tgz oci://ghcr.io/gowatana/nai-demo-repo
Pushed: ghcr.io/gowatana/nai-demo-repo/nai-demo:0.0.1
Digest: sha256:c75c31fdf351949f14ebf1ff27252a6a8bcee6ad123d76220f41f0a04785c9aa

 

OCI アーティファクトとして Push したパッケージを、認証なしで Pull できるように公開(Visibility を Public に設定)しておきます。この手順は、前回の投稿 で実施したコンテナ イメージと同様です。

今回の OCI リポジトリはこちら。

 

4-3. Helm Chart のインストール(OCI アーティファクトの Chart)

helm install で、Helm Chart を「oci://~」といった名前で指定してインストールします。

helm install nai-demo oci://ghcr.io/gowatana/nai-demo-repo/nai-demo \
--version 0.0.1 \
-n nai-demo --create-namespace \
--set config.NAI_ENDPOINT_NAME="gemma-ep-01" \
--set config.NAI_ENDPOINT_URL="https://10.1.7.122/api/v1/chat/completions" \
--set secret.NAI_API_KEY="d8cb366b-d68d-4f9e-8a65-7075e137977e"

 

helm list コマンドでは、さきほどと同様にインストールされたアプリが表示されます。

$ helm list -n nai-demo
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
nai-demo        nai-demo        1               2025-10-16 11:50:30.981327706 +0000 UTC deployed        nai-demo-0.0.1  0.0.1

 

4-4. アプリの削除

アンインストールについては、ローカル Chart でのインストールと同様に helm uninstall を実行します。

helm uninstall nai-demo -n nai-demo

 

そして、Namespace も削除しておきます。

kubectl delete namespace nai-demo

 

つづく。

 

©2026 gowatana
クリエイティブ・コモンズ・ライセンスこの 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。