“错误”: “在方案中未注册类型v1.ServiceMonitor的种类“pkg/runtime/scheme.go:100″。”

huangapple go评论94阅读模式
英文:

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

问题

我为我的应用程序创建了一个操作符,并希望为其创建一个服务监视器。
Prometheus操作符已经创建好了。
我导入了监视Prometheus库,并在我的k8s集群中创建了服务监视器CRD。
以下是这个对象的Go代码:

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
}

这是我在控制器中调用这些函数来创建这个对象的部分:

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
	}
}

但是当我创建自定义资源实例时,我遇到了这个错误:

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

请注意,这是一个错误消息,表明在方案中没有为类型v1.ServiceMonitor注册任何种类。

英文:

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 my k8s cluster.
Here is the Go code for this object:

<!-- language: lang-go -->

package controllers
import (
&quot;context&quot;
&quot;fmt&quot;
appsv1alpha1 &quot;k8s-operator/api/v1alpha1&quot;
monitoring &quot;github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1&quot;
&quot;gopkg.in/yaml.v2&quot;
&quot;k8s.io/apimachinery/pkg/api/errors&quot;
metav1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
&quot;k8s.io/apimachinery/pkg/types&quot;
&quot;sigs.k8s.io/controller-runtime/pkg/controller/controllerutil&quot;
&quot;sigs.k8s.io/controller-runtime/pkg/reconcile&quot;
)
// 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&#39;t
found := &amp;monitoring.ServiceMonitor{}
err := r.Get(context.TODO(), types.NamespacedName{
Name:      svcmonitor.Name,
Namespace: instance.Namespace,
}, found)
if err != nil &amp;&amp; errors.IsNotFound(err) {
// Create the SvcMonitor
err = r.Create(context.TODO(), svcmonitor)
if err != nil {
// SvcMonitor creation failed
return &amp;reconcile.Result{}, err
} else {
// SvcMonitor creation was successful
return nil, nil
}
} else if err != nil {
// Error that isn&#39;t due to the SvcMonitor not existing
return &amp;reconcile.Result{}, err
}
return nil, nil
}
// backendSvcMonitor is a code for creating a SvcMonitor
func (r *MyappReconciler) backendSvcMonitor(v *appsv1alpha1.Myapp) *monitoring.ServiceMonitor {
svcmonitor := &amp;monitoring.ServiceMonitor{
TypeMeta: metav1.TypeMeta{
Kind:       &quot;ServiceMonitor&quot;,
APIVersion: &quot;monitoring.coreos.com/v1&quot;,
},
ObjectMeta: metav1.ObjectMeta{
Name:      v.Spec.Name + &quot;-svcmonitor&quot;,
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(&amp;svcmonitor)
fmt.Println(string(yamlData))
return svcmonitor
}

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

<!-- language: lang-go -->

if instance.Spec.Servicemonitorenable {
result, err = r.ensureSvcMonitor(req, instance, r.backendSvcMonitor(instance))
if result != nil {
log.Error(err, &quot;Servicemonitor Not ready&quot;)
return *result, err
}
}

But when I create the custom resource instance I get this error:

<!-- language: lang-none -->

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

答案1

得分: 1

在你的main.go文件中,你需要将monitoring/v1添加到注入到controller-runtimescheme中,即:

// 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)
	}
}
英文:

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

// main.go
package main

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

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)
	}
}

答案2

得分: 0

看起来 crd ServiceMonitor 是 monitoring.coreos.com 的一部分,而不是 monitoring.coreos.com/v1,所以只需要在代码中更改 APIVersion 就可以了:

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 确保 SvcMonitor 在命名空间中运行。
func (r *MyappReconciler) ensureSvcMonitor(request reconcile.Request,
    instance *appsv1alpha1.Myapp,
    svcmonitor *monitoring.ServiceMonitor,
) (*reconcile.Result, error) {

    // 查看是否已经存在 SvcMonitor,如果不存在则创建
    found := &monitoring.ServiceMonitor{}
    err := r.Get(context.TODO(), types.NamespacedName{
        Name:      svcmonitor.Name,
        Namespace: instance.Namespace,
    }, found)
    if err != nil && errors.IsNotFound(err) {

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

        if err != nil {
            // SvcMonitor 创建失败
            return &reconcile.Result{}, err
        } else {
            // SvcMonitor 创建成功
            return nil, nil
        }
    } else if err != nil {
        // 不是由于 SvcMonitor 不存在而引起的错误
        return &reconcile.Result{}, err
    }

    return nil, nil
}

// backendSvcMonitor 是用于创建 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
}


[1]: https://github.com/prometheus-operator/prometheus-operator/blob/main/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml#L10

以上是翻译好的代码部分。

英文:

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 (
&quot;context&quot;
&quot;fmt&quot;
appsv1alpha1 &quot;k8s-operator/api/v1alpha1&quot;
monitoring &quot;github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1&quot;
&quot;gopkg.in/yaml.v2&quot;
&quot;k8s.io/apimachinery/pkg/api/errors&quot;
metav1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
&quot;k8s.io/apimachinery/pkg/types&quot;
&quot;sigs.k8s.io/controller-runtime/pkg/controller/controllerutil&quot;
&quot;sigs.k8s.io/controller-runtime/pkg/reconcile&quot;
)
// 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&#39;t
found := &amp;monitoring.ServiceMonitor{}
err := r.Get(context.TODO(), types.NamespacedName{
Name:      svcmonitor.Name,
Namespace: instance.Namespace,
}, found)
if err != nil &amp;&amp; errors.IsNotFound(err) {
// Create the SvcMonitor
err = r.Create(context.TODO(), svcmonitor)
if err != nil {
// SvcMonitor creation failed
return &amp;reconcile.Result{}, err
} else {
// SvcMonitor creation was successful
return nil, nil
}
} else if err != nil {
// Error that isn&#39;t due to the SvcMonitor not existing
return &amp;reconcile.Result{}, err
}
return nil, nil
}
// backendSvcMonitor is a code for creating a SvcMonitor
func (r *MyappReconciler) backendSvcMonitor(v *appsv1alpha1.Myapp) *monitoring.ServiceMonitor {
svcmonitor := &amp;monitoring.ServiceMonitor{
TypeMeta: metav1.TypeMeta{
Kind:       &quot;ServiceMonitor&quot;,
APIVersion: &quot;monitoring.coreos.com&quot;,
},
ObjectMeta: metav1.ObjectMeta{
Name:      v.Spec.Name + &quot;-svcmonitor&quot;,
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(&amp;svcmonitor)
fmt.Println(string(yamlData))
return svcmonitor
}

huangapple
  • 本文由 发表于 2022年10月14日 01:40:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/74059769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定