Installation
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.
You can run your Modelplane control plane anywhere. This tour uses kind for illustration.
Make sure your container engine is configured to allow higher resource allocations.
Update your Docker memory limit to 8 GB. For more information, review the Docker documentation.
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}" \
--set-json 'provider.defaultActivations=[]' \
--waitApply the bootstrap resources. They grant Crossplane the permissions it needs to manage your cluster:
kubectl apply -f /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: ["*"]
# Usages, which order teardown between composed resources. Everything else
# Modelplane composes lands on a workload cluster inside a provider-kubernetes
# Object or a provider-helm Release, so it needs no permission here: the
# providers carry their own, and reach the cluster with its kubeconfig.
- 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, Grove, 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
---
# Stop provider-kubernetes copying Secret data into Object status.
#
# It writes an observed object's whole manifest to status.atProvider.manifest,
# so for an Object whose manifest is a Secret, that Secret's data is readable by
# anyone who can get objects, which is a wider audience than can get secrets.
# Modelplane composes Secrets holding caller API keys and serving certificate
# private keys, so this redacts them.
#
# Redaction applies to a copy used only for status. Drift detection still reads
# the unredacted object, so this doesn't cause an Object to be perpetually out
# of date.
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: provider-kubernetes-modelplane
spec:
deploymentTemplate:
spec:
selector: {}
template:
spec:
containers:
- name: package-runtime
args:
- --sanitize-secrets
---
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
name: provider-kubernetes-modelplane
spec:
matchImages:
- type: Prefix
prefix: xpkg.upbound.io/upbound/provider-kubernetes
runtime:
configRef:
name: provider-kubernetes-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.3.1
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.