Installation
This document applies to Modelplane v0.1 and not to the latest release v0.3.
The control plane is where everything in Modelplane runs. In this step you’ll install it on a local kind cluster, using Crossplane for reconciliation and the Modelplane APIs. No cloud yet, that comes next.
This step takes about five minutes.
Prerequisites
Install kind , kubectl , and Helm on your machine.
Install the control plane
Crossplane provides the reconciliation engine and package management. Create the kind cluster and install it with Helm:
# Pin to kind v0.30.0 default image (containerd 2.1.4)
# kind v0.31+ ships containerd 2.2.0 which breaks Modelplane
kind create cluster --name modelplane \
--image kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5ahelm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update crossplane-stable
helm install crossplane crossplane-stable/crossplane \
--namespace crossplane-system --create-namespace \
--set "args={--enable-dependency-version-upgrades}" \
--waitApply the bootstrap resources. They grant Crossplane the permissions it needs to manage your cluster:
kubectl apply -f https://docs.modelplane.ai/v0.1/examples/getting-started/prerequisites.yaml# Modelplane prerequisites. Apply once after installing Crossplane.
#
# These resources grant Crossplane and provider-helm the permissions
# needed to compose Gateway API, MetalLB, and Service/EndpointSlice
# routing resources. They cannot be self-composed because Crossplane
# needs the permissions before it can compose anything.
---
apiVersion: v1
kind: Namespace
metadata:
name: modelplane-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: crossplane-compose-modelplane
labels:
rbac.crossplane.io/aggregate-to-crossplane: "true"
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["*"]
# Selectorless Service plus EndpointSlice composed by ModelEndpoint to route
# the control plane gateway to a remote model endpoint.
- apiGroups: [""]
resources: ["services"]
verbs: ["*"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["*"]
- apiGroups: ["gateway.networking.k8s.io"]
resources: ["gateways", "gatewayclasses", "httproutes"]
verbs: ["*"]
- apiGroups: ["gateway.envoyproxy.io"]
resources: ["backends"]
verbs: ["*"]
- apiGroups: ["metallb.io"]
resources: ["ipaddresspools", "l2advertisements"]
verbs: ["*"]
- apiGroups: ["protection.crossplane.io"]
resources: ["usages"]
verbs: ["*"]
---
# Give provider-helm a deterministic SA name so we can grant it
# permissions. Without this, the SA name has a random hash.
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: provider-helm-modelplane
spec:
serviceAccountTemplate:
metadata:
name: provider-helm-modelplane
---
# Grant provider-helm cluster-admin. It installs full Helm charts
# (MetalLB, Envoy Gateway, LeaderWorkerSet, etc.) that create arbitrary
# resource types across namespaces.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: provider-helm-modelplane
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: provider-helm-modelplane
namespace: crossplane-system
---
# Apply the DRC to provider-helm automatically via ImageConfig.
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
name: provider-helm-modelplane
spec:
matchImages:
- type: Prefix
prefix: xpkg.upbound.io/upbound/provider-helm
runtime:
configRef:
name: provider-helm-modelplane
Install Modelplane
The Modelplane Configuration adds the Modelplane APIs and the composition functions that reconcile them:
# The Modelplane Crossplane Configuration. Installing it adds the Modelplane
# APIs (InferenceGateway, InferenceClass, InferenceCluster, ModelDeployment,
# ModelCache, ModelService) and the composition functions that reconcile them.
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: modelplane
spec:
package: xpkg.upbound.io/modelplane/modelplane:v0.1.0
Wait until the configuration is healthy:
kubectl wait configuration/modelplane --for=condition=Healthy --timeout=5mNext step
The control plane is running but has nothing to schedule against yet. In the next step, you’ll build the platform to provision a GPU cluster and publish what hardware it offers.