# ServingStack

Source: /reference/servingstacks/

A ServingStack installs the serving substrate on a Kubernetes cluster: LeaderWorkerSet (Standard) or Grove and the KAI Scheduler (Dynamo), plus Gateway API, cert-manager, and Prometheus.

Apply instances as `apiVersion: infrastructure.modelplane.ai/v1alpha1`, `kind: ServingStack`.

## Example

```yaml
apiVersion: infrastructure.modelplane.ai/v1alpha1
kind: ServingStack
metadata:
  name: west-gke-stack
  namespace: platform
spec:
  cloud: GKE
  secrets:
    - type: Kubeconfig
      name: west-gke-kubeconfig
      key: kubeconfig
    - type: GoogleApplicationCredentials
      name: west-gke-sa-key
      key: private_key
  gateway:
    listeners:
      - name: http
        port: 80
        protocol: HTTP
```

## Definition

The CompositeResourceDefinition this reference is generated from, with the complete OpenAPI schema, validation rules, and defaults:

```yaml
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
  name: servingstacks.infrastructure.modelplane.ai
spec:
  group: infrastructure.modelplane.ai
  defaultCompositionRef:
    name: servingstacks.infrastructure.modelplane.ai
  names:
    categories:
    - crossplane
    - modelplane
    kind: ServingStack
    plural: servingstacks
    shortNames:
    - ss
  scope: Namespaced
  versions:
  - name: v1alpha1
    referenceable: true
    additionalPrinterColumns:
    - name: GATEWAY
      type: string
      jsonPath: .status.gateway.address
    schema:
      openAPIV3Schema:
        description: >-
          A ServingStack installs the serving substrate on a Kubernetes cluster:
          LeaderWorkerSet (Standard) or Grove and the KAI Scheduler (Dynamo),
          plus Gateway API, cert-manager, and Prometheus.
        properties:
          spec:
            description: ServingStackSpec defines the desired state of ServingStack.
            required:
            - cloud
            - secrets
            # A ServingStack is machine-generated, but the API server still
            # serves and accepts it, so this lets the compose function trust
            # that a Kubeconfig secret is present rather than checking in code.
            # The kubeconfig provides the cluster endpoint and CA cert every
            # ProviderConfig needs; a cloud-specific credential secret is
            # optional and only layers identity-based auth on top.
            x-kubernetes-validations:
            - rule: "self.secrets.exists(s, s.type == 'Kubeconfig')"
              message: spec.secrets must include a Kubeconfig entry.
            properties:
              cloud:
                type: string
                description: >-
                  The cloud the target cluster runs on. Selects the fixed set
                  of components and versions this stack installs there, which
                  is resolved per cloud at build time and changes only with a
                  Modelplane release. Mirrors
                  InferenceCluster.spec.cluster.source; the cluster
                  composition sets it.
                enum:
                - GKE
                - EKS
                - AKS
                - Nebius
                - Vultr
                - Existing
              secrets:
                type: array
                description: >-
                  Secrets used to authenticate to the target cluster. Typically
                  sourced from a GKECluster's status.secrets. Secrets are in
                  the same namespace as this ServingStack unless an entry says
                  otherwise. A Kubeconfig secret is required. If a cloud
                  identity secret is present, the serving stack authenticates
                  as that identity instead of relying on the kubeconfig's
                  embedded credentials.
                minItems: 1
                maxItems: 8
                items:
                  type: object
                  required:
                  - type
                  - name
                  - key
                  properties:
                    type:
                      type: string
                      description: >-
                        The type of credential this secret contains. Kubeconfig
                        is required. Any other value is a cloud identity type;
                        when present, the serving stack authenticates to the
                        cluster as that identity instead of using the
                        kubeconfig's embedded credentials.
                      enum:
                      - Kubeconfig
                      - GoogleApplicationCredentials
                      - AWSWebIdentityCredentials
                      - NebiusServiceAccountCredentials
                    name:
                      type: string
                      description: Name of the Secret.
                      maxLength: 253
                    key:
                      type: string
                      description: Key within the Secret that holds the credential data.
                      maxLength: 253
                    namespace:
                      type: string
                      description: >-
                        Namespace of the Secret, when it isn't this
                        ServingStack's namespace. Set on cloud identity
                        entries whose credential is the Secret the cloud
                        provider's ProviderConfig references.
                      maxLength: 253
              stack:
                type: string
                default: Standard
                description: >-
                  Which serving stack this installs. Standard (the default) is
                  the Modelplane-composed serving layer: a Deployment or
                  LeaderWorkerSet, Gateway API, and the endpoint picker. Dynamo
                  swaps in NVIDIA's components: Grove with the KAI Scheduler for
                  multi-node gang scheduling, and a shared ModelExpress server
                  for weight distribution. Propagated from the InferenceCluster.
                enum:
                - Standard
                - Dynamo
              gateway:
                type: object
                description: >-
                  Configuration for the cluster's inference traffic gateway.
                properties:
                  className:
                    type: string
                    default: envoy
                    description: >-
                      GatewayClass name. Override if the cluster already has a
                      GatewayClass named envoy.
                    minLength: 1
                    maxLength: 63
                  listeners:
                    type: array
                    description: >-
                      Gateway listeners. Defaults to a single HTTP listener on
                      port 80 if not specified.
                    maxItems: 8
                    x-kubernetes-list-type: map
                    x-kubernetes-list-map-keys:
                    - name
                    items:
                      type: object
                      required:
                      - name
                      - port
                      - protocol
                      properties:
                        name:
                          type: string
                          description: Unique listener name.
                          maxLength: 63
                          minLength: 1
                        port:
                          type: integer
                          description: Port number for this listener.
                          minimum: 1
                          maximum: 65535
                        protocol:
                          type: string
                          description: Protocol for this listener.
                          enum:
                          - HTTP
                          - TCP
            type: object
          status:
            description: ServingStackStatus defines the observed state of ServingStack.
            properties:
              gateway:
                type: object
                description: Status of the cluster's inference gateway.
                properties:
                  address:
                    type: string
                    maxLength: 256
                    description: >-
                      The gateway's external address, once assigned by the
                      cloud load balancer.
            type: object
        required:
        - spec
        type: object
    served: true
```
