はじめに
GAFA社長でっす。
この記事はNutanix Advent Calender 2024のために書き始めたのですが、ちょっとひとつの記事にするにはボリュームが大きすぎるので、分割して公開します。ていうかクリスマスまでに最後まで書ききれるのか?
2024年、Nutanixが俄然張り切り出した領域のひとつが、AIワークロードのためのプラットフォームとしてのNutanixという切り口です。分散ストレージとしてのAOS、Kubernetesクラスタの管理、GPUリソースの管理といったNutanixがそもそも得意としているテクノロジーをAIワークロードを動かすために活用しましょう、という話です。
話はわかるけど、実際何がどう動くのよ?というのを簡単にお見せするために、私が今年よく披露したデモが、Nutanix Kubernetes Platform(NKP)の上でDifyを動かし、バックエンドではNUSやNDBを使用して、 「ジョジョのことならなんでも知ってるジョジョマニアくん」 という簡単なRAGアプリケーションをその場で作って見せる、というものでした。
Nutanixでやると構築自体はちょちょいとできるのですが、「どうやって構築するの?」という声も多いので、ざっくり手順を公開します。
この記事は第一弾、NKP編です。
作業環境の準備
NKPは様々なインフラ上で動作するため、デプロイ方法も様々ですが、ここでは以下を前提とします。
- Nutanixクラスタ(NCI)の上に、NKPの
Nutanix Infrastructure Provider
を使ってデプロイする - インターネットに接続されている(dockerhubからイメージをpullできる)環境である
NKPのインストーラーは nkp
というシングルバイナリで提供されます。実際にはこのコマンドで kind
(Kubernetes in Docker)のbootstrapクラスタがローカルに展開され、そこからCluster APIを利用してデプロイ先のインフラにKubernetesクラスタが展開されます。
nkpコマンドは、Linux版とMacOS(Darwin)版があります。手元のPCで動かしてもよいのですが、せっかくNutanixを使うので、Nutanixクラスタ上に作業用の仮想マシンを立てましょう。
DockerあるいはPodmanと、kubectl/helmが使えればよいので、Linuxのディストリビューションはまあなんでもよいのですが、私は使い慣れているUbuntu24.04で作業します。
Docker,kubectl,helmをインストールし、nkpのバイナリをパスの通ったところに配置しておきます。作業を行うユーザーでdocker
コマンドが実行できるようにしておきましょう。
デプロイ先のインフラの準備
詳しくはドキュメントを読むべきですが、Nutanix Infrastructure Providerを使用してNutanixクラスタ上にNKPをデプロイする場合は、
- 使用するSubnet
- そのSubnet内で、Kubernetesのノード数ぶんのIPアドレスの空きがあるIPAMプールがあること
- 同じSubnet内で、ひとつのKubernetesクラスタにつき下記がIPAMプール外で 割り当て可能なこと
- Kubernetes API用のIPアドレス x1
- MetalLBロードバランサー用のIPアドレス x1以上 (ひとつはNKPの管理サービス用にTraefikが使う)
を確認しておきましょう。
あとプロダクション環境の場合は、TLSのためにDNSとか証明書とかも当然準備する必要がありますが、今回は社内検証環境なので割愛。
NKPのノードイメージを作る
Kubernetesの各ノードは仮想マシンとして展開されますので、そのための仮想マシンイメージを用意しておく必要があります。
NKPのダウンロードサイトにはRocky9.5ベースのイメージが用意されていますが、NKPのKonvoy Image Builderという機能を使ってカスタムイメージを作成することもできます。
今回はNutanix Enterprise AI (NAI)を動作させるため、Ubuntu22.04のイメージを作成しておきます。
$ export NUTANIX_USER=nkp # Prism Centralのadmin権限を持つユーザー名
$ export NUTANIX_PASSWORD=nx2Tech685! # 上記ユーザーのパスワード
$ ./nkp create image nutanix ubuntu-22.04 --cluster PHX-POC174 --endpoint 10.38.174.39 --subnet Secondary --insecure
これでPackerのビルドVMが立ち上がり、しばらく待つとPrism Central上に仮想マシンイメージが登録されます。
Prism Centralのユーザーは、デフォルトの admin
ユーザーを使用するとあとあとめんどくさいことになるので、必ずNKP専用のユーザー(Admin権限が必要)を作成しておくようにしましょう。
NKPをデプロイする
管理クラスタのデプロイ
NKPはシングルクラスタでも動作しますが、Cluster APIやGit Operatorを駆使してマルチKubernetesクラスタを管理するための便利機能がいろいろついてきます。
マルチクラスタ構成において、クラスタを管理するためのクラスタは Management Cluster
、管理対象となるクラスタは Managed Cluster
と呼ばれていますが、紛らわしいのでこの記事では「管理クラスタ」「ワークロードクラスタ」と呼びます。ちなみにシングルクラスタ構成の場合は Self Managed Cluster
となります。
ワークロードクラスタの構成は、管理クラスタ上のCluster APIリソースとしてKubernetesネイティブに管理されます。また、NKPにはワークロードクラスタをグループ化する workspace
という概念があり、アプリケーションのライフサイクルをクラスタ単位だけではなく、workspace単位で管理することもできます。
今回は最終的に複数のKubernetesクラスタを使用するので、管理クラスタではユーザーワークロードは動かさない前提でシンプルに作成します。
以下のコマンドでTUIが起動しますので、あとは必要な情報を入れていくだけです。
$ nkp create cluster nutanix
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Prism Central > Cluster Configuration > Additional Configuration (optional) > Create Cluster│
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│Prism Central Endpoint*: https://10.38.174.39:9440/ │
│Username*: nkp │
│Password*: *********** │
│Insecure: ( )No (•)Yes │
│Additional Trust Bundle: A PEM file as base64 encoded string │
│Project: │
│ │
│> (No Project) │
│ │
│ │
│ │
│ │
│Prism Element Cluster*: │
│ │
│> PHX-POC174 │
│ │
│ │
│ │
│ │
│Subnet*: │
│ │
│ Primary │
│> Secondary │
│ │
│ │
│ │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│shift+tab Move Up enter/tab Select Item ctrl+p Previous Page │
│tab Move Down / Filter Items ctrl+n Next Page │
│left Move Left esc Remove Filter ctrl+c Quit │
│right Move Right │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
最初のページでPrism Centralのユーザー名とパスワードを入れると、Project
Prism Element Cluster
Subnet
は選択肢が自動的に表示されるので選ぶだけです。
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│Cluster Name*: nkpmgmt │
│Control Plane Endpoint*: 10.38.174.135:6443 │
│VM Image*: │
│ │
│> nkp-rocky-9.5-1.30.5-20241207055446 │
│nkp-ubuntu-22.04-1.30.5-20241207070359 │
│ │
│ │
│ │
│ │
│Kubernetes Network │
│Service Load Balancer IP Range*: 10.38.174.136-10.38.174.138 │
│Pod Network: 192.168.0.0/16 │
│Service Network: 10.96.0.0/12 │
│ │
│Storage │
│Reclaim Policy: (•)Delete ( )Retain │
│File System: (•)ext4 ( )xfs │
│Hypervisor Attached Volumes: (•)Yes ( )No │
│Storage Container*: │
│ │
│ default-container-171380 │
│> k8s │
│ objectsd076ab2dd490845c87ccf0b65cca62235 │
│ │
│ ••• │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
Control Plane Endpoint
は、KubernetesのAPIエンドポイントです。選択したSubnetの中の、IPAMプール外のアドレスを指定してください。
Service Load Balancer IP Range
は、MetalLBが使用するIPアドレスのレンジです。このレンジの最初のIPアドレスが、NKPのダッシュボード(Kommander Dashboard)用のTraefikのIngressで使用されます。
VM Image
はあらかじめPrism Centralに登録されているNKP用のイメージが出てきます。ここで何も出てこない場合はイメージの登録が失敗している、あるいはイメージ名が間違っています。
╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
│Cluster Domain/ FQDN / Hostname for Ingress: FQDN │
│ │
│ACME Configuration │
│ACME Server: https://acme-v02.api.letsencrypt.org/directory │
│Email address for ACME Server: example@domain.com │
│ │
│Ingress │
│Certificate file: local filepath to certificate PEM file │
│Private key file: local filepath to private key PEM file │
│CA chain file: local filepath to CA chain PEM file │
│ │
│Registry │
│Registry URL: https://registry-1.docker.io │
│Registry CA Certificate: local filepath to registry CA Certificate │
│Registry Username: jyoshise │
│Registry Password: *************** │
│ │
│SSH │
│SSH User: konvoy │
│SSH public key: /home/ubuntu/.ssh/id_rsa.pub │
│ │
│Proxy │
│HTTP Proxy: │
│HTTPS Proxy: │
│No Proxy: comma separated No Proxy list for all nodes in the cluster │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
このページは入力必須ではないのですが、Registry
の項目は埋めた方がいいです。デフォルトでdockerhubからコンテナイメージを引っ張ってくるのですが、社内ネットワークから匿名でやろうとすると常にdockerhubのrate limitに引っかかる状態になっていると思うので、ImagePullBackOffしか出ねえってなります。
これを避けるには、ローカルにミラーレジストリを立てる(そのためのAir-Gapped Bundleというものも用意されています)という手もありますが、dockerhubのログイン情報を入れるだけでもだいたい回避できます。
最後に確認画面で、
│━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│
│Create NKP Cluster?: ( )Create (•)Dry Run │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
と出ます。ここで Create
を選択するとbootstrapクラスタが作成され、Nutanix上に管理クラスタがデプロイされます。
このTUIではあまり細かい構成の指定ができない(ノードのサイズや数も選べない)のですが、 Dry Run
を選択すると、実際のデプロイは行われず、ClusterリソースなどのManifest(YAML)が吐き出されるので、そのYAMLを編集してからbootstrapクラスタを起動し、kubectl applyするということも可能です。あるいは、nkp create cluster
コマンドのオプションで各種指定をすることもできます。
ここでは管理クラスタはデフォルト構成でデプロイしますので、Create
を選択します。
✓ Creating a bootstrap cluster
✓ Initializing new CAPI components
✓ Initializing new CAPI components
✓ Creating ClusterClass resources
✓ Creating ClusterClass resources
Generating cluster resources
cluster.cluster.x-k8s.io/nkpmgmt created
secret/nkpmgmt-pc-credentials created
secret/nkpmgmt-pc-credentials-for-csi created
secret/nkpmgmt-image-registry-credentials created
configmap/kommander-bootstrap-configuration created
secret/global-nutanix-credentials created
✓ Waiting for cluster infrastructure to be ready
✓ Waiting for cluster control-planes to be ready
✓ Waiting for machines to be ready
ここまで進むと、KubernetesクラスタのノードがNutanixクラスタ上に展開され始めているはずです。Prism Centralでタスクを眺めてそれをつまみに一杯やりましょう。
nkpコマンドでは以下のように確認できます。bootstrapクラスタのkubeconfigファイルが作成されているので、それを指定します。(つまり kubectl get cluster -A
などでも確認できます。)
$ ./nkp describe cluster -c nkpmgmt --kubeconfig=nkpmgmt-bootstrap.conf
NAME READY SEVERITY REASON SINCE MESSAGE
Cluster/nkpmgmt False Warning ScalingUp 36s Scaling up control plane to 3 replicas (actual 2)
├─ClusterInfrastructure - NutanixCluster/nkpmgmt-nnsbp
├─ControlPlane - KubeadmControlPlane/nkpmgmt-2hvnj False Warning ScalingUp 36s Scaling up control plane to 3 replicas (actual 2)
│ ├─Machine/nkpmgmt-2hvnj-2gpl7 True 2m55s
│ │ └─MachineInfrastructure - NutanixMachine/nkpmgmt-2hvnj-2gpl7
│ └─Machine/nkpmgmt-2hvnj-kbh7x True 12s
│ └─MachineInfrastructure - NutanixMachine/nkpmgmt-2hvnj-kbh7x
└─Workers
└─MachineDeployment/nkpmgmt-md-0-6pzld False Warning WaitingForAvailableMachines 10s Minimum availability requires 4 replicas, current 1 available
├─Machine/nkpmgmt-md-0-6pzld-tfcmp-2jdxs True 56s
│ └─MachineInfrastructure - NutanixMachine/nkpmgmt-md-0-6pzld-tfcmp-2jdxs
├─Machine/nkpmgmt-md-0-6pzld-tfcmp-j686t False Info WaitingForInfrastructure 11s 1 of 2 completed
│ └─MachineInfrastructure - NutanixMachine/nkpmgmt-md-0-6pzld-tfcmp-j686t
├─Machine/nkpmgmt-md-0-6pzld-tfcmp-p59zl False Info WaitingForInfrastructure 11s 1 of 2 completed
│ └─MachineInfrastructure - NutanixMachine/nkpmgmt-md-0-6pzld-tfcmp-p59zl
└─Machine/nkpmgmt-md-0-6pzld-tfcmp-xvmgx False Info WaitingForInfrastructure 11s 1 of 2 completed
└─MachineInfrastructure - NutanixMachine/nkpmgmt-md-0-6pzld-tfcmp-xvmgx
ここまでは、Cluster APIリソースはbootstrapクラスタの上にあるのですが、管理クラスタが立ち上がった後はそれらが管理クラスタ上に移動され、bootstrapクラスタは削除されます。つまり管理クラスタが自分自身もCluster APIで管理するということ。
✓ Initializing new CAPI components
✓ Initializing new CAPI components
✓ Creating ClusterClass resources
✓ Moving cluster resources
You can now view resources in the moved cluster by using the --kubeconfig flag with kubectl.
For example: kubectl --kubeconfig="/home/ubuntu/nkp/nkpmgmt.conf" get nodes
✓ Deleting bootstrap cluster
Cluster default/nkpmgmt kubeconfig was written to to the filesystem.
You can now view resources in the new cluster by using the --kubeconfig flag with kubectl.
For example: kubectl --kubeconfig="/home/ubuntu/nkp/nkpmgmt.conf" get nodes
その後、Git OperatorやGatekeeperなど、NKPの管理系のサービスがデプロイされます。
最後にダッシュボードのアクセス情報を得るためのコマンドが表示されて終了です。
Cluster was created successfully! Get the dashboard details with:
nkp get dashboard --kubeconfig="/home/ubuntu/nkp/nkpmgmt.conf"
所要時間はネットワーク(コンテナイメージのPull)に依存しますが、だいたい10分ぐらいかな?
ワークロードクラスタのデプロイ
管理クラスタのデプロイ直後にダッシュボードにアクセスするとこういう状態です。
クラスタがひとつだけ。Kommander Hostというクラスタに Management
というバッジがついています。このクラスタが管理クラスタということです。このダッシュボード自体も管理クラスタの上で動いています。
管理クラスタも普通のKubernetesクラスタなので、ユーザーワークロードをデプロイして動かすことももちろんできるのですが、今回は専任マネージャーとして働いてもらいます。
ここから先は nkp
コマンドを使う必要はないので、このダッシュボードのGUIで操作していきます。
初期状態では、NKP Starterというライセンスが入っています。これはNCI Pro以上では無料で使えるライセンスです。
今回はNKP Ultimateを使用するので、Remove License
でStarterのライセンスをいったん削除してからUltimateのライセンスキーを入れます。
Workspaceの作成
次にWorkspaceを作成します。Workspaceというのは、Kubernetesクラスタが所属する「組織」のようなものです。それぞれのWorkspaceに所属するクラスタ間で、展開するアプリケーションやRBACの同期などが行えます。また、KubeCostによりWorkspaceごとのコスト利用状況を可視化することもできます。
管理クラスタの中では、Workspaceはそれぞれに所属するクラスタのCluster APIリソースを格納するNamespaceとして存在します。
この画面右上の Create Workspace
を押して名前を決めるだけです。ここでは aidemo
というWorkspaceを作成しました。
Infrastructure Providerの登録
次にこのWorkspace(組織)が使用できるInfrastructure Providerを登録します。
左上のWorkspace Selectorで先ほど作った aidemo
を選び、+ Add infrastructure
を押します。
Nutanix(NCI)をInfrastructure Providerとして利用する場合は、Prism Centralの情報を入れます。
AWSを利用する場合は、適切な権限を設定したService Accountと紐づいたAccess KeyとSecret Keyを登録することにより、Cluster APIを使用してEKSクラスタをデプロイすることができます。AzureだとAKSクラスタ、vSphereやVCDの場合はノードの仮想マシンを展開してKubernetesクラスタとして構成します。
ワークロードクラスタのデプロイ
aidemo
Workspaceで右上の + Add Cluster
を押します。
ここでCreate Cluster
を選ぶと、先ほど登録したInfrastructure Providerを利用して、GUI上でパラメーターを入力してクラスタを作成します。
Upload YAML to Create Cluster
は、あらかじめ作っておいたCluster APIリソースのYAMLを適用するやりかたです。つまり管理クラスタに対してkubectl apply
をするのと同じです。
Attach Cluster
は、既存のKubernetesクラスタのkubeconfigを与えることによって管理下に置くやりかたです。
ここではCreate Cluster
を選択します。
入力が必要な情報は、管理クラスタをTUIからデプロイしたときとほぼ同じですが、こちらはNode Poolのサイズなどより細かく設定できるようになっています。
以下、見ての通りです。
Nutanix Infrastructure Providerの場合は、クラスタのデプロイはそれほど時間がかかりません。
今回は、同じaidemo
というWorkspaceの中に、DifyやMilvusを動かすためのaidemo
というクラスタと、Nutanix Enterprise AI(NAI)を動かすためのnai
というクラスタを作りました。
ちなみに管理クラスタのkubectlで見るとこのようになっています。
ubuntu@jyoshise-work:~/nkp$ kubectl -n aidemo-zj7fp-tt75j get cluster
NAME CLUSTERCLASS PHASE AGE VERSION
aidemo nkp-nutanix Provisioned 5d2h v1.30.5
nai nkp-nutanix Provisioned 4d22h v1.30.5
ubuntu@jyoshise-work:~/nkp$ kubectl -n aidemo-zj7fp-tt75j get machine
NAME CLUSTER NODENAME PROVIDERID PHASE AGE VERSION
aidemo-5cd6r-8sg99 aidemo aidemo-5cd6r-8sg99 nutanix://b4ff3656-626f-4ac0-929a-bfa3258ba8ff Running 5d2h v1.30.5
aidemo-5cd6r-ghzlm aidemo aidemo-5cd6r-ghzlm nutanix://a2a08142-d967-43be-9857-e9e42e291caa Running 5d2h v1.30.5
aidemo-5cd6r-nq92l aidemo aidemo-5cd6r-nq92l nutanix://010ed0bf-6a6b-406b-8ec9-6b9e70f44aed Running 5d2h v1.30.5
aidemo-md-0-4svhx-qcjw8-4qjsr aidemo aidemo-md-0-4svhx-qcjw8-4qjsr nutanix://e4e165bc-4fbc-4558-b1ff-1ac2b9dea921 Running 5d2h v1.30.5
aidemo-md-0-4svhx-qcjw8-jv6rd aidemo aidemo-md-0-4svhx-qcjw8-jv6rd nutanix://1a3e0742-8b72-4f97-b4de-1b7a59fb9011 Running 5d2h v1.30.5
aidemo-md-0-4svhx-qcjw8-vspbv aidemo aidemo-md-0-4svhx-qcjw8-vspbv nutanix://01b2c885-bb38-4efd-89ae-fd1083994cb9 Running 5d2h v1.30.5
nai-6xvc7-5d499 nai nai-6xvc7-5d499 nutanix://e2696507-0c69-4fba-b6fb-48b83390dcc9 Running 4d22h v1.30.5
nai-6xvc7-btd2l nai nai-6xvc7-btd2l nutanix://fe19bddf-0390-4088-b081-cdcd786cfa50 Running 4d22h v1.30.5
nai-6xvc7-x8dwj nai nai-6xvc7-x8dwj nutanix://cad9e81b-e441-43d9-b4d1-024475921c83 Running 4d22h v1.30.5
nai-md-0-8l9bb-6mpqz-fqlkf nai nutanix://5959c692-0bf1-4b3b-9a04-c1c9d1165b8b Provisioned 18s v1.30.5
nai-md-0-8l9bb-fczz4-4ggqj nai nai-md-0-8l9bb-fczz4-4ggqj nutanix://1e6ce21c-dee1-488e-bfc4-597c6bd270da Running 4d22h v1.30.5
nai-md-0-8l9bb-fczz4-cwhm5 nai nai-md-0-8l9bb-fczz4-cwhm5 nutanix://98243c4c-fe21-44cc-8af1-20af8665cc34 Running 4d22h v1.30.5
nai-md-0-8l9bb-fczz4-lt6qz nai nai-md-0-8l9bb-fczz4-lt6qz nutanix://8d1c6b20-19bc-4724-9188-277dd5a03a7b Running 4d22h v1.30.5
nai-md-0-8l9bb-fczz4-wtjsk nai nai-md-0-8l9bb-fczz4-wtjsk nutanix://c24eb904-ba4b-4f60-8686-a2d5c2733dd5 Running 4d22h v1.30.5
nai-md-1-n8dqp-4df5f-4kbd7-g5mm9 nai nai-md-1-n8dqp-4df5f-4kbd7-g5mm9 nutanix://d68f8014-966c-477d-b4e4-f478617058df Running 3d6h v1.30.5
nai-md-1-n8dqp-4df5f-4kbd7-llqgk nai nai-md-1-n8dqp-4df5f-4kbd7-llqgk nutanix://d31c877b-5f9a-4dcc-9fde-a3eaff1f404d Running 3d6h v1.30.5
②Dify編につづく。