1
0
Fork 0
mirror of https://github.com/prometheus-operator/prometheus-operator.git synced 2025-04-15 16:56:24 +00:00

Add ServiceDiscoveryRole configuration to toggle service discovery via EndpointSlice vs Endpoints (#6672)

* Add service discovery role in Prometheus and Prometheus Agent CRDs



---------

Co-authored-by: haanhvu <haanh6594@gmail.com>
Co-authored-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
Marek Słabicki 2024-07-25 00:15:52 -07:00 committed by GitHub
parent f0a3778b4b
commit 813bc2b6b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 282 additions and 29 deletions

100
Documentation/api.md generated
View file

@ -2794,6 +2794,22 @@ in a breaking way.</p>
</tr>
<tr>
<td>
<code>serviceDiscoveryRole</code><br/>
<em>
<a href="#monitoring.coreos.com/v1.ServiceDiscoveryRole">
ServiceDiscoveryRole
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Defines the service discovery role used to discover targets from <code>ServiceMonitor</code> objects.
If set, the value should be either &ldquo;Endpoints&rdquo; or &ldquo;EndpointSlice&rdquo;.
If unset, the operator assumes the &ldquo;Endpoints&rdquo; role.</p>
</td>
</tr>
<tr>
<td>
<code>baseImage</code><br/>
<em>
string
@ -7468,6 +7484,22 @@ PodMonitors, ServiceMonitors, Probes and ScrapeConfigs.</p>
in a breaking way.</p>
</td>
</tr>
<tr>
<td>
<code>serviceDiscoveryRole</code><br/>
<em>
<a href="#monitoring.coreos.com/v1.ServiceDiscoveryRole">
ServiceDiscoveryRole
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Defines the service discovery role used to discover targets from <code>ServiceMonitor</code> objects.
If set, the value should be either &ldquo;Endpoints&rdquo; or &ldquo;EndpointSlice&rdquo;.
If unset, the operator assumes the &ldquo;Endpoints&rdquo; role.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.Condition">Condition
@ -11644,6 +11676,22 @@ in a breaking way.</p>
</tr>
<tr>
<td>
<code>serviceDiscoveryRole</code><br/>
<em>
<a href="#monitoring.coreos.com/v1.ServiceDiscoveryRole">
ServiceDiscoveryRole
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Defines the service discovery role used to discover targets from <code>ServiceMonitor</code> objects.
If set, the value should be either &ldquo;Endpoints&rdquo; or &ldquo;EndpointSlice&rdquo;.
If unset, the operator assumes the &ldquo;Endpoints&rdquo; role.</p>
</td>
</tr>
<tr>
<td>
<code>baseImage</code><br/>
<em>
string
@ -13892,6 +13940,26 @@ Kubernetes core/v1.ConfigMapKeySelector
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.ServiceDiscoveryRole">ServiceDiscoveryRole
(<code>string</code> alias)</h3>
<p>
(<em>Appears on:</em><a href="#monitoring.coreos.com/v1.CommonPrometheusFields">CommonPrometheusFields</a>)
</p>
<div>
</div>
<table>
<thead>
<tr>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr><td><p>&#34;EndpointSlice&#34;</p></td>
<td></td>
</tr><tr><td><p>&#34;Endpoints&#34;</p></td>
<td></td>
</tr></tbody>
</table>
<h3 id="monitoring.coreos.com/v1.ServiceMonitorSpec">ServiceMonitorSpec
</h3>
<p>
@ -17772,6 +17840,22 @@ PodMonitors, ServiceMonitors, Probes and ScrapeConfigs.</p>
in a breaking way.</p>
</td>
</tr>
<tr>
<td>
<code>serviceDiscoveryRole</code><br/>
<em>
<a href="#monitoring.coreos.com/v1.ServiceDiscoveryRole">
ServiceDiscoveryRole
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Defines the service discovery role used to discover targets from <code>ServiceMonitor</code> objects.
If set, the value should be either &ldquo;Endpoints&rdquo; or &ldquo;EndpointSlice&rdquo;.
If unset, the operator assumes the &ldquo;Endpoints&rdquo; role.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -25016,6 +25100,22 @@ PodMonitors, ServiceMonitors, Probes and ScrapeConfigs.</p>
in a breaking way.</p>
</td>
</tr>
<tr>
<td>
<code>serviceDiscoveryRole</code><br/>
<em>
<a href="#monitoring.coreos.com/v1.ServiceDiscoveryRole">
ServiceDiscoveryRole
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Defines the service discovery role used to discover targets from <code>ServiceMonitor</code> objects.
If set, the value should be either &ldquo;Endpoints&rdquo; or &ldquo;EndpointSlice&rdquo;.
If unset, the operator assumes the &ldquo;Endpoints&rdquo; role.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1alpha1.PuppetDBSDConfig">PuppetDBSDConfig

View file

@ -52,17 +52,17 @@ Further information can also be found in the [Thanos section]({{< ref "thanos.md
The `ServiceMonitor` custom resource definition (CRD) allows to declaratively define how a dynamic set of services should be monitored. Which services are selected to be monitored with the desired configuration is defined using label selections. This allows an organization to introduce conventions around how metrics are exposed, and then following these conventions new services are automatically discovered, without the need to reconfigure the system.
For Prometheus to monitor any application within Kubernetes an `Endpoints` object needs to exist. `Endpoints` objects are essentially lists of IP addresses. Typically an `Endpoints` object is populated by a `Service` object. A `Service` object discovers `Pod`s by a label selector and adds those to the `Endpoints` object.
For Prometheus to monitor any application within Kubernetes, either an `EndpointSlice` object or an `Endpoints` object needs to exist. These objects are essentially lists of IP addresses. Typically an `EndpointSlice` or an `Endpoints` object is populated by a `Service` object. A `Service` object discovers `Pod`s by a label selector and adds those to the `EndpointSlice` or `Endpoints` object.
A `Service` may expose one or more service ports, which are backed by a list of multiple endpoints that point to a `Pod` in the common case. This is reflected in the respective `Endpoints` object as well.
A `Service` may expose one or more service ports, which are backed by a list of multiple endpoints that point to a `Pod` in the common case. This is reflected in the respective `EndpointSlice` or `Endpoints` object as well.
The `ServiceMonitor` object introduced by the Prometheus Operator in turn discovers those `Endpoints` objects and configures Prometheus to monitor those `Pod`s.
The `ServiceMonitor` object introduced by the Prometheus Operator in turn discovers those `EndpointSlice` or `Endpoints` objects and configures Prometheus to monitor those `Pod`s.
The `endpoints` section of the `ServiceMonitorSpec`, is used to configure which ports of these `Endpoints` are going to be scraped for metrics, and with which parameters. For advanced use cases one may want to monitor ports of backing `Pod`s, which are not directly part of the service endpoints. Therefore when specifying an endpoint in the `endpoints` section, they are strictly used.
The `endpoints` section of the `ServiceMonitorSpec`, is used to configure which ports of these `EndpointSlice`s or `Endpoints` are going to be scraped for metrics, and with which parameters. For advanced use cases one may want to monitor ports of backing `Pod`s, which are not directly part of the service endpoints. Therefore when specifying an endpoint in the `endpoints` section, they are strictly used.
> Note: `endpoints` (lowercase) is the field in the `ServiceMonitor` CRD, while `Endpoints` (capitalized) is the Kubernetes object kind.
> Note: `endpoints` (lowercase) is the field in the `ServiceMonitor` CRD, while `EndpointSlice` or `Endpoints` (capitalized) is the Kubernetes object kind.
Both `ServiceMonitors` as well as discovered targets may come from any namespace. This is important to allow cross-namespace monitoring use cases, e.g. for meta-monitoring. Using the `ServiceMonitorNamespaceSelector` of the `PrometheusSpec`, one can restrict the namespaces `ServiceMonitor`s are selected from by the respective Prometheus server. Using the `namespaceSelector` of the `ServiceMonitorSpec`, one can restrict the namespaces the `Endpoints` objects are allowed to be discovered from.
Both `ServiceMonitors` as well as discovered targets may come from any namespace. This is important to allow cross-namespace monitoring use cases, e.g. for meta-monitoring. Using the `ServiceMonitorNamespaceSelector` of the `PrometheusSpec`, one can restrict the namespaces `ServiceMonitor`s are selected from by the respective Prometheus server. Using the `namespaceSelector` of the `ServiceMonitorSpec`, one can restrict the namespaces the `EndpointSlice` or `Endpoints` objects are allowed to be discovered from.
One can discover targets in all namespaces like this:

18
bundle.yaml generated
View file

@ -23784,6 +23784,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector
@ -35627,6 +35636,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector

View file

@ -6825,6 +6825,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector

View file

@ -8302,6 +8302,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector

View file

@ -6826,6 +6826,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector

View file

@ -8303,6 +8303,15 @@ spec:
ServiceAccountName is the name of the ServiceAccount to use to run the
Prometheus Pods.
type: string
serviceDiscoveryRole:
description: |-
Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
If set, the value should be either "Endpoints" or "EndpointSlice".
If unset, the operator assumes the "Endpoints" role.
enum:
- Endpoints
- EndpointSlice
type: string
serviceMonitorNamespaceSelector:
description: |-
Namespaces to match for ServicedMonitors discovery. An empty label selector

View file

@ -5590,6 +5590,14 @@
"description": "ServiceAccountName is the name of the ServiceAccount to use to run the\nPrometheus Pods.",
"type": "string"
},
"serviceDiscoveryRole": {
"description": "Defines the service discovery role used to discover targets from `ServiceMonitor` objects.\nIf set, the value should be either \"Endpoints\" or \"EndpointSlice\".\nIf unset, the operator assumes the \"Endpoints\" role.",
"enum": [
"Endpoints",
"EndpointSlice"
],
"type": "string"
},
"serviceMonitorNamespaceSelector": {
"description": "Namespaces to match for ServicedMonitors discovery. An empty label selector\nmatches all namespaces. A null label selector (default value) matches the current\nnamespace only.",
"properties": {

View file

@ -6797,6 +6797,14 @@
"description": "ServiceAccountName is the name of the ServiceAccount to use to run the\nPrometheus Pods.",
"type": "string"
},
"serviceDiscoveryRole": {
"description": "Defines the service discovery role used to discover targets from `ServiceMonitor` objects.\nIf set, the value should be either \"Endpoints\" or \"EndpointSlice\".\nIf unset, the operator assumes the \"Endpoints\" role.",
"enum": [
"Endpoints",
"EndpointSlice"
],
"type": "string"
},
"serviceMonitorNamespaceSelector": {
"description": "Namespaces to match for ServicedMonitors discovery. An empty label selector\nmatches all namespaces. A null label selector (default value) matches the current\nnamespace only.",
"properties": {

View file

@ -772,6 +772,12 @@ type CommonPrometheusFields struct {
// +listType=map
// +listMapKey=name
ScrapeClasses []ScrapeClass `json:"scrapeClasses,omitempty"`
// Defines the service discovery role used to discover targets from `ServiceMonitor` objects.
// If set, the value should be either "Endpoints" or "EndpointSlice".
// If unset, the operator assumes the "Endpoints" role.
// +optional
ServiceDiscoveryRole *ServiceDiscoveryRole `json:"serviceDiscoveryRole,omitempty"`
}
// +kubebuilder:validation:Enum=HTTP;ProcessSignal
@ -785,6 +791,14 @@ const (
ProcessSignalReloadStrategyType ReloadStrategyType = "ProcessSignal"
)
// +kubebuilder:validation:Enum=Endpoints;EndpointSlice
type ServiceDiscoveryRole string
const (
EndpointsRole ServiceDiscoveryRole = "Endpoints"
EndpointSliceRole ServiceDiscoveryRole = "EndpointSlice"
)
func (cpf *CommonPrometheusFields) PrometheusURIScheme() string {
if cpf.Web != nil && cpf.Web.TLSConfig != nil {
return "https"

View file

@ -969,6 +969,11 @@ func (in *CommonPrometheusFields) DeepCopyInto(out *CommonPrometheusFields) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.ServiceDiscoveryRole != nil {
in, out := &in.ServiceDiscoveryRole, &out.ServiceDiscoveryRole
*out = new(ServiceDiscoveryRole)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonPrometheusFields.

View file

@ -107,6 +107,7 @@ type CommonPrometheusFieldsApplyConfiguration struct {
ReloadStrategy *monitoringv1.ReloadStrategyType `json:"reloadStrategy,omitempty"`
MaximumStartupDurationSeconds *int32 `json:"maximumStartupDurationSeconds,omitempty"`
ScrapeClasses []ScrapeClassApplyConfiguration `json:"scrapeClasses,omitempty"`
ServiceDiscoveryRole *monitoringv1.ServiceDiscoveryRole `json:"serviceDiscoveryRole,omitempty"`
}
// CommonPrometheusFieldsApplyConfiguration constructs an declarative configuration of the CommonPrometheusFields type for use with
@ -826,3 +827,11 @@ func (b *CommonPrometheusFieldsApplyConfiguration) WithScrapeClasses(values ...*
}
return b
}
// WithServiceDiscoveryRole sets the ServiceDiscoveryRole field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ServiceDiscoveryRole field is set to the value of the last call.
func (b *CommonPrometheusFieldsApplyConfiguration) WithServiceDiscoveryRole(value monitoringv1.ServiceDiscoveryRole) *CommonPrometheusFieldsApplyConfiguration {
b.ServiceDiscoveryRole = &value
return b
}

View file

@ -769,6 +769,14 @@ func (b *PrometheusSpecApplyConfiguration) WithScrapeClasses(values ...*ScrapeCl
return b
}
// WithServiceDiscoveryRole sets the ServiceDiscoveryRole field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ServiceDiscoveryRole field is set to the value of the last call.
func (b *PrometheusSpecApplyConfiguration) WithServiceDiscoveryRole(value monitoringv1.ServiceDiscoveryRole) *PrometheusSpecApplyConfiguration {
b.ServiceDiscoveryRole = &value
return b
}
// WithBaseImage sets the BaseImage field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BaseImage field is set to the value of the last call.

View file

@ -756,3 +756,11 @@ func (b *PrometheusAgentSpecApplyConfiguration) WithScrapeClasses(values ...*v1.
}
return b
}
// WithServiceDiscoveryRole sets the ServiceDiscoveryRole field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the ServiceDiscoveryRole field is set to the value of the last call.
func (b *PrometheusAgentSpecApplyConfiguration) WithServiceDiscoveryRole(value monitoringv1.ServiceDiscoveryRole) *PrometheusAgentSpecApplyConfiguration {
b.ServiceDiscoveryRole = &value
return b
}

View file

@ -89,7 +89,7 @@ type Operator struct {
reconciliations *operator.ReconciliationTracker
config prompkg.Config
endpointSliceSupported bool
endpointSliceSupported bool // Whether the Kubernetes API suports the EndpointSlice kind.
scrapeConfigSupported bool
canReadStorageClass bool
@ -318,15 +318,11 @@ func New(ctx context.Context, restConfig *rest.Config, c operator.Config, logger
}
}
endpointSliceSupported, err := k8sutil.IsAPIGroupVersionResourceSupported(o.kclient.Discovery(), schema.GroupVersion{Group: "discovery.k8s.io", Version: "v1"}, "endpointslices")
o.endpointSliceSupported, err = k8sutil.IsAPIGroupVersionResourceSupported(o.kclient.Discovery(), schema.GroupVersion{Group: "discovery.k8s.io", Version: "v1"}, "endpointslices")
if err != nil {
level.Warn(o.logger).Log("msg", "failed to check if the API supports the endpointslice resources", "err ", err)
}
level.Info(o.logger).Log("msg", "Kubernetes API capabilities", "endpointslices", endpointSliceSupported)
// The operator doesn't yet support the endpointslices API.
// See https://github.com/prometheus-operator/prometheus-operator/issues/3862
// for details.
o.endpointSliceSupported = false
level.Info(o.logger).Log("msg", "Kubernetes API capabilities", "endpointslices", o.endpointSliceSupported)
o.statusReporter = prompkg.StatusReporter{
Kclient: o.kclient,

View file

@ -64,13 +64,15 @@ type ConfigGenerator struct {
version semver.Version
notCompatible bool
prom monitoringv1.PrometheusInterface
endpointSliceSupported bool
useEndpointSlice bool // Whether to use EndpointSlice for service discovery from `ServiceMonitor` objects.
scrapeClasses map[string]monitoringv1.ScrapeClass
defaultScrapeClassName string
}
// NewConfigGenerator creates a ConfigGenerator for the provided Prometheus resource.
func NewConfigGenerator(logger log.Logger, p monitoringv1.PrometheusInterface, endpointSliceSupported bool) (*ConfigGenerator, error) {
func NewConfigGenerator(logger log.Logger,
p monitoringv1.PrometheusInterface,
endpointSliceSupported bool) (*ConfigGenerator, error) {
if logger == nil {
logger = log.NewNopLogger()
}
@ -94,11 +96,28 @@ func NewConfigGenerator(logger log.Logger, p monitoringv1.PrometheusInterface, e
return nil, fmt.Errorf("failed to parse scrape classes: %w", err)
}
endpointSliceConfigured := false // Always assume false to preserve original prometheus-operator behaviour.
// Check if the user has explicitly set the service discovery role to use.
switch serviceDiscoveryRole := ptr.Deref(cpf.ServiceDiscoveryRole, monitoringv1.EndpointsRole); serviceDiscoveryRole {
case monitoringv1.EndpointSliceRole:
level.Info(logger).Log("msg", "using endpointslice as service discovery role")
endpointSliceConfigured = true
case monitoringv1.EndpointsRole:
level.Info(logger).Log("msg", "using endpoints as service discovery role")
endpointSliceConfigured = false
default:
level.Warn(logger).Log("msg",
"unknown service discovery role %q, defaulting to endpoints. Configure serviceDiscoveryRole to 'EndpointSlice' to use endpointslice as service discovery role.",
serviceDiscoveryRole)
endpointSliceConfigured = false
}
return &ConfigGenerator{
logger: logger,
version: version,
prom: p,
endpointSliceSupported: endpointSliceSupported,
useEndpointSlice: endpointSliceConfigured && endpointSliceSupported,
scrapeClasses: scrapeClasses,
defaultScrapeClassName: defaultScrapeClassName,
}, nil
@ -142,7 +161,7 @@ func (cg *ConfigGenerator) WithKeyVals(keyvals ...interface{}) *ConfigGenerator
version: cg.version,
notCompatible: cg.notCompatible,
prom: cg.prom,
endpointSliceSupported: cg.endpointSliceSupported,
useEndpointSlice: cg.useEndpointSlice,
scrapeClasses: cg.scrapeClasses,
defaultScrapeClassName: cg.defaultScrapeClassName,
}
@ -161,7 +180,7 @@ func (cg *ConfigGenerator) WithMinimumVersion(version string) *ConfigGenerator {
version: cg.version,
notCompatible: true,
prom: cg.prom,
endpointSliceSupported: cg.endpointSliceSupported,
useEndpointSlice: cg.useEndpointSlice,
scrapeClasses: cg.scrapeClasses,
defaultScrapeClassName: cg.defaultScrapeClassName,
}
@ -183,7 +202,7 @@ func (cg *ConfigGenerator) WithMaximumVersion(version string) *ConfigGenerator {
version: cg.version,
notCompatible: true,
prom: cg.prom,
endpointSliceSupported: cg.endpointSliceSupported,
useEndpointSlice: cg.useEndpointSlice,
scrapeClasses: cg.scrapeClasses,
defaultScrapeClassName: cg.defaultScrapeClassName,
}
@ -329,8 +348,11 @@ func (cg *ConfigGenerator) AddHonorLabels(cfg yaml.MapSlice, honorLabels bool) y
return cg.AppendMapItem(cfg, "honor_labels", honorLabels)
}
// Returns true if the Prometheus version used supports service discovery via EndpointSlice
// and the prometheus-operator config generator is configured to use EndpointSlices for
// service discovery from ServiceMonitor objects.
func (cg *ConfigGenerator) EndpointSliceSupported() bool {
return cg.version.GTE(semver.MustParse("2.21.0")) && cg.endpointSliceSupported
return cg.version.GTE(semver.MustParse("2.21.0")) && cg.useEndpointSlice
}
// stringMapToMapSlice returns a yaml.MapSlice from a string map to ensure that

View file

@ -66,7 +66,15 @@ func mustNewConfigGenerator(t *testing.T, p *monitoringv1.Prometheus) *ConfigGen
}
logger := level.NewFilter(log.NewLogfmtLogger(os.Stdout), level.AllowWarn())
cg, err := NewConfigGenerator(log.With(logger, "test", t.Name()), p, false)
useEndpointSlice := false
if p.Spec.ServiceDiscoveryRole == nil || *p.Spec.ServiceDiscoveryRole == monitoringv1.EndpointsRole {
useEndpointSlice = false
} else if *p.Spec.ServiceDiscoveryRole == monitoringv1.EndpointSliceRole {
useEndpointSlice = true
}
cg, err := NewConfigGenerator(log.With(logger, "test", t.Name()), p, useEndpointSlice)
require.NoError(t, err)
return cg
@ -825,11 +833,13 @@ func TestK8SSDConfigGeneration(t *testing.T) {
testcases := []struct {
apiServerConfig *monitoringv1.APIServerConfig
store *assets.StoreBuilder
role string
golden string
}{
{
apiServerConfig: nil,
store: assets.NewTestStoreBuilder(),
role: "endpoints",
golden: "K8SSDConfigGenerationFirst.golden",
},
{
@ -864,8 +874,15 @@ func TestK8SSDConfigGeneration(t *testing.T) {
},
},
),
role: "endpoints",
golden: "K8SSDConfigGenerationTwo.golden",
},
{
apiServerConfig: nil,
store: assets.NewTestStoreBuilder(),
role: "endpointslice",
golden: "K8SSDConfigGenerationThree.golden",
},
{
apiServerConfig: &monitoringv1.APIServerConfig{
Host: "example.com",
@ -897,6 +914,7 @@ func TestK8SSDConfigGeneration(t *testing.T) {
},
},
store: assets.NewTestStoreBuilder(),
role: "endpoints",
golden: "K8SSDConfigGenerationTLSConfig.golden",
},
}
@ -925,7 +943,7 @@ func TestK8SSDConfigGeneration(t *testing.T) {
sm.Namespace,
tc.apiServerConfig,
tc.store.ForNamespace(sm.Namespace),
kubernetesSDRoleEndpoint,
tc.role,
attachMetaConfig,
)
s, err := yaml.Marshal(yaml.MapSlice{c})
@ -1564,9 +1582,10 @@ func TestNoEnforcedNamespaceLabelServiceMonitor(t *testing.T) {
func TestServiceMonitorWithEndpointSliceEnable(t *testing.T) {
p := defaultPrometheus()
p.Spec.CommonPrometheusFields.EnforcedNamespaceLabel = "ns-key"
p.Spec.CommonPrometheusFields.ServiceDiscoveryRole = ptr.To(monitoringv1.EndpointSliceRole)
cg := mustNewConfigGenerator(t, p)
cg.endpointSliceSupported = true
cfg, err := cg.GenerateServerConfiguration(
p.Spec.EvaluationInterval,
p.Spec.QueryLogFile,

View file

@ -355,15 +355,11 @@ func New(ctx context.Context, restConfig *rest.Config, c operator.Config, logger
}
}
endpointSliceSupported, err := k8sutil.IsAPIGroupVersionResourceSupported(o.kclient.Discovery(), schema.GroupVersion{Group: "discovery.k8s.io", Version: "v1"}, "endpointslices")
o.endpointSliceSupported, err = k8sutil.IsAPIGroupVersionResourceSupported(o.kclient.Discovery(), schema.GroupVersion{Group: "discovery.k8s.io", Version: "v1"}, "endpointslices")
if err != nil {
level.Warn(o.logger).Log("msg", "failed to check if the API supports the endpointslice resources", "err ", err)
}
level.Info(o.logger).Log("msg", "Kubernetes API capabilities", "endpointslices", endpointSliceSupported)
// The operator doesn't yet support the endpointslices API.
// See https://github.com/prometheus-operator/prometheus-operator/issues/3862
// for details.
o.endpointSliceSupported = false
level.Info(o.logger).Log("msg", "Kubernetes API capabilities", "endpointslices", o.endpointSliceSupported)
o.statusReporter = prompkg.StatusReporter{
Kclient: o.kclient,
@ -813,6 +809,7 @@ func (c *Operator) sync(ctx context.Context, key string) error {
}
assetStore := assets.NewStoreBuilder(c.kclient.CoreV1(), c.kclient.CoreV1())
cg, err := prompkg.NewConfigGenerator(c.logger, p, c.endpointSliceSupported)
if err != nil {
return err

View file

@ -0,0 +1,5 @@
kubernetes_sd_configs:
- role: endpointslice
namespaces:
names:
- test