OLM Integration Bundle Tutorial

    This document succinctly walks through getting an Operator OLM-ready with bundles, and glosses over explanations of certain steps for brevity. The following documents contain more detail on these steps:

    • All operator-framework manifest commands supported by the SDK: .
    • Generating operator-framework manifests: generation overview.

    If you are working with package manifests, see the once you have completed the Setup section below.

    Important: this guide assumes your project was scaffolded with . These features are unavailable to projects of version 2 or less; this information can be found by inspecting your PROJECT file’s version value.

    Let’s first walk through creating an Operator for memcached, a distributed key-value store.

    Follow one of the user guides to develop the memcached-operator in either Go, , or Helm, depending on which Operator type you are interested in. This guide assumes memcached-operator is on version 0.0.1, which is set in the Makefile variable VERSION.

    Ensure OLM is enabled on your cluster before following this guide. has several subcommands that can install, uninstall, and check the status of particular OLM versions in a cluster.

    Note: Certain cluster types may already have OLM enabled, but under a non-default ("olm") namespace, which can be configured by setting --olm-namespace=[non-default-olm-namespace] for operator-sdk olm status|uninstall subcommands.

    You can check if OLM is already installed by running the following command, which will detect the installed OLM version automatically (0.15.1 in this example):

    All resources listed should have status Installed.

    If OLM is not already installed, go ahead and install the latest version:

    1. $ operator-sdk olm install
    2. INFO[0000] Fetching CRDs for version "latest"
    3. INFO[0001] Fetching resources for version "latest"
    4. INFO[0007] Creating CRDs and resources
    5. INFO[0007] Creating CustomResourceDefinition "clusterserviceversions.operators.coreos.com"
    6. INFO[0007] Creating CustomResourceDefinition "installplans.operators.coreos.com"
    7. INFO[0007] Creating CustomResourceDefinition "subscriptions.operators.coreos.com"
    8. ...
    9. NAME NAMESPACE KIND STATUS
    10. clusterserviceversions.operators.coreos.com CustomResourceDefinition Installed
    11. installplans.operators.coreos.com CustomResourceDefinition Installed
    12. subscriptions.operators.coreos.com CustomResourceDefinition Installed
    13. catalogsources.operators.coreos.com CustomResourceDefinition Installed
    14. ...

    If working with package manifests, see the package manifests tutorial.

    We will now create bundle manifests by running make bundle in the root of the memcached-operator project.

    1. $ make bundle
    2. /home/user/go/bin/controller-gen "crd:trivialVersions=true" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
    3. operator-sdk generate kustomize manifests -q
    4. kustomize build config/manifests | operator-sdk generate bundle -q --overwrite --version 0.0.1
    5. INFO[0000] Building annotations.yaml
    6. INFO[0000] Writing annotations.yaml in /home/user/go/src/github.com/test-org/memcached-operator/bundle/metadata
    7. operator-sdk bundle validate ./bundle
    8. INFO[0000] Found annotations file bundle-dir=bundle container-tool=docker
    9. INFO[0000] Could not find optional dependencies file bundle-dir=bundle container-tool=docker
    10. INFO[0000] All validation tests have completed successfully

    The above command will have created the following bundle artifacts: a manifests directory (bundle/manifests) containing a CSV and all CRDs from config/crds, directory (bundle/metadata), and bundle.Dockerfile have been created in the Operator project. These files have been statically validated by operator-sdk bundle validate to ensure the on-disk bundle representation is correct.

    At this point in development we’ve generated all files necessary to build the memcached-operator bundle. Now we’re ready to test and deploy the Operator with OLM.

    Note: If testing a bundle whose image will be hosted in a registry that is private and/or has a custom CA, these must be complete.

    Before proceeding, make sure you’ve Installed OLM onto your cluster.

    First, we need to build our bundle. To build a memcached-operator bundle, run:

    1. $ make bundle-build bundle-push BUNDLE_IMG=<some-registry>/memcached-operator-bundle:v0.0.1

    Now that the bundle image is present in a registry, can create a pod to serve that bundle to OLM via a Subscription, along with other OLM objects, ephemerally.

    We can use the operator-sdk run bundle-upgrade command with a newer version of bundle image to upgrade an existing operator bundle deployed on cluster. The command automates the manual orchestration typically required to upgrade an operator from one version to another. It extracts the package name from bundle, finds the existing subscription, updates the catalog source, deletes the existing registry pod and creates a new registry pod with the version of bundle image provided in the command.

    Let’s upgrade the previously deployed memcached-operator bundle from version 0.0.1 to 0.0.2.

    1. $ operator-sdk run bundle-upgrade <some-registry>/memcached-operator-bundle:v0.0.2
    2. INFO[0002] Found existing subscription with name memcached-operator-bundle-0-0-1-sub and namespace default
    3. INFO[0002] Found existing catalog source with name memcached-operator-catalog and namespace default
    4. INFO[0007] Successfully created registry pod: <some-registry>-memcached-operator-bundle-0-0-2
    5. INFO[0007] Updated catalog source memcached-operator-catalog with address and annotations
    6. INFO[0008] Deleted previous registry pod with name "<some-registry>-memcached-operator-bundle-0-0-1"
    7. INFO[0050] Approved InstallPlan install-c8fkh for the Subscription: memcached-operator-bundle-0-0-1-sub
    8. INFO[0050] Waiting for ClusterServiceVersion "default/memcached-operator.v0.0.2" to reach 'Succeeded' phase
    9. INFO[0050] Waiting for ClusterServiceVersion "default/memcached-operator.v0.0.2" to appear
    10. INFO[0052] Found ClusterServiceVersion "default/memcached-operator.v0.0.2" phase: Pending
    11. INFO[0057] Found ClusterServiceVersion "default/memcached-operator.v0.0.2" phase: InstallReady
    12. INFO[0058] Found ClusterServiceVersion "default/memcached-operator.v0.0.2" phase: Installing
    13. INFO[0095] Found ClusterServiceVersion "default/memcached-operator.v0.0.2" phase: Succeeded
    14. INFO[0095] Successfully upgraded to "memcached-operator.v0.0.2"

    Upgrading a bundle that was installed traditionally using OLM

    Let’s see how to deploy an operator bundle traditionally using OLM and then upgrade the operator bundle to a newer version.

    First, create a CatalogSource by building the CatalogSource from a catalog.

    1. $ oc create -f catalogsource.yaml
    1. # catalogsource.yaml
    2. apiVersion: operators.coreos.com/v1alpha1
    3. kind: CatalogSource
    4. metadata:
    5. name: etcdoperator
    6. namespace: default
    7. spec:
    8. displayName: Etcd Operators
    9. sourceType: grpc

    Next, install the operator bundle by creating a subscription.

    1. apiVersion: v1
    2. items:
    3. - apiVersion: operators.coreos.com/v1alpha1
    4. kind: Subscription
    5. metadata:
    6. name: etcd
    7. namespace: default
    8. spec:
    9. channel: "stable"
    10. installPlanApproval: Manual
    11. name: etcd
    12. source: etcdoperator
    13. sourceNamespace: default
    14. startingCSV: etcdoperator.v0.0.1

    Once the Operator bundle is deployed, you can use the run bundle-upgrade command by specifing the new bundle image that you want to upgrade to.

    1. $ operator-sdk run bundle-upgrade <some-registry>/etcd-bundle:v0.0.2
    2. INFO[0000] Found existing subscription with name etcd and namespace default
    3. INFO[0000] Found existing catalog source with name etcdoperator and namespace default
    4. INFO[0005] Successfully created registry pod: <some-registry>-etcd-bundle-0-0-2
    5. INFO[0005] Updated catalog source etcdoperator with address and annotations
    6. INFO[0005] Deleted previous registry pod with name "<some-registry>-etcd-bundle-0-0-1"
    7. INFO[0005] Approved InstallPlan install-6vrzh for the Subscription: etcd
    8. INFO[0005] Waiting for ClusterServiceVersion "default/etcdoperator.v0.0.2" to reach 'Succeeded' phase
    9. INFO[0005] Waiting for ClusterServiceVersion "default/etcdoperator.v0.0.2" to appear
    10. INFO[0007] Found ClusterServiceVersion "default/etcdoperator.v0.0.2" phase: Pending
    11. INFO[0008] Found ClusterServiceVersion "default/etcdoperator.v0.0.2" phase: Installing
    12. INFO[0018] Found ClusterServiceVersion "default/etcdoperator.v0.0.2" phase: Succeeded
    13. INFO[0018] Successfully upgraded to "etcdoperator.v0.0.2"

    OLM and Operator Registry consumes Operator bundles via a catalog of Operators, implemented as an index image, which are composed of one or more bundles. To build and push a memcached-operator bundle image for version v0.0.1, run:

    1. $ make bundle-build bundle-push BUNDLE_IMG=<some-registry>/memcached-operator-bundle:v0.0.1

    Now you can build and push the catalog by running catalog-* Makfile targets, which use the Operator package manager tool to build the catalog:

    Assuming IMAGE_TAG_BASE = <some-registry>/memcached-operator has the desired tag base, you can inline the above two commands to:

    1. $ make bundle-build bundle-push catalog-build catalog-push

    Which will build and push both <some-registry>/memcached-operator-bundle:v0.0.1 and <some-registry>/memcached-operator-catalog:v0.0.1.

    In-depth discussions of OLM concepts mentioned here: