mirror of
https://github.com/prometheus-operator/prometheus-operator.git
synced 2025-04-15 16:56:24 +00:00
feat: enable config reload via signal
This commit adds the option to reload Prometheus configuration using signal instead of the /-/reload endpoint. Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
parent
34941afa1a
commit
a143c8da5d
22 changed files with 550 additions and 177 deletions
97
Documentation/api.md
generated
97
Documentation/api.md
generated
|
@ -2547,6 +2547,21 @@ that will be kept in memory. 0 means no limit.</p>
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>reloadStrategy</code><br/>
|
||||
<em>
|
||||
<a href="#monitoring.coreos.com/v1.ReloadStrategyType">
|
||||
ReloadStrategyType
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>baseImage</code><br/>
|
||||
<em>
|
||||
string
|
||||
|
@ -6892,6 +6907,21 @@ that will be kept in memory. 0 means no limit.</p>
|
|||
<p>It requires Prometheus >= v2.47.0.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>reloadStrategy</code><br/>
|
||||
<em>
|
||||
<a href="#monitoring.coreos.com/v1.ReloadStrategyType">
|
||||
ReloadStrategyType
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="monitoring.coreos.com/v1.Condition">Condition
|
||||
|
@ -10793,6 +10823,21 @@ that will be kept in memory. 0 means no limit.</p>
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>reloadStrategy</code><br/>
|
||||
<em>
|
||||
<a href="#monitoring.coreos.com/v1.ReloadStrategyType">
|
||||
ReloadStrategyType
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>baseImage</code><br/>
|
||||
<em>
|
||||
string
|
||||
|
@ -11720,6 +11765,28 @@ string
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="monitoring.coreos.com/v1.ReloadStrategyType">ReloadStrategyType
|
||||
(<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>"HTTP"</p></td>
|
||||
<td><p>HTTPReloadStrategyType reloads the configuration using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr><tr><td><p>"ProcessSignal"</p></td>
|
||||
<td><p>ProcessSignalReloadStrategyType reloads the configuration by sending a SIGHUP signal to the process.</p>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
<h3 id="monitoring.coreos.com/v1.RemoteReadSpec">RemoteReadSpec
|
||||
</h3>
|
||||
<p>
|
||||
|
@ -16144,6 +16211,21 @@ that will be kept in memory. 0 means no limit.</p>
|
|||
<p>It requires Prometheus >= v2.47.0.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>reloadStrategy</code><br/>
|
||||
<em>
|
||||
<a href="#monitoring.coreos.com/v1.ReloadStrategyType">
|
||||
ReloadStrategyType
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -20331,6 +20413,21 @@ that will be kept in memory. 0 means no limit.</p>
|
|||
<p>It requires Prometheus >= v2.47.0.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>reloadStrategy</code><br/>
|
||||
<em>
|
||||
<a href="#monitoring.coreos.com/v1.ReloadStrategyType">
|
||||
ReloadStrategyType
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="monitoring.coreos.com/v1alpha1.PushoverConfig">PushoverConfig
|
||||
|
|
16
bundle.yaml
generated
16
bundle.yaml
generated
|
@ -18963,6 +18963,14 @@ spec:
|
|||
when the field is set to the empty string (`\"\"`). \n Default:
|
||||
\"prometheus\""
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteWrite:
|
||||
description: Defines the list of remote write configurations.
|
||||
items:
|
||||
|
@ -27961,6 +27969,14 @@ spec:
|
|||
can be set to a standard I/O stream, e.g. `/dev/stdout`, to log
|
||||
query information to the default Prometheus log stream."
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteRead:
|
||||
description: Defines the list of remote read configurations.
|
||||
items:
|
||||
|
|
|
@ -49,6 +49,9 @@ const (
|
|||
defaultRetryInterval = 5 * time.Second // 5 seconds was the value previously hardcoded in github.com/thanos-io/thanos/pkg/reloader.
|
||||
defaultReloadTimeout = 30 * time.Second // 30 seconds was the default value
|
||||
|
||||
httpReloadMethod = "http"
|
||||
signalReloadMethod = "signal"
|
||||
|
||||
statefulsetOrdinalEnvvar = "STATEFULSET_ORDINAL_NUMBER"
|
||||
)
|
||||
|
||||
|
@ -67,6 +70,9 @@ func main() {
|
|||
|
||||
watchedDir := app.Flag("watched-dir", "directory to watch non-recursively").Strings()
|
||||
|
||||
reloadMethod := app.Flag("reload-method", "method used to reload the configuration").Default(httpReloadMethod).Enum(httpReloadMethod, signalReloadMethod)
|
||||
processName := app.Flag("process-executable-name", "executable name used to match the process when using the signal reload method").Default("prometheus").String()
|
||||
|
||||
createStatefulsetOrdinalFrom := app.Flag(
|
||||
"statefulset-ordinal-from-envvar",
|
||||
fmt.Sprintf("parse this environment variable to create %s, containing the statefulset ordinal number", statefulsetOrdinalEnvvar)).
|
||||
|
@ -93,9 +99,12 @@ func main() {
|
|||
fmt.Sprintf("log level to use. Possible values: %s", strings.Join(logging.AvailableLogLevels, ", "))).
|
||||
Default(logging.LevelInfo).StringVar(&logConfig.Level)
|
||||
|
||||
reloadURL := app.Flag("reload-url", "reload URL to trigger Prometheus reload on").
|
||||
reloadURL := app.Flag("reload-url", "URL to trigger the configuration").
|
||||
Default("http://127.0.0.1:9090/-/reload").URL()
|
||||
|
||||
runtimeInfoURL := app.Flag("runtimeinfo-url", "URL to check the status of the runtime configuration").
|
||||
Default("http://127.0.0.1:9090/api/v1/status/runtimeinfo").URL()
|
||||
|
||||
versionutil.RegisterIntoKingpinFlags(app)
|
||||
|
||||
if _, err := app.Parse(os.Args[1:]); err != nil {
|
||||
|
@ -140,23 +149,30 @@ func main() {
|
|||
)
|
||||
|
||||
{
|
||||
opts := reloader.Options{
|
||||
CfgFile: *cfgFile,
|
||||
CfgOutputFile: *cfgSubstFile,
|
||||
WatchedDirs: *watchedDir,
|
||||
DelayInterval: *delayInterval,
|
||||
WatchInterval: *watchInterval,
|
||||
RetryInterval: *retryInterval,
|
||||
}
|
||||
|
||||
switch *reloadMethod {
|
||||
case signalReloadMethod:
|
||||
opts.RuntimeInfoURL = *runtimeInfoURL
|
||||
opts.ProcessName = *processName
|
||||
default:
|
||||
opts.ReloadURL = *reloadURL
|
||||
opts.HTTPClient = createHTTPClient(reloadTimeout)
|
||||
}
|
||||
|
||||
rel := reloader.New(
|
||||
logger,
|
||||
r,
|
||||
&reloader.Options{
|
||||
ReloadURL: *reloadURL,
|
||||
CfgFile: *cfgFile,
|
||||
CfgOutputFile: *cfgSubstFile,
|
||||
WatchedDirs: *watchedDir,
|
||||
DelayInterval: *delayInterval,
|
||||
WatchInterval: *watchInterval,
|
||||
RetryInterval: *retryInterval,
|
||||
},
|
||||
&opts,
|
||||
)
|
||||
|
||||
client := createHTTPClient(reloadTimeout)
|
||||
rel.SetHttpClient(client)
|
||||
|
||||
g.Add(func() error {
|
||||
return rel.Watch(ctx)
|
||||
}, func(error) {
|
||||
|
|
|
@ -4366,6 +4366,14 @@ spec:
|
|||
when the field is set to the empty string (`\"\"`). \n Default:
|
||||
\"prometheus\""
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteWrite:
|
||||
description: Defines the list of remote write configurations.
|
||||
items:
|
||||
|
|
|
@ -4854,6 +4854,14 @@ spec:
|
|||
can be set to a standard I/O stream, e.g. `/dev/stdout`, to log
|
||||
query information to the default Prometheus log stream."
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteRead:
|
||||
description: Defines the list of remote read configurations.
|
||||
items:
|
||||
|
|
|
@ -4367,6 +4367,14 @@ spec:
|
|||
when the field is set to the empty string (`\"\"`). \n Default:
|
||||
\"prometheus\""
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteWrite:
|
||||
description: Defines the list of remote write configurations.
|
||||
items:
|
||||
|
|
|
@ -4855,6 +4855,14 @@ spec:
|
|||
can be set to a standard I/O stream, e.g. `/dev/stdout`, to log
|
||||
query information to the default Prometheus log stream."
|
||||
type: string
|
||||
reloadStrategy:
|
||||
description: Defines the strategy used to reload the Prometheus configuration.
|
||||
If not specified, the configuration is reloaded using the /-/reload
|
||||
HTTP endpoint.
|
||||
enum:
|
||||
- HTTP
|
||||
- ProcessSignal
|
||||
type: string
|
||||
remoteRead:
|
||||
description: Defines the list of remote read configurations.
|
||||
items:
|
||||
|
|
3
go.mod
3
go.mod
|
@ -28,7 +28,7 @@ require (
|
|||
github.com/prometheus/exporter-toolkit v0.10.0
|
||||
github.com/prometheus/prometheus v0.48.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/thanos-io/thanos v0.32.5
|
||||
github.com/thanos-io/thanos v0.32.5-0.20231124114724-023faa2d67a3
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||
golang.org/x/net v0.18.0
|
||||
golang.org/x/sync v0.5.0
|
||||
|
@ -51,6 +51,7 @@ require (
|
|||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/mitchellh/go-ps v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
)
|
||||
|
||||
|
|
6
go.sum
6
go.sum
|
@ -415,6 +415,8 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz
|
|||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||
github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0=
|
||||
github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA=
|
||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
|
@ -538,8 +540,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
|||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/thanos-io/thanos v0.32.5 h1:khHvuEAbUKox9DQI9cSmLes4F9G3MqWPxcdrf2tYY0w=
|
||||
github.com/thanos-io/thanos v0.32.5/go.mod h1:POOrd2N/0wRQKkg1MJTvU29X+IVs7iMjSoN08q8V1Mo=
|
||||
github.com/thanos-io/thanos v0.32.5-0.20231124114724-023faa2d67a3 h1:jrrcsbgX3/SsaCNi+jSIyCyuOOvLGgmlKmaOHf/uEOo=
|
||||
github.com/thanos-io/thanos v0.32.5-0.20231124114724-023faa2d67a3/go.mod h1:DzjNla690uSQazyHrLGK6FeOn3VfV2ReA57Pi7SgZ+8=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
||||
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
||||
|
|
|
@ -3886,6 +3886,14 @@
|
|||
"description": "Name of Prometheus external label used to denote the Prometheus instance name. The external label will _not_ be added when the field is set to the empty string (`\"\"`). \n Default: \"prometheus\"",
|
||||
"type": "string"
|
||||
},
|
||||
"reloadStrategy": {
|
||||
"description": "Defines the strategy used to reload the Prometheus configuration. If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.",
|
||||
"enum": [
|
||||
"HTTP",
|
||||
"ProcessSignal"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"remoteWrite": {
|
||||
"description": "Defines the list of remote write configurations.",
|
||||
"items": {
|
||||
|
|
|
@ -4376,6 +4376,14 @@
|
|||
"description": "queryLogFile specifies where the file to which PromQL queries are logged. \n If the filename has an empty path, e.g. 'query.log', The Prometheus Pods will mount the file into an emptyDir volume at `/var/log/prometheus`. If a full path is provided, e.g. '/var/log/prometheus/query.log', you must mount a volume in the specified directory and it must be writable. This is because the prometheus container runs with a read-only root filesystem for security reasons. Alternatively, the location can be set to a standard I/O stream, e.g. `/dev/stdout`, to log query information to the default Prometheus log stream.",
|
||||
"type": "string"
|
||||
},
|
||||
"reloadStrategy": {
|
||||
"description": "Defines the strategy used to reload the Prometheus configuration. If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.",
|
||||
"enum": [
|
||||
"HTTP",
|
||||
"ProcessSignal"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"remoteRead": {
|
||||
"description": "Defines the list of remote read configurations.",
|
||||
"items": {
|
||||
|
|
|
@ -616,6 +616,38 @@ type CommonPrometheusFields struct {
|
|||
//
|
||||
// +optional
|
||||
KeepDroppedTargets *uint64 `json:"keepDroppedTargets,omitempty"`
|
||||
|
||||
// Defines the strategy used to reload the Prometheus configuration.
|
||||
// If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.
|
||||
// +optional
|
||||
ReloadStrategy *ReloadStrategyType `json:"reloadStrategy,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:validation:Enum=HTTP;ProcessSignal
|
||||
type ReloadStrategyType string
|
||||
|
||||
const (
|
||||
// HTTPReloadStrategyType reloads the configuration using the /-/reload HTTP endpoint.
|
||||
HTTPReloadStrategyType ReloadStrategyType = "HTTP"
|
||||
|
||||
// ProcessSignalReloadStrategyType reloads the configuration by sending a SIGHUP signal to the process.
|
||||
ProcessSignalReloadStrategyType ReloadStrategyType = "ProcessSignal"
|
||||
)
|
||||
|
||||
func (cpf *CommonPrometheusFields) PrometheusURIScheme() string {
|
||||
if cpf.Web != nil && cpf.Web.TLSConfig != nil {
|
||||
return "https"
|
||||
}
|
||||
|
||||
return "http"
|
||||
}
|
||||
|
||||
func (cpf *CommonPrometheusFields) WebRoutePrefix() string {
|
||||
if cpf.RoutePrefix != "" {
|
||||
return cpf.RoutePrefix
|
||||
}
|
||||
|
||||
return "/"
|
||||
}
|
||||
|
||||
// +genclient
|
||||
|
|
5
pkg/apis/monitoring/v1/zz_generated.deepcopy.go
generated
5
pkg/apis/monitoring/v1/zz_generated.deepcopy.go
generated
|
@ -893,6 +893,11 @@ func (in *CommonPrometheusFields) DeepCopyInto(out *CommonPrometheusFields) {
|
|||
*out = new(uint64)
|
||||
**out = **in
|
||||
}
|
||||
if in.ReloadStrategy != nil {
|
||||
in, out := &in.ReloadStrategy, &out.ReloadStrategy
|
||||
*out = new(ReloadStrategyType)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonPrometheusFields.
|
||||
|
|
|
@ -102,6 +102,7 @@ type CommonPrometheusFieldsApplyConfiguration struct {
|
|||
LabelNameLengthLimit *uint64 `json:"labelNameLengthLimit,omitempty"`
|
||||
LabelValueLengthLimit *uint64 `json:"labelValueLengthLimit,omitempty"`
|
||||
KeepDroppedTargets *uint64 `json:"keepDroppedTargets,omitempty"`
|
||||
ReloadStrategy *monitoringv1.ReloadStrategyType `json:"reloadStrategy,omitempty"`
|
||||
}
|
||||
|
||||
// CommonPrometheusFieldsApplyConfiguration constructs an declarative configuration of the CommonPrometheusFields type for use with
|
||||
|
@ -771,3 +772,11 @@ func (b *CommonPrometheusFieldsApplyConfiguration) WithKeepDroppedTargets(value
|
|||
b.KeepDroppedTargets = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithReloadStrategy sets the ReloadStrategy 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 ReloadStrategy field is set to the value of the last call.
|
||||
func (b *CommonPrometheusFieldsApplyConfiguration) WithReloadStrategy(value monitoringv1.ReloadStrategyType) *CommonPrometheusFieldsApplyConfiguration {
|
||||
b.ReloadStrategy = &value
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -719,6 +719,14 @@ func (b *PrometheusSpecApplyConfiguration) WithKeepDroppedTargets(value uint64)
|
|||
return b
|
||||
}
|
||||
|
||||
// WithReloadStrategy sets the ReloadStrategy 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 ReloadStrategy field is set to the value of the last call.
|
||||
func (b *PrometheusSpecApplyConfiguration) WithReloadStrategy(value monitoringv1.ReloadStrategyType) *PrometheusSpecApplyConfiguration {
|
||||
b.ReloadStrategy = &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.
|
||||
|
|
|
@ -697,3 +697,11 @@ func (b *PrometheusAgentSpecApplyConfiguration) WithKeepDroppedTargets(value uin
|
|||
b.KeepDroppedTargets = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithReloadStrategy sets the ReloadStrategy 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 ReloadStrategy field is set to the value of the last call.
|
||||
func (b *PrometheusAgentSpecApplyConfiguration) WithReloadStrategy(value monitoringv1.ReloadStrategyType) *PrometheusAgentSpecApplyConfiguration {
|
||||
b.ReloadStrategy = &value
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -50,14 +50,22 @@ type ConfigReloader struct {
|
|||
logFormat string
|
||||
logLevel string
|
||||
reloadURL url.URL
|
||||
runtimeInfoURL url.URL
|
||||
runOnce bool
|
||||
shard *int32
|
||||
volumeMounts []v1.VolumeMount
|
||||
watchedDirectories []string
|
||||
useSignal bool
|
||||
}
|
||||
|
||||
type ReloaderOption = func(*ConfigReloader)
|
||||
|
||||
func ReloaderUseSignal() ReloaderOption {
|
||||
return func(c *ConfigReloader) {
|
||||
c.useSignal = true
|
||||
}
|
||||
}
|
||||
|
||||
// ReloaderRunOnce sets the runOnce option for the config-reloader container
|
||||
func ReloaderRunOnce() ReloaderOption {
|
||||
return func(c *ConfigReloader) {
|
||||
|
@ -101,9 +109,16 @@ func ReloaderConfig(rc ContainerConfig) ReloaderOption {
|
|||
}
|
||||
|
||||
// ReloaderURL sets the reloaderURL option for the config-reloader container
|
||||
func ReloaderURL(reloadURL url.URL) ReloaderOption {
|
||||
func ReloaderURL(u url.URL) ReloaderOption {
|
||||
return func(c *ConfigReloader) {
|
||||
c.reloadURL = reloadURL
|
||||
c.reloadURL = u
|
||||
}
|
||||
}
|
||||
|
||||
// RuntimeInfoURL sets the runtimeInfoURL option for the config-reloader container
|
||||
func RuntimeInfoURL(u url.URL) ReloaderOption {
|
||||
return func(c *ConfigReloader) {
|
||||
c.runtimeInfoURL = u
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,8 +215,17 @@ func CreateConfigReloader(name string, options ...ReloaderOption) v1.Container {
|
|||
args = append(args, fmt.Sprintf("--web-config-file=%s", configReloader.webConfigFile))
|
||||
}
|
||||
|
||||
if len(configReloader.reloadURL.String()) > 0 {
|
||||
args = append(args, fmt.Sprintf("--reload-url=%s", configReloader.reloadURL.String()))
|
||||
if configReloader.useSignal {
|
||||
args = append(args, "--reload-method=signal")
|
||||
if len(configReloader.runtimeInfoURL.String()) > 0 {
|
||||
args = append(args, fmt.Sprintf("--runtimeinfo-url=%s", configReloader.runtimeInfoURL.String()))
|
||||
}
|
||||
} else {
|
||||
// Don't set the --reload-method argument in case the operator is
|
||||
// configured with an older version of the config reloader.
|
||||
if len(configReloader.reloadURL.String()) > 0 {
|
||||
args = append(args, fmt.Sprintf("--reload-url=%s", configReloader.reloadURL.String()))
|
||||
}
|
||||
}
|
||||
|
||||
if len(configReloader.configFile) > 0 {
|
||||
|
|
|
@ -16,14 +16,13 @@ package prometheusagent
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
|
||||
|
@ -188,13 +187,8 @@ func makeStatefulSetSpec(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
webRoutePrefix := "/"
|
||||
if cpf.RoutePrefix != "" {
|
||||
webRoutePrefix = cpf.RoutePrefix
|
||||
}
|
||||
|
||||
cpf.EnableFeatures = append(cpf.EnableFeatures, "agent")
|
||||
promArgs := prompkg.BuildCommonPrometheusArgs(cpf, cg, webRoutePrefix)
|
||||
promArgs := prompkg.BuildCommonPrometheusArgs(cpf, cg)
|
||||
promArgs = appendAgentArgs(promArgs, cg, cpf.WALCompression)
|
||||
|
||||
var ports []v1.ContainerPort
|
||||
|
@ -247,7 +241,7 @@ func makeStatefulSetSpec(
|
|||
// Prometheus is effectively ready.
|
||||
// We don't want to use the /-/healthy handler here because it returns OK as
|
||||
// soon as the web server is started (irrespective of the WAL replay).
|
||||
readyProbeHandler := prompkg.ProbeHandler("/-/ready", cpf, webConfigGenerator, webRoutePrefix)
|
||||
readyProbeHandler := prompkg.ProbeHandler("/-/ready", cpf, webConfigGenerator)
|
||||
startupProbe := &v1.Probe{
|
||||
ProbeHandler: readyProbeHandler,
|
||||
TimeoutSeconds: prompkg.ProbeTimeoutSeconds,
|
||||
|
@ -263,7 +257,7 @@ func makeStatefulSetSpec(
|
|||
}
|
||||
|
||||
livenessProbe := &v1.Probe{
|
||||
ProbeHandler: prompkg.ProbeHandler("/-/healthy", cpf, webConfigGenerator, webRoutePrefix),
|
||||
ProbeHandler: prompkg.ProbeHandler("/-/healthy", cpf, webConfigGenerator),
|
||||
TimeoutSeconds: prompkg.ProbeTimeoutSeconds,
|
||||
PeriodSeconds: 5,
|
||||
FailureThreshold: 6,
|
||||
|
@ -291,11 +285,6 @@ func makeStatefulSetSpec(
|
|||
|
||||
var additionalContainers, operatorInitContainers []v1.Container
|
||||
|
||||
prometheusURIScheme := "http"
|
||||
if cpf.Web != nil && cpf.Web.TLSConfig != nil {
|
||||
prometheusURIScheme = "https"
|
||||
}
|
||||
|
||||
var watchedDirectories []string
|
||||
configReloaderVolumeMounts := []v1.VolumeMount{
|
||||
{
|
||||
|
@ -314,18 +303,13 @@ func makeStatefulSetSpec(
|
|||
}
|
||||
|
||||
operatorInitContainers = append(operatorInitContainers,
|
||||
operator.CreateConfigReloader(
|
||||
"init-config-reloader",
|
||||
operator.ReloaderConfig(c.ReloaderConfig),
|
||||
operator.ReloaderRunOnce(),
|
||||
operator.LogFormat(cpf.LogFormat),
|
||||
operator.LogLevel(cpf.LogLevel),
|
||||
operator.VolumeMounts(configReloaderVolumeMounts),
|
||||
operator.ConfigFile(path.Join(prompkg.ConfDir, prompkg.ConfigFilename)),
|
||||
operator.ConfigEnvsubstFile(path.Join(prompkg.ConfOutDir, prompkg.ConfigEnvsubstFilename)),
|
||||
operator.WatchedDirectories(watchedDirectories),
|
||||
prompkg.BuildConfigReloader(
|
||||
p,
|
||||
c,
|
||||
true,
|
||||
configReloaderVolumeMounts,
|
||||
watchedDirectories,
|
||||
operator.Shard(shard),
|
||||
operator.ImagePullPolicy(cpf.ImagePullPolicy),
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -340,8 +324,6 @@ func makeStatefulSetSpec(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
boolFalse := false
|
||||
boolTrue := true
|
||||
operatorContainers := append([]v1.Container{
|
||||
{
|
||||
Name: "prometheus",
|
||||
|
@ -356,30 +338,20 @@ func makeStatefulSetSpec(
|
|||
Resources: cpf.Resources,
|
||||
TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
ReadOnlyRootFilesystem: &boolTrue,
|
||||
AllowPrivilegeEscalation: &boolFalse,
|
||||
ReadOnlyRootFilesystem: ptr.To(true),
|
||||
AllowPrivilegeEscalation: ptr.To(false),
|
||||
Capabilities: &v1.Capabilities{
|
||||
Drop: []v1.Capability{"ALL"},
|
||||
},
|
||||
},
|
||||
},
|
||||
operator.CreateConfigReloader(
|
||||
"config-reloader",
|
||||
operator.ReloaderConfig(c.ReloaderConfig),
|
||||
operator.ReloaderURL(url.URL{
|
||||
Scheme: prometheusURIScheme,
|
||||
Host: c.LocalHost + ":9090",
|
||||
Path: path.Clean(webRoutePrefix + "/-/reload"),
|
||||
}),
|
||||
operator.ListenLocal(cpf.ListenLocal),
|
||||
operator.LocalHost(c.LocalHost),
|
||||
operator.LogFormat(cpf.LogFormat),
|
||||
operator.LogLevel(cpf.LogLevel),
|
||||
operator.ConfigFile(path.Join(prompkg.ConfDir, prompkg.ConfigFilename)),
|
||||
operator.ConfigEnvsubstFile(path.Join(prompkg.ConfOutDir, prompkg.ConfigEnvsubstFilename)),
|
||||
operator.WatchedDirectories(watchedDirectories), operator.VolumeMounts(configReloaderVolumeMounts),
|
||||
prompkg.BuildConfigReloader(
|
||||
p,
|
||||
c,
|
||||
false,
|
||||
configReloaderVolumeMounts,
|
||||
watchedDirectories,
|
||||
operator.Shard(shard),
|
||||
operator.ImagePullPolicy(cpf.ImagePullPolicy),
|
||||
),
|
||||
}, additionalContainers...)
|
||||
|
||||
|
@ -407,11 +379,12 @@ func makeStatefulSetSpec(
|
|||
Annotations: podAnnotations,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ShareProcessNamespace: prompkg.ShareProcessNamespace(p),
|
||||
Containers: containers,
|
||||
InitContainers: initContainers,
|
||||
SecurityContext: cpf.SecurityContext,
|
||||
ServiceAccountName: cpf.ServiceAccountName,
|
||||
AutomountServiceAccountToken: &boolTrue,
|
||||
AutomountServiceAccountToken: ptr.To(true),
|
||||
NodeSelector: cpf.NodeSelector,
|
||||
PriorityClassName: cpf.PriorityClassName,
|
||||
TerminationGracePeriodSeconds: &terminationGracePeriod,
|
||||
|
|
|
@ -16,7 +16,6 @@ package prometheus
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
|
@ -25,6 +24,7 @@ import (
|
|||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
||||
"github.com/prometheus-operator/prometheus-operator/pkg/k8sutil"
|
||||
|
@ -262,11 +262,7 @@ func makeStatefulSetSpec(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
webRoutePrefix := "/"
|
||||
if cpf.RoutePrefix != "" {
|
||||
webRoutePrefix = cpf.RoutePrefix
|
||||
}
|
||||
promArgs := prompkg.BuildCommonPrometheusArgs(cpf, cg, webRoutePrefix)
|
||||
promArgs := prompkg.BuildCommonPrometheusArgs(cpf, cg)
|
||||
promArgs = appendServerArgs(promArgs, cg, retention, retentionSize, rules, query, allowOverlappingBlocks, enableAdminAPI, cpf.WALCompression)
|
||||
|
||||
var ports []v1.ContainerPort
|
||||
|
@ -320,7 +316,7 @@ func makeStatefulSetSpec(
|
|||
// Prometheus is effectively ready.
|
||||
// We don't want to use the /-/healthy handler here because it returns OK as
|
||||
// soon as the web server is started (irrespective of the WAL replay).
|
||||
readyProbeHandler := prompkg.ProbeHandler("/-/ready", cpf, webConfigGenerator, webRoutePrefix)
|
||||
readyProbeHandler := prompkg.ProbeHandler("/-/ready", cpf, webConfigGenerator)
|
||||
startupProbe := &v1.Probe{
|
||||
ProbeHandler: readyProbeHandler,
|
||||
TimeoutSeconds: prompkg.ProbeTimeoutSeconds,
|
||||
|
@ -336,7 +332,7 @@ func makeStatefulSetSpec(
|
|||
}
|
||||
|
||||
livenessProbe := &v1.Probe{
|
||||
ProbeHandler: prompkg.ProbeHandler("/-/healthy", cpf, webConfigGenerator, webRoutePrefix),
|
||||
ProbeHandler: prompkg.ProbeHandler("/-/healthy", cpf, webConfigGenerator),
|
||||
TimeoutSeconds: prompkg.ProbeTimeoutSeconds,
|
||||
PeriodSeconds: 5,
|
||||
FailureThreshold: 6,
|
||||
|
@ -365,12 +361,7 @@ func makeStatefulSetSpec(
|
|||
|
||||
var additionalContainers, operatorInitContainers []v1.Container
|
||||
|
||||
prometheusURIScheme := "http"
|
||||
if cpf.Web != nil && cpf.Web.TLSConfig != nil {
|
||||
prometheusURIScheme = "https"
|
||||
}
|
||||
|
||||
thanosContainer, err := createThanosContainer(&disableCompaction, p, thanos, c, prometheusURIScheme, webRoutePrefix)
|
||||
thanosContainer, err := createThanosContainer(&disableCompaction, p, thanos, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -416,18 +407,13 @@ func makeStatefulSetSpec(
|
|||
}
|
||||
|
||||
operatorInitContainers = append(operatorInitContainers,
|
||||
operator.CreateConfigReloader(
|
||||
"init-config-reloader",
|
||||
operator.ReloaderConfig(c.ReloaderConfig),
|
||||
operator.ReloaderRunOnce(),
|
||||
operator.LogFormat(cpf.LogFormat),
|
||||
operator.LogLevel(cpf.LogLevel),
|
||||
operator.VolumeMounts(configReloaderVolumeMounts),
|
||||
operator.ConfigFile(path.Join(prompkg.ConfDir, prompkg.ConfigFilename)),
|
||||
operator.ConfigEnvsubstFile(path.Join(prompkg.ConfOutDir, prompkg.ConfigEnvsubstFilename)),
|
||||
operator.WatchedDirectories(watchedDirectories),
|
||||
prompkg.BuildConfigReloader(
|
||||
p,
|
||||
c,
|
||||
true,
|
||||
configReloaderVolumeMounts,
|
||||
watchedDirectories,
|
||||
operator.Shard(shard),
|
||||
operator.ImagePullPolicy(cpf.ImagePullPolicy),
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -437,13 +423,10 @@ func makeStatefulSetSpec(
|
|||
}
|
||||
|
||||
containerArgs, err := operator.BuildArgs(promArgs, cpf.AdditionalArgs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
boolFalse := false
|
||||
boolTrue := true
|
||||
operatorContainers := append([]v1.Container{
|
||||
{
|
||||
Name: "prometheus",
|
||||
|
@ -458,30 +441,20 @@ func makeStatefulSetSpec(
|
|||
Resources: cpf.Resources,
|
||||
TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
ReadOnlyRootFilesystem: &boolTrue,
|
||||
AllowPrivilegeEscalation: &boolFalse,
|
||||
ReadOnlyRootFilesystem: ptr.To(true),
|
||||
AllowPrivilegeEscalation: ptr.To(false),
|
||||
Capabilities: &v1.Capabilities{
|
||||
Drop: []v1.Capability{"ALL"},
|
||||
},
|
||||
},
|
||||
},
|
||||
operator.CreateConfigReloader(
|
||||
"config-reloader",
|
||||
operator.ReloaderConfig(c.ReloaderConfig),
|
||||
operator.ReloaderURL(url.URL{
|
||||
Scheme: prometheusURIScheme,
|
||||
Host: c.LocalHost + ":9090",
|
||||
Path: path.Clean(webRoutePrefix + "/-/reload"),
|
||||
}),
|
||||
operator.ListenLocal(cpf.ListenLocal),
|
||||
operator.LocalHost(c.LocalHost),
|
||||
operator.LogFormat(cpf.LogFormat),
|
||||
operator.LogLevel(cpf.LogLevel),
|
||||
operator.ConfigFile(path.Join(prompkg.ConfDir, prompkg.ConfigFilename)),
|
||||
operator.ConfigEnvsubstFile(path.Join(prompkg.ConfOutDir, prompkg.ConfigEnvsubstFilename)),
|
||||
operator.WatchedDirectories(watchedDirectories), operator.VolumeMounts(configReloaderVolumeMounts),
|
||||
prompkg.BuildConfigReloader(
|
||||
p,
|
||||
c,
|
||||
false,
|
||||
configReloaderVolumeMounts,
|
||||
watchedDirectories,
|
||||
operator.Shard(shard),
|
||||
operator.ImagePullPolicy(cpf.ImagePullPolicy),
|
||||
),
|
||||
}, additionalContainers...)
|
||||
|
||||
|
@ -509,11 +482,12 @@ func makeStatefulSetSpec(
|
|||
Annotations: podAnnotations,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ShareProcessNamespace: prompkg.ShareProcessNamespace(p),
|
||||
Containers: containers,
|
||||
InitContainers: initContainers,
|
||||
SecurityContext: cpf.SecurityContext,
|
||||
ServiceAccountName: cpf.ServiceAccountName,
|
||||
AutomountServiceAccountToken: &boolTrue,
|
||||
AutomountServiceAccountToken: ptr.To(true),
|
||||
NodeSelector: cpf.NodeSelector,
|
||||
PriorityClassName: cpf.PriorityClassName,
|
||||
TerminationGracePeriodSeconds: &terminationGracePeriod,
|
||||
|
@ -647,8 +621,7 @@ func createThanosContainer(
|
|||
disableCompaction *bool,
|
||||
p monitoringv1.PrometheusInterface,
|
||||
thanos *monitoringv1.ThanosSpec,
|
||||
c *prompkg.Config,
|
||||
prometheusURIScheme, webRoutePrefix string) (*v1.Container, error) {
|
||||
c *prompkg.Config) (*v1.Container, error) {
|
||||
|
||||
var container *v1.Container
|
||||
cpf := p.GetCommonPrometheusFields()
|
||||
|
@ -675,7 +648,7 @@ func createThanosContainer(
|
|||
}
|
||||
|
||||
thanosArgs := []monitoringv1.Argument{
|
||||
{Name: "prometheus.url", Value: fmt.Sprintf("%s://%s:9090%s", prometheusURIScheme, c.LocalHost, path.Clean(webRoutePrefix))},
|
||||
{Name: "prometheus.url", Value: fmt.Sprintf("%s://%s:9090%s", cpf.PrometheusURIScheme(), c.LocalHost, path.Clean(cpf.WebRoutePrefix()))},
|
||||
{Name: "prometheus.http-client", Value: `{"tls_config": {"insecure_skip_verify":true}}`},
|
||||
{Name: "grpc-address", Value: fmt.Sprintf("%s:10901", grpcBindAddress)},
|
||||
{Name: "http-address", Value: fmt.Sprintf("%s:10902", httpBindAddress)},
|
||||
|
|
|
@ -2075,6 +2075,83 @@ func TestConfigReloader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestConfigReloaderWithSignal(t *testing.T) {
|
||||
expectedShardNum := 0
|
||||
logger := newLogger()
|
||||
p := monitoringv1.Prometheus{
|
||||
Spec: monitoringv1.PrometheusSpec{
|
||||
CommonPrometheusFields: monitoringv1.CommonPrometheusFields{
|
||||
ReloadStrategy: func(r monitoringv1.ReloadStrategyType) *monitoringv1.ReloadStrategyType { return &r }(monitoringv1.ProcessSignalReloadStrategyType),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cg, err := prompkg.NewConfigGenerator(logger, &p, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
sset, err := makeStatefulSet(
|
||||
"test",
|
||||
&p,
|
||||
p.Spec.BaseImage, p.Spec.Tag, p.Spec.SHA,
|
||||
p.Spec.Retention,
|
||||
p.Spec.RetentionSize,
|
||||
p.Spec.Rules,
|
||||
p.Spec.Query,
|
||||
p.Spec.AllowOverlappingBlocks,
|
||||
p.Spec.EnableAdminAPI,
|
||||
p.Spec.QueryLogFile,
|
||||
p.Spec.Thanos,
|
||||
p.Spec.DisableCompaction,
|
||||
defaultTestConfig,
|
||||
cg,
|
||||
nil,
|
||||
"",
|
||||
int32(expectedShardNum),
|
||||
nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedArgsConfigReloader := []string{
|
||||
"--listen-address=:8080",
|
||||
"--reload-method=signal",
|
||||
"--runtimeinfo-url=http://localhost:9090/api/v1/status/runtimeinfo",
|
||||
"--config-file=/etc/prometheus/config/prometheus.yaml.gz",
|
||||
"--config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml",
|
||||
}
|
||||
|
||||
for _, c := range sset.Spec.Template.Spec.Containers {
|
||||
switch c.Name {
|
||||
case "config-reloader":
|
||||
require.Equal(t, expectedArgsConfigReloader, c.Args)
|
||||
for _, env := range c.Env {
|
||||
if env.Name == "SHARD" {
|
||||
require.Equal(t, strconv.Itoa(expectedShardNum), env.Value)
|
||||
}
|
||||
}
|
||||
|
||||
case "prometheus":
|
||||
require.NotContains(t, c.Args, "--web.enable-lifecycle")
|
||||
}
|
||||
}
|
||||
|
||||
expectedArgsInitConfigReloader := []string{
|
||||
"--watch-interval=0",
|
||||
"--listen-address=:8080",
|
||||
"--config-file=/etc/prometheus/config/prometheus.yaml.gz",
|
||||
"--config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml",
|
||||
}
|
||||
|
||||
for _, c := range sset.Spec.Template.Spec.InitContainers {
|
||||
if c.Name == "init-config-reloader" {
|
||||
require.Equal(t, expectedArgsInitConfigReloader, c.Args)
|
||||
for _, env := range c.Env {
|
||||
if env.Name == "SHARD" {
|
||||
require.Equal(t, strconv.Itoa(expectedShardNum), env.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestThanosGetConfigInterval(t *testing.T) {
|
||||
sset, err := makeStatefulSetFromPrometheus(monitoringv1.Prometheus{
|
||||
Spec: monitoringv1.PrometheusSpec{
|
||||
|
|
|
@ -204,12 +204,15 @@ func queryLogFilePath(queryLogFile string) string {
|
|||
}
|
||||
|
||||
// BuildCommonPrometheusArgs builds a slice of arguments that are common between Prometheus Server and Agent.
|
||||
func BuildCommonPrometheusArgs(cpf monitoringv1.CommonPrometheusFields, cg *ConfigGenerator, webRoutePrefix string) []monitoringv1.Argument {
|
||||
func BuildCommonPrometheusArgs(cpf monitoringv1.CommonPrometheusFields, cg *ConfigGenerator) []monitoringv1.Argument {
|
||||
promArgs := []monitoringv1.Argument{
|
||||
{Name: "web.console.templates", Value: "/etc/prometheus/consoles"},
|
||||
{Name: "web.console.libraries", Value: "/etc/prometheus/console_libraries"},
|
||||
{Name: "config.file", Value: path.Join(ConfOutDir, ConfigEnvsubstFilename)},
|
||||
{Name: "web.enable-lifecycle"},
|
||||
}
|
||||
|
||||
if ptr.Deref(cpf.ReloadStrategy, monitoringv1.HTTPReloadStrategyType) == monitoringv1.HTTPReloadStrategyType {
|
||||
promArgs = append(promArgs, monitoringv1.Argument{Name: "web.enable-lifecycle"})
|
||||
}
|
||||
|
||||
if cpf.Web != nil {
|
||||
|
@ -234,7 +237,7 @@ func BuildCommonPrometheusArgs(cpf monitoringv1.CommonPrometheusFields, cg *Conf
|
|||
promArgs = append(promArgs, monitoringv1.Argument{Name: "web.external-url", Value: cpf.ExternalURL})
|
||||
}
|
||||
|
||||
promArgs = append(promArgs, monitoringv1.Argument{Name: "web.route-prefix", Value: webRoutePrefix})
|
||||
promArgs = append(promArgs, monitoringv1.Argument{Name: "web.route-prefix", Value: cpf.WebRoutePrefix()})
|
||||
|
||||
if cpf.LogLevel != "" && cpf.LogLevel != "info" {
|
||||
promArgs = append(promArgs, monitoringv1.Argument{Name: "log.level", Value: cpf.LogLevel})
|
||||
|
@ -375,8 +378,8 @@ func VolumeClaimName(p monitoringv1.PrometheusInterface, cpf monitoringv1.Common
|
|||
return volName
|
||||
}
|
||||
|
||||
func ProbeHandler(probePath string, cpf monitoringv1.CommonPrometheusFields, webConfigGenerator *ConfigGenerator, webRoutePrefix string) v1.ProbeHandler {
|
||||
probePath = path.Clean(webRoutePrefix + probePath)
|
||||
func ProbeHandler(probePath string, cpf monitoringv1.CommonPrometheusFields, webConfigGenerator *ConfigGenerator) v1.ProbeHandler {
|
||||
probePath = path.Clean(cpf.WebRoutePrefix() + probePath)
|
||||
handler := v1.ProbeHandler{}
|
||||
if cpf.ListenLocal {
|
||||
probeURL := url.URL{
|
||||
|
@ -427,3 +430,69 @@ func BuildPodMetadata(cpf monitoringv1.CommonPrometheusFields, cg *ConfigGenerat
|
|||
|
||||
return podAnnotations, podLabels
|
||||
}
|
||||
|
||||
func BuildConfigReloader(
|
||||
p monitoringv1.PrometheusInterface,
|
||||
c *Config,
|
||||
initContainer bool,
|
||||
mounts []v1.VolumeMount,
|
||||
watchedDirectories []string,
|
||||
opts ...operator.ReloaderOption,
|
||||
) v1.Container {
|
||||
cpf := p.GetCommonPrometheusFields()
|
||||
|
||||
reloaderOptions := []operator.ReloaderOption{
|
||||
operator.ReloaderConfig(c.ReloaderConfig),
|
||||
operator.LogFormat(cpf.LogFormat),
|
||||
operator.LogLevel(cpf.LogLevel),
|
||||
operator.VolumeMounts(mounts),
|
||||
operator.ConfigFile(path.Join(ConfDir, ConfigFilename)),
|
||||
operator.ConfigEnvsubstFile(path.Join(ConfOutDir, ConfigEnvsubstFilename)),
|
||||
operator.WatchedDirectories(watchedDirectories),
|
||||
operator.ImagePullPolicy(cpf.ImagePullPolicy),
|
||||
}
|
||||
reloaderOptions = append(reloaderOptions, opts...)
|
||||
|
||||
name := "config-reloader"
|
||||
if initContainer {
|
||||
name = "init-config-reloader"
|
||||
reloaderOptions = append(reloaderOptions, operator.ReloaderRunOnce())
|
||||
return operator.CreateConfigReloader(name, reloaderOptions...)
|
||||
}
|
||||
|
||||
if ptr.Deref(cpf.ReloadStrategy, monitoringv1.HTTPReloadStrategyType) == monitoringv1.ProcessSignalReloadStrategyType {
|
||||
reloaderOptions = append(reloaderOptions,
|
||||
operator.ReloaderUseSignal(),
|
||||
)
|
||||
reloaderOptions = append(reloaderOptions,
|
||||
operator.RuntimeInfoURL(url.URL{
|
||||
Scheme: cpf.PrometheusURIScheme(),
|
||||
Host: c.LocalHost + ":9090",
|
||||
Path: path.Clean(cpf.WebRoutePrefix() + "/api/v1/status/runtimeinfo"),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
reloaderOptions = append(reloaderOptions,
|
||||
operator.ListenLocal(cpf.ListenLocal),
|
||||
operator.LocalHost(c.LocalHost),
|
||||
)
|
||||
reloaderOptions = append(reloaderOptions,
|
||||
operator.ReloaderURL(url.URL{
|
||||
Scheme: cpf.PrometheusURIScheme(),
|
||||
Host: c.LocalHost + ":9090",
|
||||
Path: path.Clean(cpf.WebRoutePrefix() + "/-/reload"),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return operator.CreateConfigReloader(name, reloaderOptions...)
|
||||
}
|
||||
|
||||
func ShareProcessNamespace(p monitoringv1.PrometheusInterface) *bool {
|
||||
return ptr.To(
|
||||
ptr.Deref(
|
||||
p.GetCommonPrometheusFields().ReloadStrategy,
|
||||
monitoringv1.HTTPReloadStrategyType,
|
||||
) == monitoringv1.ProcessSignalReloadStrategyType,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1161,18 +1161,31 @@ func testPromStorageUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func testPromReloadConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCtx := framework.NewTestCtx(t)
|
||||
defer testCtx.Cleanup(t)
|
||||
ns := framework.CreateNamespace(context.Background(), t, testCtx)
|
||||
framework.SetupPrometheusRBAC(context.Background(), t, testCtx, ns)
|
||||
for _, tc := range []struct {
|
||||
reloadStrategy monitoringv1.ReloadStrategyType
|
||||
}{
|
||||
{
|
||||
reloadStrategy: monitoringv1.HTTPReloadStrategyType,
|
||||
},
|
||||
{
|
||||
reloadStrategy: monitoringv1.ProcessSignalReloadStrategyType,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("%s reload strategy", tc.reloadStrategy), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCtx := framework.NewTestCtx(t)
|
||||
defer testCtx.Cleanup(t)
|
||||
ns := framework.CreateNamespace(context.Background(), t, testCtx)
|
||||
framework.SetupPrometheusRBAC(context.Background(), t, testCtx, ns)
|
||||
|
||||
name := "test"
|
||||
p := framework.MakeBasicPrometheus(ns, name, name, 1)
|
||||
p.Spec.ServiceMonitorSelector = nil
|
||||
p.Spec.PodMonitorSelector = nil
|
||||
name := "test"
|
||||
p := framework.MakeBasicPrometheus(ns, name, name, 1)
|
||||
p.Spec.ServiceMonitorSelector = nil
|
||||
p.Spec.PodMonitorSelector = nil
|
||||
p.Spec.ReloadStrategy = ptr.To(tc.reloadStrategy)
|
||||
|
||||
firstConfig := `
|
||||
firstConfig := `
|
||||
global:
|
||||
scrape_interval: 1m
|
||||
scrape_configs:
|
||||
|
@ -1183,43 +1196,43 @@ scrape_configs:
|
|||
- 111.111.111.111:9090
|
||||
`
|
||||
|
||||
var bufOne bytes.Buffer
|
||||
if err := operator.GzipConfig(&bufOne, []byte(firstConfig)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
firstConfigCompressed := bufOne.Bytes()
|
||||
var bufOne bytes.Buffer
|
||||
if err := operator.GzipConfig(&bufOne, []byte(firstConfig)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
firstConfigCompressed := bufOne.Bytes()
|
||||
|
||||
cfg := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("prometheus-%s", name),
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"prometheus.yaml.gz": firstConfigCompressed,
|
||||
"configmaps.json": []byte("{}"),
|
||||
},
|
||||
}
|
||||
cfg := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("prometheus-%s", name),
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"prometheus.yaml.gz": firstConfigCompressed,
|
||||
"configmaps.json": []byte("{}"),
|
||||
},
|
||||
}
|
||||
|
||||
svc := framework.MakePrometheusService(p.Name, "not-relevant", v1.ServiceTypeClusterIP)
|
||||
svc := framework.MakePrometheusService(p.Name, "not-relevant", v1.ServiceTypeClusterIP)
|
||||
|
||||
if _, err := framework.KubeClient.CoreV1().Secrets(ns).Create(context.Background(), cfg, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := framework.KubeClient.CoreV1().Secrets(ns).Create(context.Background(), cfg, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := framework.CreatePrometheusAndWaitUntilReady(context.Background(), ns, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := framework.CreatePrometheusAndWaitUntilReady(context.Background(), ns, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if finalizerFn, err := framework.CreateOrUpdateServiceAndWaitUntilReady(context.Background(), ns, svc); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
testCtx.AddFinalizerFn(finalizerFn)
|
||||
}
|
||||
if finalizerFn, err := framework.CreateOrUpdateServiceAndWaitUntilReady(context.Background(), ns, svc); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
testCtx.AddFinalizerFn(finalizerFn)
|
||||
}
|
||||
|
||||
if err := framework.WaitForActiveTargets(context.Background(), ns, svc.Name, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := framework.WaitForActiveTargets(context.Background(), ns, svc.Name, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
secondConfig := `
|
||||
secondConfig := `
|
||||
global:
|
||||
scrape_interval: 1m
|
||||
scrape_configs:
|
||||
|
@ -1231,24 +1244,26 @@ scrape_configs:
|
|||
- 111.111.111.112:9090
|
||||
`
|
||||
|
||||
var bufTwo bytes.Buffer
|
||||
if err := operator.GzipConfig(&bufTwo, []byte(secondConfig)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
secondConfigCompressed := bufTwo.Bytes()
|
||||
var bufTwo bytes.Buffer
|
||||
if err := operator.GzipConfig(&bufTwo, []byte(secondConfig)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
secondConfigCompressed := bufTwo.Bytes()
|
||||
|
||||
cfg, err := framework.KubeClient.CoreV1().Secrets(ns).Get(context.Background(), cfg.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(fmt.Errorf("could not retrieve previous secret: %w", err))
|
||||
}
|
||||
cfg, err := framework.KubeClient.CoreV1().Secrets(ns).Get(context.Background(), cfg.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(fmt.Errorf("could not retrieve previous secret: %w", err))
|
||||
}
|
||||
|
||||
cfg.Data["prometheus.yaml.gz"] = secondConfigCompressed
|
||||
if _, err := framework.KubeClient.CoreV1().Secrets(ns).Update(context.Background(), cfg, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg.Data["prometheus.yaml.gz"] = secondConfigCompressed
|
||||
if _, err := framework.KubeClient.CoreV1().Secrets(ns).Update(context.Background(), cfg, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := framework.WaitForActiveTargets(context.Background(), ns, svc.Name, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
if err := framework.WaitForActiveTargets(context.Background(), ns, svc.Name, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue