1
0
Fork 0
mirror of https://github.com/prometheus-operator/prometheus-operator.git synced 2025-04-21 03:38:43 +00:00

Merge pull request from brancz/thanos

*: Add Thanos integration
This commit is contained in:
Frederic Branczyk 2018-06-25 09:07:54 +02:00 committed by GitHub
commit 2ef66dc908
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 794 additions and 113 deletions

View file

@ -36,6 +36,9 @@ This Document documents the types introduced by the Prometheus Operator to be co
* [ServiceMonitorSpec](#servicemonitorspec)
* [StorageSpec](#storagespec)
* [TLSConfig](#tlsconfig)
* [ThanosGCSSpec](#thanosgcsspec)
* [ThanosS3Spec](#thanoss3spec)
* [ThanosSpec](#thanosspec)
## AlertingSpec
@ -265,6 +268,7 @@ Specification of the desired behavior of the Prometheus cluster. More info: http
| containers | Containers allows injecting additional containers. This is meant to allow adding an authentication proxy to a Prometheus pod. | []v1.Container | false |
| additionalScrapeConfigs | AdditionalScrapeConfigs allows specifying a key of a Secret containing additional Prometheus scrape configurations. Scrape configurations specified are appended to the configurations generated by the Prometheus Operator. Job configurations specified must have the form as specified in the official Prometheus documentation: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#<scrape_config>. As scrape configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible scrape configs are going to break Prometheus after the upgrade. | *[v1.SecretKeySelector](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#secretkeyselector-v1-core) | false |
| additionalAlertManagerConfigs | AdditionalAlertManagerConfigs allows specifying a key of a Secret containing additional Prometheus AlertManager configurations. AlertManager configurations specified are appended to the configurations generated by the Prometheus Operator. Job configurations specified must have the form as specified in the official Prometheus documentation: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#<alertmanager_config>. As AlertManager configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility to break upgrades of Prometheus. It is advised to review Prometheus release notes to ensure that no incompatible AlertManager configs are going to break Prometheus after the upgrade. | *[v1.SecretKeySelector](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#secretkeyselector-v1-core) | false |
| thanos | Thanos configuration allows configuring various aspects of a Prometheus server in a Thanos environment.\n\nThis section is experimental, it may change significantly without deprecation notice in any release.\n\nThis is experimental and may change significantly without backward compatibility in any release. | *[ThanosSpec](#thanosspec) | false |
[Back to TOC](#table-of-contents)
@ -423,3 +427,42 @@ TLSConfig specifies TLS configuration parameters.
| insecureSkipVerify | Disable target certificate validation. | bool | false |
[Back to TOC](#table-of-contents)
## ThanosGCSSpec
ThanosGCSSpec defines parameters for use of Google Cloud Storage (GCS) with Thanos.
| Field | Description | Scheme | Required |
| ----- | ----------- | ------ | -------- |
| bucket | Google Cloud Storage bucket name for stored blocks. If empty it won't store any block inside Google Cloud Storage. | *string | false |
[Back to TOC](#table-of-contents)
## ThanosS3Spec
ThanosSpec defines parameters for of AWS Simple Storage Service (S3) with Thanos. (S3 compatible services apply as well)
| Field | Description | Scheme | Required |
| ----- | ----------- | ------ | -------- |
| bucket | S3-Compatible API bucket name for stored blocks. | *string | false |
| endpoint | S3-Compatible API endpoint for stored blocks. | *string | false |
| accessKey | AccessKey for an S3-Compatible API. | *[v1.SecretKeySelector](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#secretkeyselector-v1-core) | false |
| secretKey | SecretKey for an S3-Compatible API. | *[v1.SecretKeySelector](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#secretkeyselector-v1-core) | false |
| insecure | Whether to use an insecure connection with an S3-Compatible API. | *bool | false |
| signatureVersion2 | Whether to use S3 Signature Version 2; otherwise Signature Version 4 will be used. | *bool | false |
[Back to TOC](#table-of-contents)
## ThanosSpec
ThanosSpec defines parameters for a Prometheus server within a Thanos deployment.
| Field | Description | Scheme | Required |
| ----- | ----------- | ------ | -------- |
| peers | Peers is a DNS name for Thanos to discover peers through. | *string | false |
| version | Version describes the version of Thanos to use. | *string | false |
| baseImage | Thanos base image if other than default. | *string | false |
| gcs | GCS configures use of GCS in Thanos. | *[ThanosGCSSpec](#thanosgcsspec) | true |
| s3 | S3 configures use of S3 in Thanos. | *[ThanosS3Spec](#thanoss3spec) | true |
[Back to TOC](#table-of-contents)

View file

@ -37,7 +37,7 @@ prometheus-config-reloader:
-ldflags "-X github.com/coreos/prometheus-operator/pkg/version.Version=$(shell cat VERSION)" \
-o $@ cmd/$@/main.go
pkg/client/monitoring/v1/zz_generated.deepcopy.go: $(DEEPCOPY_GEN_BINARY)
pkg/client/monitoring/v1/zz_generated.deepcopy.go: .header pkg/client/monitoring/v1/types.go $(DEEPCOPY_GEN_BINARY)
$(DEEPCOPY_GEN_BINARY) \
-i github.com/coreos/prometheus-operator/pkg/client/monitoring/v1 \
--go-header-file="$(GOPATH)/src/github.com/coreos/prometheus-operator/.header" \
@ -78,7 +78,7 @@ hack/prometheus-config-reloader-image: cmd/prometheus-config-reloader/Dockerfile
##############
.PHONY: generate
generate: Documentation/*
generate: pkg/client/monitoring/v1/zz_generated.deepcopy.go pkg/client/monitoring/v1/openapi_generated.go kube-prometheus Documentation/*
.PHONY: generate-in-docker
generate-in-docker: hack/jsonnet-docker-image

View file

@ -78,6 +78,7 @@ func init() {
flagset.StringVar(&cfg.ConfigReloaderImage, "config-reloader-image", "quay.io/coreos/configmap-reload:v0.0.1", "Reload Image")
flagset.StringVar(&cfg.AlertmanagerDefaultBaseImage, "alertmanager-default-base-image", "quay.io/prometheus/alertmanager", "Alertmanager default base image")
flagset.StringVar(&cfg.PrometheusDefaultBaseImage, "prometheus-default-base-image", "quay.io/prometheus/prometheus", "Prometheus default base image")
flagset.StringVar(&cfg.ThanosDefaultBaseImage, "thanos-default-base-image", "improbable/thanos", "Thanos default base image")
flagset.StringVar(&cfg.Namespace, "namespace", v1.NamespaceAll, "Namespace to scope the interaction of the Prometheus Operator and the apiserver.")
flagset.Var(&cfg.Labels, "labels", "Labels to be add to all resources created by the operator")
flagset.StringVar(&cfg.CrdGroup, "crd-apigroup", monitoringv1.Group, "prometheus CRD API group name")

View file

@ -1,73 +0,0 @@
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: self
labels:
prometheus: self
spec:
podMetadata:
labels:
thanos-peer: 'true'
replicas: 2
version: v2.2.1
serviceAccountName: prometheus-k8s
serviceMonitorSelector:
matchLabels:
app: prometheus
ruleSelector:
matchLabels:
role: prometheus-rulefiles
prometheus: k8s
resources:
requests:
# 2Gi is default, but won't schedule if you don't have a node with >2Gi
# memory. Modify based on your target and time-series count for
# production use. This value is mainly meant for demonstration/testing
# purposes.
memory: 400Mi
containers:
- name: thanos
image: improbable/thanos:latest
args:
- "sidecar"
- "--log.level=debug"
- "--cluster.peers=thanos-peers.default.svc:10900"
ports:
- name: http
containerPort: 10902
- name: grpc
containerPort: 10901
- name: cluster
containerPort: 10900
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: prometheus
labels:
app: prometheus
spec:
selector:
matchLabels:
app: prometheus
endpoints:
- port: web
interval: 30s
---
apiVersion: v1
kind: Service
metadata:
labels:
app: prometheus
prometheus: self
name: prometheus-self
spec:
type: NodePort
ports:
- name: web
nodePort: 30900
port: 9090
protocol: TCP
targetPort: web
selector:
prometheus: self

View file

@ -2673,6 +2673,77 @@ spec:
phase:
description: Phase represents the current phase of PersistentVolumeClaim.
type: string
thanos:
description: ThanosSpec defines parameters for a Prometheus server within
a Thanos deployment.
properties:
baseImage:
description: Thanos base image if other than default.
type: string
gcs:
description: ThanosGCSSpec defines parameters for use of Google
Cloud Storage (GCS) with Thanos.
properties:
bucket:
description: Google Cloud Storage bucket name for stored blocks.
If empty it won't store any block inside Google Cloud Storage.
type: string
peers:
description: Peers is a DNS name for Thanos to discover peers through.
type: string
s3:
description: ThanosSpec defines parameters for of AWS Simple Storage
Service (S3) with Thanos. (S3 compatible services apply as well)
properties:
accessKey:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
optional:
description: Specify whether the Secret or it's key must
be defined
type: boolean
required:
- key
bucket:
description: S3-Compatible API bucket name for stored blocks.
type: string
endpoint:
description: S3-Compatible API endpoint for stored blocks.
type: string
insecure:
description: Whether to use an insecure connection with an S3-Compatible
API.
type: boolean
secretKey:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
optional:
description: Specify whether the Secret or it's key must
be defined
type: boolean
required:
- key
signatureVersion2:
description: Whether to use S3 Signature Version 2; otherwise
Signature Version 4 will be used.
type: boolean
version:
description: Version describes the version of Thanos to use.
type: string
tolerations:
description: If specified, the pod's tolerations.
items:

View file

@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: prometheus-self
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: prometheus-self
subjects:
- kind: ServiceAccount
name: default
namespace: default

View file

@ -0,0 +1,17 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: prometheus-self
namespace: default
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
verbs:
- get
- list
- watch

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: prometheus
prometheus: self
name: prometheus-self
spec:
ports:
- name: web
port: 9090
protocol: TCP
targetPort: web
selector:
prometheus: self

View file

@ -0,0 +1,13 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: prometheus
labels:
app: prometheus
spec:
selector:
matchLabels:
app: prometheus
endpoints:
- port: web
interval: 30s

View file

@ -0,0 +1,20 @@
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: self
labels:
prometheus: self
spec:
podMetadata:
labels:
thanos-peer: 'true'
replicas: 2
serviceMonitorSelector:
matchLabels:
app: prometheus
ruleSelector:
matchLabels:
role: prometheus-rulefiles
prometheus: k8s
thanos:
peers: thanos-peers.default.svc:10900

View file

@ -6,7 +6,7 @@ metadata:
app: thanos-query
thanos-peer: "true"
spec:
replicas: 2
replicas: 1
selector:
matchLabels:
app: thanos-query
@ -19,7 +19,7 @@ spec:
spec:
containers:
- name: thanos-query
image: improbable/thanos:latest
image: improbable/thanos:v0.1.0-rc.1
args:
- "query"
- "--log.level=debug"
@ -31,21 +31,4 @@ spec:
- name: grpc
containerPort: 10901
- name: cluster
containerPort: 10900
---
apiVersion: v1
kind: Service
metadata:
labels:
app: thanos-query
name: thanos-query
spec:
type: NodePort
selector:
app: thanos-query
ports:
- port: 9090
protocol: TCP
targetPort: http
name: http-query
nodePort: 31111
containerPort: 10900

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: thanos-query
name: thanos-query
spec:
selector:
app: thanos-query
ports:
- port: 9090
protocol: TCP
targetPort: http
name: http-query

View file

@ -10,5 +10,4 @@ spec:
port: 10900
targetPort: cluster
selector:
# Useful endpoint for gathering all thanos components for common gossip cluster.
thanos-peer: "true"

File diff suppressed because one or more lines are too long

View file

@ -191,6 +191,7 @@ func UnstructuredFromAlertmanager(a *Alertmanager) (*unstructured.Unstructured,
// necessary anymore.
unstructured.RemoveNestedField(r.Object, "metadata", "creationTimestamp")
unstructured.RemoveNestedField(r.Object, "spec", "storage", "volumeClaimTemplate", "metadata", "creationTimestamp")
unstructured.RemoveNestedField(r.Object, "spec", "podMetadata", "creationTimestamp")
return &r, nil
}

View file

@ -1043,11 +1043,17 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
Ref: ref("k8s.io/api/core/v1.SecretKeySelector"),
},
},
"thanos": {
SchemaProps: spec.SchemaProps{
Description: "Thanos configuration allows configuring various aspects of a Prometheus server in a Thanos environment.\n\nThis section is experimental, it may change significantly without deprecation notice in any release.\n\nThis is experimental and may change significantly without backward compatibility in any release.",
Ref: ref("github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosSpec"),
},
},
},
},
},
Dependencies: []string{
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.AlertingSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.RemoteReadSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.RemoteWriteSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.StorageSpec", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecretKeySelector", "k8s.io/api/core/v1.Toleration", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.AlertingSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.RemoteReadSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.RemoteWriteSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.StorageSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosSpec", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecretKeySelector", "k8s.io/api/core/v1.Toleration", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
},
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.PrometheusStatus": {
Schema: spec.Schema{
@ -1632,6 +1638,118 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
},
Dependencies: []string{},
},
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosGCSSpec": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "ThanosGCSSpec defines parameters for use of Google Cloud Storage (GCS) with Thanos.",
Properties: map[string]spec.Schema{
"bucket": {
SchemaProps: spec.SchemaProps{
Description: "Google Cloud Storage bucket name for stored blocks. If empty it won't store any block inside Google Cloud Storage.",
Type: []string{"string"},
Format: "",
},
},
},
},
},
Dependencies: []string{},
},
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosS3Spec": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "ThanosSpec defines parameters for of AWS Simple Storage Service (S3) with Thanos. (S3 compatible services apply as well)",
Properties: map[string]spec.Schema{
"bucket": {
SchemaProps: spec.SchemaProps{
Description: "S3-Compatible API bucket name for stored blocks.",
Type: []string{"string"},
Format: "",
},
},
"endpoint": {
SchemaProps: spec.SchemaProps{
Description: "S3-Compatible API endpoint for stored blocks.",
Type: []string{"string"},
Format: "",
},
},
"accessKey": {
SchemaProps: spec.SchemaProps{
Description: "AccessKey for an S3-Compatible API.",
Ref: ref("k8s.io/api/core/v1.SecretKeySelector"),
},
},
"secretKey": {
SchemaProps: spec.SchemaProps{
Description: "SecretKey for an S3-Compatible API.",
Ref: ref("k8s.io/api/core/v1.SecretKeySelector"),
},
},
"insecure": {
SchemaProps: spec.SchemaProps{
Description: "Whether to use an insecure connection with an S3-Compatible API.",
Type: []string{"boolean"},
Format: "",
},
},
"signatureVersion2": {
SchemaProps: spec.SchemaProps{
Description: "Whether to use S3 Signature Version 2; otherwise Signature Version 4 will be used.",
Type: []string{"boolean"},
Format: "",
},
},
},
},
},
Dependencies: []string{
"k8s.io/api/core/v1.SecretKeySelector"},
},
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosSpec": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "ThanosSpec defines parameters for a Prometheus server within a Thanos deployment.",
Properties: map[string]spec.Schema{
"peers": {
SchemaProps: spec.SchemaProps{
Description: "Peers is a DNS name for Thanos to discover peers through.",
Type: []string{"string"},
Format: "",
},
},
"version": {
SchemaProps: spec.SchemaProps{
Description: "Version describes the version of Thanos to use.",
Type: []string{"string"},
Format: "",
},
},
"baseImage": {
SchemaProps: spec.SchemaProps{
Description: "Thanos base image if other than default.",
Type: []string{"string"},
Format: "",
},
},
"gcs": {
SchemaProps: spec.SchemaProps{
Description: "GCS configures use of GCS in Thanos.",
Ref: ref("github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosGCSSpec"),
},
},
"s3": {
SchemaProps: spec.SchemaProps{
Description: "S3 configures use of S3 in Thanos.",
Ref: ref("github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosS3Spec"),
},
},
},
},
},
Dependencies: []string{
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosGCSSpec", "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ThanosS3Spec"},
},
"k8s.io/api/core/v1.AWSElasticBlockStoreVolumeSource": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{

View file

@ -190,6 +190,7 @@ func UnstructuredFromPrometheus(p *Prometheus) (*unstructured.Unstructured, erro
// necessary anymore.
unstructured.RemoveNestedField(r.Object, "metadata", "creationTimestamp")
unstructured.RemoveNestedField(r.Object, "spec", "storage", "volumeClaimTemplate", "metadata", "creationTimestamp")
unstructured.RemoveNestedField(r.Object, "spec", "podMetadata", "creationTimestamp")
return &r, nil
}

View file

@ -163,6 +163,15 @@ type PrometheusSpec struct {
// notes to ensure that no incompatible AlertManager configs are going to break
// Prometheus after the upgrade.
AdditionalAlertManagerConfigs *v1.SecretKeySelector `json:"additionalAlertManagerConfigs,omitempty"`
// Thanos configuration allows configuring various aspects of a Prometheus
// server in a Thanos environment.
//
// This section is experimental, it may change significantly without
// deprecation notice in any release.
//
// This is experimental and may change significantly without backward
// compatibility in any release.
Thanos *ThanosSpec `json:"thanos,omitempty"`
}
// Most recent observed status of the Prometheus cluster. Read-only. Not
@ -215,6 +224,48 @@ type StorageSpec struct {
VolumeClaimTemplate v1.PersistentVolumeClaim `json:"volumeClaimTemplate,omitempty"`
}
// ThanosSpec defines parameters for a Prometheus server within a Thanos deployment.
// +k8s:openapi-gen=true
type ThanosSpec struct {
// Peers is a DNS name for Thanos to discover peers through.
Peers *string `json:"peers,omitempty"`
// Version describes the version of Thanos to use.
Version *string `json:"version,omitempty"`
// Thanos base image if other than default.
BaseImage *string `json:"baseImage,omitempty"`
// GCS configures use of GCS in Thanos.
GCS *ThanosGCSSpec `json:"gcs,omitempty"`
// S3 configures use of S3 in Thanos.
S3 *ThanosS3Spec `json:"s3,omitempty"`
}
// ThanosGCSSpec defines parameters for use of Google Cloud Storage (GCS) with
// Thanos.
// +k8s:openapi-gen=true
type ThanosGCSSpec struct {
// Google Cloud Storage bucket name for stored blocks. If empty it won't
// store any block inside Google Cloud Storage.
Bucket *string `json:"bucket,omitempty"`
}
// ThanosSpec defines parameters for of AWS Simple Storage Service (S3) with
// Thanos. (S3 compatible services apply as well)
// +k8s:openapi-gen=true
type ThanosS3Spec struct {
// S3-Compatible API bucket name for stored blocks.
Bucket *string `json:"bucket,omitempty"`
// S3-Compatible API endpoint for stored blocks.
Endpoint *string `json:"endpoint,omitempty"`
// AccessKey for an S3-Compatible API.
AccessKey *v1.SecretKeySelector `json:"accessKey,omitempty"`
// SecretKey for an S3-Compatible API.
SecretKey *v1.SecretKeySelector `json:"secretKey,omitempty"`
// Whether to use an insecure connection with an S3-Compatible API.
Insecure *bool `json:"insecure,omitempty"`
// Whether to use S3 Signature Version 2; otherwise Signature Version 4 will be used.
SignatureVersion2 *bool `json:"signatureVersion2,omitempty"`
}
// RemoteWriteSpec defines the remote_write configuration for prometheus.
// +k8s:openapi-gen=true
type RemoteWriteSpec struct {

View file

@ -671,6 +671,15 @@ func (in *PrometheusSpec) DeepCopyInto(out *PrometheusSpec) {
(*in).DeepCopyInto(*out)
}
}
if in.Thanos != nil {
in, out := &in.Thanos, &out.Thanos
if *in == nil {
*out = nil
} else {
*out = new(ThanosSpec)
(*in).DeepCopyInto(*out)
}
}
return
}
@ -986,3 +995,159 @@ func (in *TLSConfig) DeepCopy() *TLSConfig {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThanosGCSSpec) DeepCopyInto(out *ThanosGCSSpec) {
*out = *in
if in.Bucket != nil {
in, out := &in.Bucket, &out.Bucket
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThanosGCSSpec.
func (in *ThanosGCSSpec) DeepCopy() *ThanosGCSSpec {
if in == nil {
return nil
}
out := new(ThanosGCSSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThanosS3Spec) DeepCopyInto(out *ThanosS3Spec) {
*out = *in
if in.Bucket != nil {
in, out := &in.Bucket, &out.Bucket
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.Endpoint != nil {
in, out := &in.Endpoint, &out.Endpoint
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.AccessKey != nil {
in, out := &in.AccessKey, &out.AccessKey
if *in == nil {
*out = nil
} else {
*out = new(core_v1.SecretKeySelector)
(*in).DeepCopyInto(*out)
}
}
if in.SecretKey != nil {
in, out := &in.SecretKey, &out.SecretKey
if *in == nil {
*out = nil
} else {
*out = new(core_v1.SecretKeySelector)
(*in).DeepCopyInto(*out)
}
}
if in.Insecure != nil {
in, out := &in.Insecure, &out.Insecure
if *in == nil {
*out = nil
} else {
*out = new(bool)
**out = **in
}
}
if in.SignatureVersion2 != nil {
in, out := &in.SignatureVersion2, &out.SignatureVersion2
if *in == nil {
*out = nil
} else {
*out = new(bool)
**out = **in
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThanosS3Spec.
func (in *ThanosS3Spec) DeepCopy() *ThanosS3Spec {
if in == nil {
return nil
}
out := new(ThanosS3Spec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThanosSpec) DeepCopyInto(out *ThanosSpec) {
*out = *in
if in.Peers != nil {
in, out := &in.Peers, &out.Peers
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.Version != nil {
in, out := &in.Version, &out.Version
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.BaseImage != nil {
in, out := &in.BaseImage, &out.BaseImage
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.GCS != nil {
in, out := &in.GCS, &out.GCS
if *in == nil {
*out = nil
} else {
*out = new(ThanosGCSSpec)
(*in).DeepCopyInto(*out)
}
}
if in.S3 != nil {
in, out := &in.S3, &out.S3
if *in == nil {
*out = nil
} else {
*out = new(ThanosS3Spec)
(*in).DeepCopyInto(*out)
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThanosSpec.
func (in *ThanosSpec) DeepCopy() *ThanosSpec {
if in == nil {
return nil
}
out := new(ThanosSpec)
in.DeepCopyInto(out)
return out
}

View file

@ -128,6 +128,7 @@ type Config struct {
PrometheusConfigReloader string
AlertmanagerDefaultBaseImage string
PrometheusDefaultBaseImage string
ThanosDefaultBaseImage string
Namespace string
Labels Labels
CrdGroup string

View file

@ -89,7 +89,7 @@ func buildExternalLabels(p *v1.Prometheus) yaml.MapSlice {
func generateConfig(p *v1.Prometheus, mons map[string]*v1.ServiceMonitor, basicAuthSecrets map[string]BasicAuthCredentials, additionalScrapeConfigs []byte, additionalAlertManagerConfigs []byte) ([]byte, error) {
versionStr := p.Spec.Version
if versionStr == "" {
versionStr = DefaultVersion
versionStr = DefaultPrometheusVersion
}
version, err := semver.Parse(strings.TrimLeft(versionStr, "v"))

View file

@ -32,17 +32,18 @@ import (
)
const (
governingServiceName = "prometheus-operated"
DefaultVersion = "v2.2.1"
defaultRetention = "24h"
storageDir = "/prometheus"
confDir = "/etc/prometheus/config"
confOutDir = "/etc/prometheus/config_out"
rulesDir = "/etc/prometheus/rules"
secretsDir = "/etc/prometheus/secrets/"
configFilename = "prometheus.yaml"
configEnvsubstFilename = "prometheus.env.yaml"
sSetInputChecksumName = "prometheus-operator-input-checksum"
governingServiceName = "prometheus-operated"
DefaultPrometheusVersion = "v2.2.1"
DefaultThanosVersion = "v0.1.0-rc.1"
defaultRetention = "24h"
storageDir = "/prometheus"
confDir = "/etc/prometheus/config"
confOutDir = "/etc/prometheus/config_out"
rulesDir = "/etc/prometheus/rules"
secretsDir = "/etc/prometheus/secrets/"
configFilename = "prometheus.yaml"
configEnvsubstFilename = "prometheus.env.yaml"
sSetInputChecksumName = "prometheus-operator-input-checksum"
)
var (
@ -88,7 +89,11 @@ func makeStatefulSet(
p.Spec.BaseImage = config.PrometheusDefaultBaseImage
}
if p.Spec.Version == "" {
p.Spec.Version = DefaultVersion
p.Spec.Version = DefaultPrometheusVersion
}
if p.Spec.Thanos != nil && p.Spec.Thanos.Version == nil {
v := DefaultThanosVersion
p.Spec.Thanos.Version = &v
}
versionStr := strings.TrimLeft(p.Spec.Version, "v")
@ -542,6 +547,86 @@ func makeStatefulSetSpec(p monitoringv1.Prometheus, c *Config) (*appsv1.Stateful
finalLabels := c.Labels.Merge(podLabels)
additionalContainers := p.Spec.Containers
if p.Spec.Thanos != nil {
thanosBaseImage := c.ThanosDefaultBaseImage
if p.Spec.Thanos.BaseImage != nil {
thanosBaseImage = *p.Spec.Thanos.BaseImage
}
thanosArgs := []string{"sidecar"}
if p.Spec.Thanos.Peers != nil {
thanosArgs = append(thanosArgs, fmt.Sprintf("--cluster.peers=%s", *p.Spec.Thanos.Peers))
}
if p.Spec.LogLevel != "" && p.Spec.LogLevel != "info" {
thanosArgs = append(thanosArgs, fmt.Sprintf("--log.level=%s", p.Spec.LogLevel))
}
if p.Spec.Thanos.GCS != nil {
if p.Spec.Thanos.GCS.Bucket != nil {
thanosArgs = append(thanosArgs, fmt.Sprintf("--gcs.bucket=%s", *p.Spec.Thanos.GCS.Bucket))
}
}
envVars := []v1.EnvVar{}
if p.Spec.Thanos.S3 != nil {
if p.Spec.Thanos.S3.Bucket != nil {
thanosArgs = append(thanosArgs, fmt.Sprintf("--s3.bucket=%s", *p.Spec.Thanos.S3.Bucket))
}
if p.Spec.Thanos.S3.Endpoint != nil {
thanosArgs = append(thanosArgs, fmt.Sprintf("--s3.endpoint=%s", *p.Spec.Thanos.S3.Endpoint))
}
if p.Spec.Thanos.S3.Insecure != nil && *p.Spec.Thanos.S3.Insecure {
thanosArgs = append(thanosArgs, "--s3.insecure")
}
if p.Spec.Thanos.S3.SignatureVersion2 != nil && *p.Spec.Thanos.S3.SignatureVersion2 {
thanosArgs = append(thanosArgs, "--s3.signature-version2")
}
if p.Spec.Thanos.S3.AccessKey != nil {
envVars = append(envVars, v1.EnvVar{
Name: "S3_ACCESS_KEY",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: p.Spec.Thanos.S3.AccessKey,
},
})
}
if p.Spec.Thanos.S3.SecretKey != nil {
envVars = append(envVars, v1.EnvVar{
Name: "S3_SECRET_KEY",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: p.Spec.Thanos.S3.SecretKey,
},
})
}
}
c := v1.Container{
Name: "thanos-sidecar",
Image: thanosBaseImage + ":" + *p.Spec.Thanos.Version,
Args: thanosArgs,
Ports: []v1.ContainerPort{
{
Name: "http",
ContainerPort: 10902,
},
{
Name: "grpc",
ContainerPort: 10901,
},
{
Name: "cluster",
ContainerPort: 10900,
},
},
Env: envVars,
}
additionalContainers = append(additionalContainers, c)
promArgs = append(promArgs, "--storage.tsdb.min-block-duration=2h", "--storage.tsdb.max-block-duration=2h")
}
return &appsv1.StatefulSetSpec{
ServiceName: governingServiceName,
Replicas: p.Spec.Replicas,
@ -610,7 +695,7 @@ func makeStatefulSetSpec(p monitoringv1.Prometheus, c *Config) (*appsv1.Stateful
},
},
},
}, p.Spec.Containers...),
}, additionalContainers...),
SecurityContext: securityContext,
ServiceAccountName: p.Spec.ServiceAccountName,
NodeSelector: p.Spec.NodeSelector,

View file

@ -1070,6 +1070,107 @@ func TestPromOpMatchPromAndServMonInDiffNSs(t *testing.T) {
}
}
func TestThanos(t *testing.T) {
t.Parallel()
ctx := framework.NewTestCtx(t)
defer ctx.Cleanup(t)
ns := ctx.CreateNamespace(t, framework.KubeClient)
ctx.SetupPrometheusRBAC(t, ns, framework.KubeClient)
peerServiceName := "thanos-peers"
querierServiceName := "thanos-querier"
basicPrometheus := framework.MakeBasicPrometheus(ns, "basic-prometheus", "test-group", 1)
peerServiceDNS := fmt.Sprintf("%s.%s.svc:10900", peerServiceName, ns)
version := "v0.1.0-rc.1"
basicPrometheus.Spec.Thanos = &monitoringv1.ThanosSpec{
Peers: &peerServiceDNS,
Version: &version,
}
basicPrometheus.Spec.PodMetadata = &metav1.ObjectMeta{
Labels: map[string]string{
"thanos-peer": "true",
},
}
replicas := int32(2)
basicPrometheus.Spec.Replicas = &replicas
pservice := framework.MakePrometheusService(basicPrometheus.Name, "test-group", v1.ServiceTypeClusterIP)
tservice := framework.MakeThanosService(peerServiceName)
qservice := framework.MakeThanosQuerierService(querierServiceName)
s := framework.MakeBasicServiceMonitor("test-group")
thanosQuerier, err := testFramework.MakeDeployment("../../example/thanos/querier-deployment.yaml")
if err != nil {
t.Fatal("Making deployment failed: ", err)
}
querierArgs := []string{
"query",
"--log.level=debug",
"--query.replica-label=prometheus_replica",
fmt.Sprintf("--cluster.peers=%s", peerServiceDNS),
}
log.Println("setting up querier with args: ", querierArgs)
thanosQuerier.Spec.Template.Spec.Containers[0].Args = querierArgs
if err := testFramework.CreateDeployment(framework.KubeClient, ns, thanosQuerier); err != nil {
t.Fatal("Creating Thanos querier failed: ", err)
}
if _, err := testFramework.CreateServiceAndWaitUntilReady(framework.KubeClient, ns, qservice); err != nil {
t.Fatal("Creating Thanos querier service failed: ", err)
}
if _, err := framework.MonClientV1.ServiceMonitors(ns).Create(s); err != nil {
t.Fatal("Creating ServiceMonitor failed: ", err)
}
if _, err := framework.KubeClient.CoreV1().Services(ns).Create(pservice); err != nil {
t.Fatal("Creating prometheus service failed: ", err)
}
if _, err := framework.MonClientV1.Prometheuses(ns).Create(basicPrometheus); err != nil {
t.Fatal("Creating prometheus failed: ", err)
}
if _, err := framework.KubeClient.CoreV1().Services(ns).Create(tservice); err != nil {
t.Fatal("Creating prometheus service failed: ", err)
}
err = wait.Poll(5*time.Second, 5*time.Minute, func() (bool, error) {
proxyGet := framework.KubeClient.CoreV1().Services(ns).ProxyGet
request := proxyGet("http", querierServiceName, "http-query", "/api/v1/query", map[string]string{"query": "prometheus_build_info", "dedup": "false"})
b, err := request.DoRaw()
if err != nil {
log.Println(fmt.Sprintf("Error performing request against Thanos querier: %v\n\nretrying...", err))
return false, nil
}
d := struct {
Data struct {
Result []map[string]interface{} `json:"result"`
} `json:"data"`
}{}
err = json.Unmarshal(b, &d)
if err != nil {
return false, err
}
result := len(d.Data.Result)
// We're expecting 4 results as we are requesting the
// `prometheus_build_info` metric, which is collected for both
// Prometheus replicas by both replicas.
expected := 4
if result != expected {
log.Printf("Unexpected number of results from query. Got %d, expected %d. retrying...\n", result, expected)
return false, nil
}
return true, nil
})
if err != nil {
t.Fatal("Failed to get correct result from Thanos querier: ", err)
}
}
func isDiscoveryWorking(ns, svcName, prometheusName string) func() (bool, error) {
return func() (bool, error) {
pods, err := framework.KubeClient.CoreV1().Pods(ns).List(prometheus.ListOptions(prometheusName))

View file

@ -41,7 +41,7 @@ func (f *Framework) MakeBasicPrometheus(ns, name, group string, replicas int32)
},
Spec: monitoringv1.PrometheusSpec{
Replicas: &replicas,
Version: prometheus.DefaultVersion,
Version: prometheus.DefaultPrometheusVersion,
ServiceMonitorSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"group": group,
@ -147,6 +147,48 @@ func (f *Framework) MakePrometheusService(name, group string, serviceType v1.Ser
return service
}
func (f *Framework) MakeThanosQuerierService(name string) *v1.Service {
service := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
v1.ServicePort{
Name: "http-query",
Port: 10902,
TargetPort: intstr.FromString("http"),
},
},
Selector: map[string]string{
"app": "thanos-query",
},
},
}
return service
}
func (f *Framework) MakeThanosService(name string) *v1.Service {
service := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
v1.ServicePort{
Name: "cluster",
Port: 10900,
TargetPort: intstr.FromString("cluster"),
},
},
Selector: map[string]string{
"thanos-peer": "true",
},
},
}
return service
}
func (f *Framework) CreatePrometheusAndWaitUntilReady(ns string, p *monitoringv1.Prometheus) error {
_, err := f.MonClientV1.Prometheuses(ns).Create(p)
if err != nil {