Home > other >  "error": "no kind is registered for the type v1.ServiceMonitor in scheme \"pkg/
"error": "no kind is registered for the type v1.ServiceMonitor in scheme \"pkg/

Time:10-14

I created an operator for my application and want to create a service monitor for it. The Prometheus operator was created. The monitoring prometheus library was imported and the service monitor crd was created in mu k8s cluster. It is the go code for this object :

package controllers

import (
    "context"
    "fmt"

    appsv1alpha1 "k8s-operator/api/v1alpha1"

    monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
    "gopkg.in/yaml.v2"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/types"
    "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    "sigs.k8s.io/controller-runtime/pkg/reconcile"
)

// ensureSvcMonitor ensures SvcMonitor is Running in a namespace.
func (r *MyappReconciler) ensureSvcMonitor(request reconcile.Request,
    instance *appsv1alpha1.Myapp,
    svcmonitor *monitoring.ServiceMonitor,
) (*reconcile.Result, error) {

    // See if SvcMonitor already exists and create if it doesn't
    found := &monitoring.ServiceMonitor{}
    err := r.Get(context.TODO(), types.NamespacedName{
        Name:      svcmonitor.Name,
        Namespace: instance.Namespace,
    }, found)
    if err != nil && errors.IsNotFound(err) {

        // Create the SvcMonitor
        err = r.Create(context.TODO(), svcmonitor)

        if err != nil {
            // SvcMonitor creation failed
            return &reconcile.Result{}, err
        } else {
            // SvcMonitor creation was successful
            return nil, nil
        }
    } else if err != nil {
        // Error that isn't due to the SvcMonitor not existing
        return &reconcile.Result{}, err
    }

    return nil, nil
}

// backendSvcMonitor is a code for creating a SvcMonitor
func (r *MyappReconciler) backendSvcMonitor(v *appsv1alpha1.Myapp) *monitoring.ServiceMonitor {

    svcmonitor := &monitoring.ServiceMonitor{
        TypeMeta: metav1.TypeMeta{
            Kind:       "ServiceMonitor",
            APIVersion: "monitoring.coreos.com/v1",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name:      v.Spec.Name   "-svcmonitor",
            Namespace: v.Namespace},
        Spec: monitoring.ServiceMonitorSpec{
            Endpoints: []monitoring.Endpoint{{
                Port: v.Spec.Name,
            }},
            Selector: metav1.LabelSelector{
                MatchLabels: labels(v),
            },
        },
    }

    controllerutil.SetControllerReference(v, svcmonitor, r.Scheme)
    yamlData, _ := yaml.Marshal(&svcmonitor)
    fmt.Println(string(yamlData))
    return svcmonitor
}

and it is the part which I call these function to create this object in my controller:

if instance.Spec.Servicemonitorenable {
        result, err = r.ensureSvcMonitor(req, instance, r.backendSvcMonitor(instance))
        if result != nil {
            log.Error(err, "Servicemonitor Not ready")
            return *result, err
        }
    }
but when I creat the crd instance I get this error:

"error": "no kind is registered for the type v1.ServiceMonitor in scheme \"pkg/runtime/scheme.go:100\""}

CodePudding user response:

It looks like the crd ServiceMonitor is part of monitoring.coreos.com and not monitoring.coreos.com/v1, so it should be enough to change that (APIVersion) in your code:

package controllers

import (
    "context"
    "fmt"

    appsv1alpha1 "k8s-operator/api/v1alpha1"

    monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
    "gopkg.in/yaml.v2"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/types"
    "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    "sigs.k8s.io/controller-runtime/pkg/reconcile"
)

// ensureSvcMonitor ensures SvcMonitor is Running in a namespace.
func (r *MyappReconciler) ensureSvcMonitor(request reconcile.Request,
    instance *appsv1alpha1.Myapp,
    svcmonitor *monitoring.ServiceMonitor,
) (*reconcile.Result, error) {

    // See if SvcMonitor already exists and create if it doesn't
    found := &monitoring.ServiceMonitor{}
    err := r.Get(context.TODO(), types.NamespacedName{
        Name:      svcmonitor.Name,
        Namespace: instance.Namespace,
    }, found)
    if err != nil && errors.IsNotFound(err) {

        // Create the SvcMonitor
        err = r.Create(context.TODO(), svcmonitor)

        if err != nil {
            // SvcMonitor creation failed
            return &reconcile.Result{}, err
        } else {
            // SvcMonitor creation was successful
            return nil, nil
        }
    } else if err != nil {
        // Error that isn't due to the SvcMonitor not existing
        return &reconcile.Result{}, err
    }

    return nil, nil
}

// backendSvcMonitor is a code for creating a SvcMonitor
func (r *MyappReconciler) backendSvcMonitor(v *appsv1alpha1.Myapp) *monitoring.ServiceMonitor {

    svcmonitor := &monitoring.ServiceMonitor{
        TypeMeta: metav1.TypeMeta{
            Kind:       "ServiceMonitor",
            APIVersion: "monitoring.coreos.com",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name:      v.Spec.Name   "-svcmonitor",
            Namespace: v.Namespace},
        Spec: monitoring.ServiceMonitorSpec{
            Endpoints: []monitoring.Endpoint{{
                Port: v.Spec.Name,
            }},
            Selector: metav1.LabelSelector{
                MatchLabels: labels(v),
            },
        },
    }

    controllerutil.SetControllerReference(v, svcmonitor, r.Scheme)
    yamlData, _ := yaml.Marshal(&svcmonitor)
    fmt.Println(string(yamlData))
    return svcmonitor
}

CodePudding user response:

In your main.go, you need to add monitoring/v1 to the scheme injected into controller-runtime i.e.:

// main.go
package main

import (
    "os"
    ctrl "sigs.k8s.io/controller-runtime"
    monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
    "k8s.io/apimachinery/pkg/runtime"
)

var (
    scheme = runtime.NewScheme()
)

func init() {
    monitoring.AddToScheme(scheme)
}

func main() {
    mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
        Scheme: scheme,
        // ... other options here
    })

    // Start Manager
    if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
        os.Exit(1)
    }
}
  • Related