A significant change for OLM (Operator Lifecycle Manager) v1 is its alignment with the inherent cluster-scoped nature of Custom Resource Definitions (CRDs). While specifics are in development, let's explore the rationale, potential trajectory, and best-practices.
The inherent design of CRDs is cluster-scoped. Having a namespace-scoped operator counteracts this fundamental design, potentially leading to complexities and inconsistencies. The shift towards a cluster-scoped operator model in OLM v1 is, therefore, a step towards better aligning with the essence of CRDs.
To offer a clearer picture of this evolution, take a look at the following visual comparison between the existing namespaced-scope operator and the proposed cluster-scoped operator.
The diagram below provides a side-by-side comparison, capturing the evolution from OLM v0.x to OLM v1.x.
OLM v1 aims for a more streamlined, cluster-wide singleton model, ideally suited for operators built for the “AllNamespace” installation mode.
Even as changes are anticipated, OLM v0.x retains its importance. It is understood that OLM v0.x will continue throughout the life of OpenShift 4, potentially shifting to maintenance mode when OLM v1.0 emerges.
The Operator is a Cluster level object. It will seat at the cluster level. The operator will have a deployment, that seat in the namespace. The operator object seat at the cluster level will manage the namespaces. Proper tenacy for the operator. The admin, The Operator doesn't automatically get The admin tell olm, which have permission Not all tenants will see this Operator. It is configurable. Only certain tents are deamend to see the Operator
The Operator needs to support Multi-tenancy
-
Let's say you have an operator that deploys an application, AppX, and you have instances of this operator in multiple namespaces each deploying its own instance of AppX. This approach needs to be altered. In the cluster-scoped model, you'll have a single instance of your operator that manages all instances of AppX across all namespaces.
-
When moving from namespace-scoped to cluster-scoped, you must modify the manager setup in
main.go
by removingNamespace: namespace
. -
By default, it manages resources cluster wide.
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Namespace: namespace, // Remove this line
MetricsBindAddress: metricsAddr,
...
})
-
Reconcile object in the namespace where the request is been made.
- In
controllers/memcached_controller.go
, you might have something like:
- In
podList := &corev1.PodList{}
listOpts := []client.ListOption{
client.InNamespace(memcached.Namespace),
client.MatchingLabels(labelsForMemcached(memcached.Name)),
}
if err = r.List(ctx, podList, listOpts...); err != nil {
log.Error(err, "Failed to list pods", "Memcached.Namespace", memcached.Namespace, "Memcached.Name", memcached.Name)
return ctrl.Result{}, err
}
- The operator should expect credentials coming from one or more tenants essentially support multi-tenancy.
- If your operator uses a
Secret
to store credentials, ensure that it reads theSecret
from the namespace of theMemcached
custom resource rather than the operator's namespace.
func (r *DatabaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// Assume secret is in database's namespace
secret := &corev1.Secret{}
if err := r.Get(ctx, client.ObjectKey{Name: "my-secret", Namespace: req.Namespace}, secret); err != nil {
return ctrl.Result{}, err
}
// Use secret...
}
- Instead of harcode the managed application version, include a
version
field in the CRD that specifies which version to deploy. - Let the tenant decides which version of the application to deploy
- If you need to change the schema of your CRD (for example, adding a new optional field), you should create a new version of your CRD (e.g., v1beta2), keeping the old one (e.g., v1beta1) for backward compatibility.
- Continuing with the previous example, your operator should be capable of managing resources created with both v1beta1 and v1beta2 CRDs.
- Suppose you decide to remove the v1beta1 version of the CRD. You should plan to do this only when you're ready to release a new major version of your operator, so users are aware that this is a breaking change.
- If you need to introduce a breaking change to your CRD, use a conversion webhook. This webhook could, for example, automatically convert a v1beta1 object to a v1beta2 object when the user tries to interact with it, preserving backward compatibility.
- Your operator should still work with the least amount of privileges necessary. If it used to need permissions to read a certain ConfigMap in its own namespace, now it needs permissions to read that ConfigMap in any namespace. But it doesn't suddenly need permissions to read all ConfigMaps in all namespaces.
The operator resource is available via CLI
Further details are being formulated, with GA but limited support
- clusterscope operator will be picked up by the new OLM API.
- WATCHNAMESPACE env variable, part of the operatorgroup, does not exist in v1.