Set up Controller Environments

This guide helps you set up a local Kubernetes environment for testing OCM controller-based deployments. You’ll install the OCM Controllers, kro, and Flux to enable GitOps workflows with OCM component versions.

You’ll end up with

  • A local or remote Kubernetes cluster with OCM Controllers, kro, and Flux installed

Estimated time

~15 minutes

Prerequisites

Setup Workflow

  1. Create a Local Kubernetes Cluster

    πŸ“£ Note: πŸ“£
    Skip this step if you’re using a remote Kubernetes cluster.

    Create a local kind cluster:

    kind create cluster
    You should see this output
    Creating cluster "kind" ...
     βœ“ Ensuring node image (kindest/node:v1.35.0) πŸ–Ό
     βœ“ Preparing nodes πŸ“¦
     βœ“ Writing configuration πŸ“œ
     βœ“ Starting control-plane πŸ•ΉοΈ
     βœ“ Installing CNI 
     βœ“ Installing StorageClass πŸ’Ύ
    Set kubectl context to "kind-kind"
    You can now use your cluster with:
    
    kubectl cluster-info --context kind-kind
    Have a nice day! πŸ‘‹

    Verify the cluster is running:

    kubectl cluster-info
    You should see this output
    Kubernetes control plane is running at https://127.0.0.1:53348
    CoreDNS is running at https://127.0.0.1:53348/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'
  2. Install kro

    Install kro following the official installation guide. The easiest way is via Helm:

    helm install kro oci://registry.k8s.io/kro/charts/kro \
      --namespace kro-system \
      --create-namespace
    You should see this output
    Pulled: registry.k8s.io/kro/charts/kro:0.8.5
    Digest: sha256:c9a9dc0133f43a25711f4bdbce1eeb4b6448015958f901c6fad61a049e54415e
    NAME: kro
    LAST DEPLOYED: Wed Feb 25 12:02:15 2026
    NAMESPACE: kro-system
    STATUS: deployed
    REVISION: 1
    DESCRIPTION: Install complete
    TEST SUITE: None

    Verify kro is running:

    kubectl get pods -n kro-system
    You should see this output
    NAME                   READY   STATUS    RESTARTS   AGE
    kro-5644d5759f-82nsx   1/1     Running   0          2m22s
  3. Install a Deployer: Flux

    We use Flux as deployer. In theory, you could use any other deployer that is able to apply a deployable resource to a Kubernetes cluster, for instance Argo CD.

    Install the controllers using the Flux CLI:

    flux install
    You should see this output
    ✚ generating manifests
    βœ” manifests build completed
    β–Ί installing components in flux-system namespace
    CustomResourceDefinition/alerts.notification.toolkit.fluxcd.io created
    CustomResourceDefinition/buckets.source.toolkit.fluxcd.io created
    CustomResourceDefinition/externalartifacts.source.toolkit.fluxcd.io created
    CustomResourceDefinition/gitrepositories.source.toolkit.fluxcd.io created
    CustomResourceDefinition/helmcharts.source.toolkit.fluxcd.io created
    CustomResourceDefinition/helmreleases.helm.toolkit.fluxcd.io created
    CustomResourceDefinition/helmrepositories.source.toolkit.fluxcd.io created
    CustomResourceDefinition/kustomizations.kustomize.toolkit.fluxcd.io created
    CustomResourceDefinition/ocirepositories.source.toolkit.fluxcd.io created
    CustomResourceDefinition/providers.notification.toolkit.fluxcd.io created
    CustomResourceDefinition/receivers.notification.toolkit.fluxcd.io created
    Namespace/flux-system created
    ClusterRole/crd-controller-flux-system created
    ClusterRole/flux-edit-flux-system created
    ClusterRole/flux-view-flux-system created
    ClusterRoleBinding/cluster-reconciler-flux-system created
    ClusterRoleBinding/crd-controller-flux-system created
    ResourceQuota/flux-system/critical-pods-flux-system created
    ServiceAccount/flux-system/helm-controller created
    ServiceAccount/flux-system/kustomize-controller created
    ServiceAccount/flux-system/notification-controller created
    ServiceAccount/flux-system/source-controller created
    Service/flux-system/notification-controller created
    Service/flux-system/source-controller created
    Service/flux-system/webhook-receiver created
    Deployment/flux-system/helm-controller created
    Deployment/flux-system/kustomize-controller created
    Deployment/flux-system/notification-controller created
    Deployment/flux-system/source-controller created
    NetworkPolicy/flux-system/allow-egress created
    NetworkPolicy/flux-system/allow-scraping created
    NetworkPolicy/flux-system/allow-webhooks created
    β—Ž verifying installation
    βœ” helm-controller: deployment ready
    βœ” kustomize-controller: deployment ready
    βœ” notification-controller: deployment ready
    βœ” source-controller: deployment ready
    βœ” install finished

    Verify Flux is running:

    kubectl get pods -n flux-system
    You should see this output
    NAME                                         READY   STATUS      RESTARTS        AGE
    helm-controller-b6767d66-zbwws               1/1     Running     0               3h29m
    kustomize-controller-57c7ff5596-v6fvr        1/1     Running     0               3h29m
    notification-controller-58ffd586f7-pr65t     1/1     Running     0               3h29m
    source-controller-6ff87cb475-2h2lv           1/1     Running     0               3h29m
  4. Install the OCM Controllers

    Use Helm to install the OCM controllers:

    helm install ocm-k8s-toolkit "oci://ghcr.io/open-component-model/kubernetes/controller/chart:<pre-release>" \
      --namespace ocm-k8s-toolkit-system \
      --create-namespace

    You can check out this list to pick the latest pre-release version until an official release was published.

    You should see this output
    Pulled: ghcr.io/open-component-model/kubernetes/controller/chart:0.0.0-66b9926
    Digest: sha256:cfa13f5c98fc41c3d318471241e431479d2f35c492431c82e76b14dc6dcfcd9a
    NAME: ocm-k8s-toolkit
    LAST DEPLOYED: Mon Mar  9 11:59:18 2026
    NAMESPACE: ocm-k8s-toolkit-system
    STATUS: deployed
    REVISION: 1
    DESCRIPTION: Install complete
    TEST SUITE: None

    Verify the OCM controller is running:

    kubectl get pods -n ocm-k8s-toolkit-system
    You should see this output
    NAME                                                  READY   STATUS    RESTARTS   AGE
    ocm-k8s-toolkit-controller-manager-79b7975755-vxtqt   1/1     Running   0          59s
  5. Verify Complete Setup

    Check all components are running:

    kubectl get pods --all-namespaces | grep -E '(kro-system|flux-system|ocm-k8s-toolkit-system)'
    You should see this output
    NAMESPACE                NAME                                                 READY    STATUS             RESTARTS        AGE
    flux-system              helm-controller-b6767d66-zbwws                        1/1     Running            0               3h39m
    flux-system              kustomize-controller-57c7ff5596-v6fvr                 1/1     Running            0               3h39m
    flux-system              notification-controller-58ffd586f7-pr65t              1/1     Running            0               3h39m
    flux-system              source-controller-6ff87cb475-2h2lv                    1/1     Running            0               3h39m
    kro-system               kro-86d5b5b5bd-6gmvr                                  1/1     Running            0               3h38m
    ocm-k8s-toolkit-system   ocm-k8s-toolkit-controller-manager-788f58d4bd-ntbx8   1/1     Running            0               57s

Registry Access

The OCM Controllers need access to an OCI registry to fetch component versions.

Tip

We recommend using a publicly accessible registry like ghcr.io. Using a local registry requires additional configuration to ensure it’s accessible both from your CLI and from within the cluster.

For private registries, you’ll need to configure credentials. See Configure Credentials for Private Registries for details.

Cleanup

To remove the local kind cluster after testing, run:

kind delete cluster
You should see this output
Deleting cluster "kind" ...
Deleted nodes: ["kind-control-plane"]

Next Steps