Install Kubernetes Operators with Nova
Overview
This tutorial shows how to install a Kubernetes Operator through the Nova Control Plane.
The Prometheus Operator is used as an example, but the same pattern can be used for other operators whose manifests and custom resources are supported by Nova.
Operator manifests are standard Kubernetes resources. When those resources are applied to the Nova Control Plane and match a SchedulePolicy, Nova schedules them to an eligible workload cluster.
The examples in this tutorial are for illustrative purposes. In a production environment, customize the SchedulePolicy, operator manifests, CRDs, RBAC, and custom resources for your own workload clusters and application requirements.
Before You Begin
Before starting, make sure you have:
- A running Nova Control Plane.
- At least one workload cluster registered with Nova.
kubectlconfigured with access to the Nova Control Plane.- A workload cluster label you can use in a
SchedulePolicy. curlandjqavailable locally if you use the example commands.- The
add_labels.shhelper script, or another way to add labels to downloaded manifests.
This tutorial uses the following contexts:
${NOVA_CONTROLPLANE_CONTEXT}for the Nova Control Plane.${K8S_CLUSTER_CONTEXT_1}for the workload cluster where the operator is expected to run.
How It Works
In this workflow:
- Create a
SchedulePolicyin the Nova Control Plane. - Label the operator manifests so they match the
SchedulePolicy. - Apply the operator manifests to the Nova Control Plane.
- Nova places the operator resources on an eligible workload cluster.
- Apply any required RBAC and custom resources through the Nova Control Plane.
- Verify the operator and custom resources in the selected workload cluster.
Many operators require CRDs to exist before their custom resources can be created. Make sure the operator CRDs are installed through the Nova Control Plane before applying custom resources that depend on them.
Operators often provide cluster-level functionality. If an operator needs to reconcile resources across multiple workload clusters, configure the SchedulePolicy to spread or duplicate the operator resources across those workload clusters.
This is especially important when the operator’s custom resources may be scheduled to different workload clusters. The operator should be running in each workload cluster where it is expected to manage those resources.
Step 1: Define a SchedulePolicy
Create a SchedulePolicy that selects the operator resources and places them on an eligible workload cluster.
Apply the following SchedulePolicy to the Nova Control Plane:
kubectl apply --context=${NOVA_CONTROLPLANE_CONTEXT} -f - <<'EOF'
apiVersion: policy.elotl.co/v1alpha1
kind: SchedulePolicy
metadata:
name: prometheus-operator-policy
spec:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
clusterSelector:
matchLabels:
kubernetes.io/metadata.name: wlc-1
resourceSelectors:
labelSelectors:
- matchLabels:
nova.elotl.co/policy: prometheus-operator-policy
EOF
Step 2: Prepare the operator manifests
This tutorial uses the Prometheus Operator bundle from the official Prometheus Operator project.
The bundle must be labeled so the resources match the SchedulePolicy resourceSelector.
This tutorial uses a helper script to add labels to the upstream Prometheus Operator bundle. You can also add the labels manually or use another manifest processing tool, such as Kustomize.
Download the helper script and make it executable:
curl -sL https://raw.githubusercontent.com/elotl/try-nova/refs/heads/main/add_labels.sh -o add_labels.sh
chmod +x add_labels.sh
Step 3: Install the Prometheus Operator through the Nova Control Plane
Download the latest Prometheus Operator bundle, add the Nova policy label, and apply it to the Nova Control Plane:
LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name)
curl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | \
./add_labels.sh -l nova.elotl.co/policy=prometheus-operator-policy | \
kubectl apply --context=${NOVA_CONTROLPLANE_CONTEXT} -f -
Step 4: Verify the operator is running
First, verify that the operator resources exist in the Nova Control Plane:
kubectl get deploy --context=${NOVA_CONTROLPLANE_CONTEXT}
Then verify that the operator resources were placed on the expected workload cluster:
kubectl get deploy --context=${K8S_CLUSTER_CONTEXT_1}
kubectl get pods --context=${K8S_CLUSTER_CONTEXT_1}
Wait for the Prometheus Operator pods to become ready.
Step 5: Create RBAC for Prometheus
Next, create the RBAC resources required by the Prometheus custom resource.
Apply the RBAC resources to the Nova Control Plane:
kubectl apply --context=${NOVA_CONTROLPLANE_CONTEXT} -f - <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
nova.elotl.co/policy: prometheus-operator-policy
name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
nova.elotl.co/policy: prometheus-operator-policy
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/metrics
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
nova.elotl.co/policy: prometheus-operator-policy
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: default
EOF
Step 6: Deploy Prometheus
After the operator and RBAC resources are available, create a Prometheus custom resource.
Apply the following Prometheus custom resource to the Nova Control Plane:
kubectl apply --context=${NOVA_CONTROLPLANE_CONTEXT} -f - <<'EOF'
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
nova.elotl.co/policy: prometheus-operator-policy
name: prometheus
spec:
serviceAccountName: prometheus
serviceMonitorSelector:
matchLabels:
team: frontend
resources:
requests:
memory: 400Mi
enableAdminAPI: false
EOF
Step 7: Verify Prometheus
Verify that the Prometheus custom resource exists in the Nova Control Plane:
kubectl get prometheus --context=${NOVA_CONTROLPLANE_CONTEXT}
Then verify that the Prometheus resources are running in the selected workload cluster:
kubectl get pods --context=${K8S_CLUSTER_CONTEXT_1}
The Prometheus Operator and Prometheus custom resource should now be running in the selected workload cluster.
Cleanup
To remove the example resources, delete them from the Nova Control Plane:
kubectl delete prometheus prometheus --context=${NOVA_CONTROLPLANE_CONTEXT}
kubectl delete clusterrolebinding prometheus --context=${NOVA_CONTROLPLANE_CONTEXT}
kubectl delete clusterrole prometheus --context=${NOVA_CONTROLPLANE_CONTEXT}
kubectl delete serviceaccount prometheus --context=${NOVA_CONTROLPLANE_CONTEXT}
kubectl delete schedulepolicy prometheus-operator-policy --context=${NOVA_CONTROLPLANE_CONTEXT}
If you want to remove the Prometheus Operator resources, delete the same labeled bundle resources from the Nova Control Plane using the manifests or tooling you used to install them.