我为我的应用程序创建了一个操作符,并希望为它创建一个服务监视器。Prometheus操作符被创建。在我的k8s集群中导入了监视Prometheus库,并创建了服务监视器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\""}发布于 2022-10-14 03:51:05
在您的main.go中,您需要将monitoring/v1添加到注入controller-runtime的scheme中,即:
// 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)
}
}发布于 2022-10-13 17:56:13
看起来,crd ServiceMonitor是monitoring.coreos.com的一部分,而不是monitoring.coreos.com。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 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
}https://stackoverflow.com/questions/74059769
复制相似问题