content/master/guides/scalable-composition.md
An XRD can expose the Kubernetes
scale subresource
on a composite resource. Exposing the scale subresource enables standard
Kubernetes scaling tools, including kubectl scale, the
Horizontal Pod Autoscaler,
and KEDA, to control the composite resource without knowing
its full schema.
This guide shows how to expose the scale subresource by creating a MyApp
composite resource that wraps a Kubernetes Deployment.
When a user creates a MyApp, Crossplane provisions a Deployment and wires
the replica count between the composite resource and the Deployment. Standard
Kubernetes scaling tools can then drive the replica count without knowing the
full schema of MyApp.
An example MyApp XR looks like this:
apiVersion: example.org/v1alpha1
kind: MyApp
metadata:
name: my-app
spec:
replicas: 1
Behind the scenes, Crossplane:
Deployment (the composed resource) with the requested replica
countDeployment to
status.replicas on the MyAppMyApp as ready when the Deployment is healthyBecause MyApp exposes the scale subresource, you can scale it without
knowing its full schema:
kubectl scale myapp/my-app --replicas=3
The Horizontal Pod Autoscaler and KEDA can also target MyApp directly using
the same scale subresource.
This guide requires:
Install function-patch-and-transform to compose resources and patch
fields between the composite resource and its composed resources:
{{< manifest path="guides/scalable-composition/fn-pat.yaml" >}}
This guide also uses function-auto-ready. This function automatically
marks composed resources as ready when they're healthy:
{{< manifest path="guides/scalable-composition/fn-auto-ready.yaml" >}}
Check that Crossplane installed the functions:
kubectl get pkg
NAME INSTALLED HEALTHY PACKAGE AGE
function.pkg.crossplane.io/function-auto-ready True True xpkg.crossplane.io/crossplane-contrib/function-auto-ready:v0.6.3 2s
function.pkg.crossplane.io/function-patch-and-transform True True xpkg.crossplane.io/crossplane-contrib/function-patch-and-transform:v0.10.3 16s
Configure the scale subresource per version in the XRD's
{{<hover label="xrdscale" line="22">}}subresources{{</hover>}} field.
{{< manifest path="guides/scalable-composition/xrd-scale.yaml" label="xrdscale" >}}
Verify the XRD exists:
kubectl get xrd
NAME ESTABLISHED OFFERED AGE
myapps.example.org True 6s
The scale block has three fields:
spec that holds the
desired replica count. This field must exist in the XRD schema.status that holds the
observed replica count. This field must exist in the XRD schema.string field in status that holds a serialized
label selector. Required by the Horizontal Pod Autoscaler.{{<hint "important">}}
Crossplane propagates the scale configuration to the generated CRD.
The composition author must implement the scaling logic, for example
by patching spec.replicas from the composite resource into a
composed Deployment.
{{</hint>}}
After enabling the scale subresource on the XRD, wire the replica count into
the composed resources in the Composition. The following example uses
function-patch-and-transform to forward spec.replicas from the composite
resource to a Deployment:
{{< manifest path="guides/scalable-composition/composition-scale.yaml" >}}
Verify the composition exists:
kubectl get compositions
NAME XR-KIND XR-APIVERSION AGE
myapp MyApp example.org/v1alpha1 3s
The composition must also write back the current replica count to
status.replicas (and status.labelSelector if used) so that autoscalers and
kubectl scale --current-replicas read the correct replica count.
MyApp composite resourceWith the XRD and Composition in place, create a MyApp composite resource:
apiVersion: example.org/v1alpha1
kind: MyApp
metadata:
name: my-app
spec:
replicas: 1
Verify the current replica count:
kubectl get myapp/my-app
NAME DESIRED CURRENT SYNCED READY COMPOSITION AGE
my-app 1 1 True True myapp 108s
After applying the XRD and Composition, scale a composite resource with
kubectl scale:
kubectl scale myapp/my-app --replicas=3
Verify the current replica count:
kubectl get myapp/my-app
NAME DESIRED CURRENT SYNCED READY COMPOSITION AGE
my-app 3 3 True True myapp 3m26s