NAI 2.4 の推論エンドポイントむけに作成したデモ アプリを、Nutanix Kubernetes Platform(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 Ready7d19h 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
Secret
secret.yaml
Deployment
deployment.yaml
- L20:前回の投稿 で作成したデモ アプリのコンテナ イメージを指定しています。(ghcr.io/gowatana/nai-demo-chat:v0.0.1)
Service
service.yaml
- L14:AI チャット アプリは、80 番ポートで公開します。
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
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
configmap.yaml
helm/nai-demo/templates/configmap.yaml
secret.yaml
helm/nai-demo/templates/secret.yaml
deployment.yaml
helm/nai-demo/templates/deployment.yaml
service.yaml
helm/nai-demo/templates/service.yaml
NOTES.txt
YMAL ファイルではありませんが、helm install や helm status 実行時に表示されるノートのテンプレートファイルを、下記のように編集しておきます。
helm/nai-demo/templates/NOTES.txt
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
つづく。
