feat: add logging via vector + loki
diff --git a/charts/loki/.helmignore b/charts/loki/.helmignore
new file mode 100644
index 0000000..6d90723
--- /dev/null
+++ b/charts/loki/.helmignore
@@ -0,0 +1,32 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
+
+# Other
+doc.yaml
+README.tpl
+README.md.gotmpl
+ci
+CHANGELOG.md
diff --git a/charts/loki/Chart.lock b/charts/loki/Chart.lock
new file mode 100644
index 0000000..547f0f0
--- /dev/null
+++ b/charts/loki/Chart.lock
@@ -0,0 +1,9 @@
+dependencies:
+- name: minio
+ repository: https://charts.min.io/
+ version: 4.0.12
+- name: grafana-agent-operator
+ repository: https://grafana.github.io/helm-charts
+ version: 0.2.3
+digest: sha256:74ef214ca08874662ab403a2e5eea39df26ad690962fa19f9ff69cf551550ff2
+generated: "2022-09-14T10:22:56.1397723-06:00"
diff --git a/charts/loki/Chart.yaml b/charts/loki/Chart.yaml
new file mode 100644
index 0000000..cf8817b
--- /dev/null
+++ b/charts/loki/Chart.yaml
@@ -0,0 +1,26 @@
+apiVersion: v2
+appVersion: 2.7.3
+dependencies:
+- alias: minio
+ condition: minio.enabled
+ name: minio
+ repository: https://charts.min.io/
+ version: 4.0.12
+- alias: grafana-agent-operator
+ condition: monitoring.selfMonitoring.grafanaAgent.installOperator
+ name: grafana-agent-operator
+ repository: https://grafana.github.io/helm-charts
+ version: 0.2.3
+description: Helm chart for Grafana Loki in simple, scalable mode
+home: https://grafana.github.io/helm-charts
+icon: https://grafana.com/docs/loki/latest/logo_and_name.png
+maintainers:
+- name: trevorwhitney
+- name: jeschkies
+name: loki
+sources:
+- https://github.com/grafana/loki
+- https://grafana.com/oss/loki/
+- https://grafana.com/docs/loki/latest/
+type: application
+version: 4.6.1
diff --git a/charts/loki/README.md b/charts/loki/README.md
new file mode 100644
index 0000000..6f908a7
--- /dev/null
+++ b/charts/loki/README.md
@@ -0,0 +1,20 @@
+# loki
+
+  
+
+Helm chart for Grafana Loki in simple, scalable mode
+
+## Source Code
+
+* <https://github.com/grafana/loki>
+* <https://grafana.com/oss/loki/>
+* <https://grafana.com/docs/loki/latest/>
+
+## Requirements
+
+| Repository | Name | Version |
+|------------|------|---------|
+| https://charts.min.io/ | minio(minio) | 4.0.12 |
+| https://grafana.github.io/helm-charts | grafana-agent-operator(grafana-agent-operator) | 0.2.3 |
+
+Find more information in the Loki Helm Chart [documentation](https://grafana.com/docs/loki/next/installation/helm).
diff --git a/charts/loki/charts/grafana-agent-operator/.helmignore b/charts/loki/charts/grafana-agent-operator/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/loki/charts/grafana-agent-operator/Chart.yaml b/charts/loki/charts/grafana-agent-operator/Chart.yaml
new file mode 100644
index 0000000..c302ca5
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/Chart.yaml
@@ -0,0 +1,13 @@
+apiVersion: v2
+appVersion: 0.25.1
+description: A Helm chart for Grafana Agent Operator
+home: https://grafana.com/docs/agent/latest/
+icon: https://raw.githubusercontent.com/grafana/agent/v0.25.1/docs/assets/logo_and_name.png
+maintainers:
+- email: grafana-agent-team@googlegroups.com
+ name: Grafana Agent Team
+name: grafana-agent-operator
+sources:
+- https://github.com/grafana/agent/tree/v0.25.1/pkg/operator
+type: application
+version: 0.2.3
diff --git a/charts/loki/charts/grafana-agent-operator/README.md b/charts/loki/charts/grafana-agent-operator/README.md
new file mode 100644
index 0000000..5a05193
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/README.md
@@ -0,0 +1,75 @@
+# grafana-agent-operator
+
+  
+
+A Helm chart for Grafana Agent Operator
+
+⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.**
+
+## Source Code
+
+* <https://github.com/grafana/agent/tree/v0.25.1/pkg/operator>
+
+Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources.
+
+To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/).
+
+## CRDs
+
+The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/production/operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs.
+
+## Get Repo Info
+
+```console
+helm repo add grafana https://grafana.github.io/helm-charts
+helm repo update
+```
+
+_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._
+
+## Installing the Chart
+
+To install the chart with the release name `my-release`:
+
+```console
+helm install my-release grafana/grafana-agent-operator
+```
+
+## Uninstalling the Chart
+
+To uninstall/delete the my-release deployment:
+
+```console
+helm delete my-release
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Upgrading an existing Release to a new major version
+
+A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility.
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| affinity | object | `{}` | Pod affinity configuration |
+| annotations | object | `{}` | Annotations for the Deployment |
+| extraArgs | list | `[]` | List of additional cli arguments to configure agent-operator (example: `--log.level`) |
+| fullnameOverride | string | `""` | Overrides the chart's computed fullname |
+| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy |
+| image.pullSecrets | list | `[]` | Image pull secrets |
+| image.registry | string | `"docker.io"` | Image registry |
+| image.repository | string | `"grafana/agent-operator"` | Image repo |
+| image.tag | string | `"v0.25.1"` | Image tag |
+| kubeletService | object | `{"namespace":"default","serviceName":"kubelet"}` | If both are set, Agent Operator will create and maintain a service for scraping kubelets https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets |
+| nameOverride | string | `""` | Overrides the chart's name |
+| nodeSelector | object | `{}` | nodeSelector configuration |
+| podAnnotations | object | `{}` | Annotations for the Deployment Pods |
+| podLabels | object | `{}` | Annotations for the Deployment Pods |
+| podSecurityContext | object | `{}` | Pod security context (runAsUser, etc.) |
+| rbac | object | `{"create":true}` | Toggle to create ClusterRole and ClusterRoleBinding |
+| resources | object | `{}` | Resource limits and requests config |
+| serviceAccount.create | bool | `true` | Toggle to create ServiceAccount |
+| serviceAccount.name | string | `nil` | Service account name |
+| tolerations | list | `[]` | Tolerations applied to Pods |
diff --git a/charts/loki/charts/grafana-agent-operator/README.md.gotmpl b/charts/loki/charts/grafana-agent-operator/README.md.gotmpl
new file mode 100644
index 0000000..5b08d32
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/README.md.gotmpl
@@ -0,0 +1,52 @@
+{{ template "chart.header" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+{{ template "chart.description" . }}
+
+⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.**
+
+{{ template "chart.sourcesSection" . }}
+
+{{ template "chart.requirementsSection" . }}
+
+Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources.
+
+To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/).
+
+## CRDs
+
+The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/production/operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs.
+
+## Get Repo Info
+
+```console
+helm repo add grafana https://grafana.github.io/helm-charts
+helm repo update
+```
+
+_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._
+
+## Installing the Chart
+
+To install the chart with the release name `my-release`:
+
+```console
+helm install my-release grafana/grafana-agent-operator
+```
+
+## Uninstalling the Chart
+
+To uninstall/delete the my-release deployment:
+
+```console
+helm delete my-release
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Upgrading an existing Release to a new major version
+
+A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility.
+
+{{ template "chart.valuesSection" . }}
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml
new file mode 100644
index 0000000..825a2da
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml
@@ -0,0 +1,612 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: podmonitors.monitoring.coreos.com
+spec:
+ group: monitoring.coreos.com
+ names:
+ categories:
+ - prometheus-operator
+ kind: PodMonitor
+ listKind: PodMonitorList
+ plural: podmonitors
+ singular: podmonitor
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: PodMonitor defines monitoring for a set of pods.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specification of desired Pod selection for target discovery
+ by Prometheus.
+ properties:
+ jobLabel:
+ description: The label to use to retrieve the job name from.
+ type: string
+ labelLimit:
+ description: Per-scrape limit on number of labels that will be accepted
+ for a sample. Only valid in Prometheus versions 2.27.0 and newer.
+ format: int64
+ type: integer
+ labelNameLengthLimit:
+ description: Per-scrape limit on length of labels name that will be
+ accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ labelValueLengthLimit:
+ description: Per-scrape limit on length of labels value that will
+ be accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ namespaceSelector:
+ description: Selector to select which namespaces the Endpoints objects
+ are discovered from.
+ properties:
+ any:
+ description: Boolean describing whether all namespaces are selected
+ in contrast to a list restricting them.
+ type: boolean
+ matchNames:
+ description: List of namespace names to select from.
+ items:
+ type: string
+ type: array
+ type: object
+ podMetricsEndpoints:
+ description: A list of endpoints allowed as part of this PodMonitor.
+ items:
+ description: PodMetricsEndpoint defines a scrapeable endpoint of
+ a Kubernetes Pod serving Prometheus metrics.
+ properties:
+ authorization:
+ description: Authorization section for this endpoint
+ properties:
+ credentials:
+ description: The secret's key that contains the credentials
+ of the request
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type:
+ description: Set the authentication type. Defaults to Bearer,
+ Basic will cause an error
+ type: string
+ type: object
+ basicAuth:
+ description: 'BasicAuth allow an endpoint to authenticate over
+ basic authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint'
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerTokenSecret:
+ description: Secret to mount to read bearer token for scraping
+ targets. The secret needs to be in the same namespace as the
+ pod monitor and accessible by the Prometheus Operator.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ followRedirects:
+ description: FollowRedirects configures whether scrape requests
+ follow HTTP 3xx redirects.
+ type: boolean
+ honorLabels:
+ description: HonorLabels chooses the metric's labels on collisions
+ with target labels.
+ type: boolean
+ honorTimestamps:
+ description: HonorTimestamps controls whether Prometheus respects
+ the timestamps present in scraped data.
+ type: boolean
+ interval:
+ description: Interval at which metrics should be scraped
+ type: string
+ metricRelabelings:
+ description: MetricRelabelConfigs to apply to samples before
+ ingestion.
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the
+ label set, being applied to samples before ingestion. It
+ defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex
+ capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name
+ which may only contain ASCII letters, numbers, as
+ well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ oauth2:
+ description: OAuth2 for the URL. Only valid in Prometheus versions
+ 2.27.0 and newer.
+ properties:
+ clientId:
+ description: The secret or configmap containing the OAuth2
+ client id
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ clientSecret:
+ description: The secret containing the OAuth2 client 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ endpointParams:
+ additionalProperties:
+ type: string
+ description: Parameters to append to the token URL
+ type: object
+ scopes:
+ description: OAuth2 scopes used for the token request
+ items:
+ type: string
+ type: array
+ tokenUrl:
+ description: The URL to fetch the token from
+ minLength: 1
+ type: string
+ required:
+ - clientId
+ - clientSecret
+ - tokenUrl
+ type: object
+ params:
+ additionalProperties:
+ items:
+ type: string
+ type: array
+ description: Optional HTTP URL parameters
+ type: object
+ path:
+ description: HTTP path to scrape for metrics.
+ type: string
+ port:
+ description: Name of the pod port this endpoint refers to. Mutually
+ exclusive with targetPort.
+ type: string
+ proxyUrl:
+ description: ProxyURL eg http://proxyserver:2195 Directs scrapes
+ to proxy through this endpoint.
+ type: string
+ relabelings:
+ description: 'RelabelConfigs to apply to samples before scraping.
+ Prometheus Operator automatically adds relabelings for a few
+ standard Kubernetes fields. The original scrape job''s name
+ is available via the `__tmp_prometheus_job_name` label. More
+ info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config'
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the
+ label set, being applied to samples before ingestion. It
+ defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex
+ capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name
+ which may only contain ASCII letters, numbers, as
+ well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ scheme:
+ description: HTTP scheme to use for scraping.
+ type: string
+ scrapeTimeout:
+ description: Timeout after which the scrape is ended
+ type: string
+ targetPort:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'Deprecated: Use ''port'' instead.'
+ x-kubernetes-int-or-string: true
+ tlsConfig:
+ description: TLS configuration to use when scraping the endpoint.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ cert:
+ description: Struct containing the client cert file for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keySecret:
+ description: Secret containing the client key file for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ type: object
+ type: array
+ podTargetLabels:
+ description: PodTargetLabels transfers labels on the Kubernetes Pod
+ onto the target.
+ items:
+ type: string
+ type: array
+ sampleLimit:
+ description: SampleLimit defines per-scrape limit on number of scraped
+ samples that will be accepted.
+ format: int64
+ type: integer
+ selector:
+ description: Selector to select Pod objects.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ targetLimit:
+ description: TargetLimit defines a limit on the number of scraped
+ targets that will be accepted.
+ format: int64
+ type: integer
+ required:
+ - podMetricsEndpoints
+ - selector
+ type: object
+ required:
+ - spec
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml
new file mode 100644
index 0000000..259f5a4
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml
@@ -0,0 +1,654 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: probes.monitoring.coreos.com
+spec:
+ group: monitoring.coreos.com
+ names:
+ categories:
+ - prometheus-operator
+ kind: Probe
+ listKind: ProbeList
+ plural: probes
+ singular: probe
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: Probe defines monitoring for a set of static targets or ingresses.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specification of desired Ingress selection for target discovery
+ by Prometheus.
+ properties:
+ authorization:
+ description: Authorization section for this endpoint
+ properties:
+ credentials:
+ description: The secret's key that contains the credentials of
+ the request
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type:
+ description: Set the authentication type. Defaults to Bearer,
+ Basic will cause an error
+ type: string
+ type: object
+ basicAuth:
+ description: 'BasicAuth allow an endpoint to authenticate over basic
+ authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint'
+ properties:
+ password:
+ description: The secret in the service monitor namespace that
+ contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace that
+ contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerTokenSecret:
+ description: Secret to mount to read bearer token for scraping targets.
+ The secret needs to be in the same namespace as the probe and accessible
+ by the Prometheus Operator.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ interval:
+ description: Interval at which targets are probed using the configured
+ prober. If not specified Prometheus' global scrape interval is used.
+ type: string
+ jobName:
+ description: The job name assigned to scraped metrics by default.
+ type: string
+ labelLimit:
+ description: Per-scrape limit on number of labels that will be accepted
+ for a sample. Only valid in Prometheus versions 2.27.0 and newer.
+ format: int64
+ type: integer
+ labelNameLengthLimit:
+ description: Per-scrape limit on length of labels name that will be
+ accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ labelValueLengthLimit:
+ description: Per-scrape limit on length of labels value that will
+ be accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ metricRelabelings:
+ description: MetricRelabelConfigs to apply to samples before ingestion.
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the label
+ set, being applied to samples before ingestion. It defines `<metric_relabel_configs>`-section
+ of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching. Default
+ is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source label
+ values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex capture
+ groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source label
+ values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing labels.
+ Their content is concatenated using the configured separator
+ and matched against the configured regular expression for
+ the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name which
+ may only contain ASCII letters, numbers, as well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written in
+ a replace action. It is mandatory for replace actions. Regex
+ capture groups are available.
+ type: string
+ type: object
+ type: array
+ module:
+ description: 'The module to use for probing specifying how to probe
+ the target. Example module configuring in the blackbox exporter:
+ https://github.com/prometheus/blackbox_exporter/blob/master/example.yml'
+ type: string
+ oauth2:
+ description: OAuth2 for the URL. Only valid in Prometheus versions
+ 2.27.0 and newer.
+ properties:
+ clientId:
+ description: The secret or configmap containing the OAuth2 client
+ id
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ clientSecret:
+ description: The secret containing the OAuth2 client 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ endpointParams:
+ additionalProperties:
+ type: string
+ description: Parameters to append to the token URL
+ type: object
+ scopes:
+ description: OAuth2 scopes used for the token request
+ items:
+ type: string
+ type: array
+ tokenUrl:
+ description: The URL to fetch the token from
+ minLength: 1
+ type: string
+ required:
+ - clientId
+ - clientSecret
+ - tokenUrl
+ type: object
+ prober:
+ description: Specification for the prober to use for probing targets.
+ The prober.URL parameter is required. Targets cannot be probed if
+ left empty.
+ properties:
+ path:
+ description: Path to collect metrics from. Defaults to `/probe`.
+ type: string
+ proxyUrl:
+ description: Optional ProxyURL.
+ type: string
+ scheme:
+ description: HTTP scheme to use for scraping. Defaults to `http`.
+ type: string
+ url:
+ description: Mandatory URL of the prober.
+ type: string
+ required:
+ - url
+ type: object
+ sampleLimit:
+ description: SampleLimit defines per-scrape limit on number of scraped
+ samples that will be accepted.
+ format: int64
+ type: integer
+ scrapeTimeout:
+ description: Timeout for scraping metrics from the Prometheus exporter.
+ type: string
+ targetLimit:
+ description: TargetLimit defines a limit on the number of scraped
+ targets that will be accepted.
+ format: int64
+ type: integer
+ targets:
+ description: Targets defines a set of static or dynamically discovered
+ targets to probe.
+ properties:
+ ingress:
+ description: ingress defines the Ingress objects to probe and
+ the relabeling configuration. If `staticConfig` is also defined,
+ `staticConfig` takes precedence.
+ properties:
+ namespaceSelector:
+ description: From which namespaces to select Ingress objects.
+ properties:
+ any:
+ description: Boolean describing whether all namespaces
+ are selected in contrast to a list restricting them.
+ type: boolean
+ matchNames:
+ description: List of namespace names to select from.
+ items:
+ type: string
+ type: array
+ type: object
+ relabelingConfigs:
+ description: 'RelabelConfigs to apply to the label set of
+ the target before it gets scraped. The original ingress
+ address is available via the `__tmp_prometheus_ingress_address`
+ label. It can be used to customize the probed URL. The original
+ scrape job''s name is available via the `__tmp_prometheus_job_name`
+ label. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config'
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of
+ the label set, being applied to samples before ingestion.
+ It defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex
+ replace is performed if the regular expression matches.
+ Regex capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label
+ name which may only contain ASCII letters, numbers,
+ as well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ selector:
+ description: Selector to select the Ingress objects.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values.
+ If the operator is In or NotIn, the values array
+ must be non-empty. If the operator is Exists or
+ DoesNotExist, the values array must be empty.
+ This array is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs.
+ A single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is
+ "key", the operator is "In", and the values array contains
+ only "value". The requirements are ANDed.
+ type: object
+ type: object
+ type: object
+ staticConfig:
+ description: 'staticConfig defines the static list of targets
+ to probe and the relabeling configuration. If `ingress` is also
+ defined, `staticConfig` takes precedence. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.'
+ properties:
+ labels:
+ additionalProperties:
+ type: string
+ description: Labels assigned to all metrics scraped from the
+ targets.
+ type: object
+ relabelingConfigs:
+ description: 'RelabelConfigs to apply to the label set of
+ the targets before it gets scraped. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config'
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of
+ the label set, being applied to samples before ingestion.
+ It defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex
+ replace is performed if the regular expression matches.
+ Regex capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label
+ name which may only contain ASCII letters, numbers,
+ as well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ static:
+ description: The list of hosts to probe.
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ tlsConfig:
+ description: TLS configuration to use when scraping the endpoint.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ cert:
+ description: Struct containing the client cert file for the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keySecret:
+ description: Secret containing the client key file for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ type: object
+ required:
+ - spec
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml
new file mode 100644
index 0000000..8f8f8ae
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml
@@ -0,0 +1,638 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: servicemonitors.monitoring.coreos.com
+spec:
+ group: monitoring.coreos.com
+ names:
+ categories:
+ - prometheus-operator
+ kind: ServiceMonitor
+ listKind: ServiceMonitorList
+ plural: servicemonitors
+ singular: servicemonitor
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: ServiceMonitor defines monitoring for a set of services.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specification of desired Service selection for target discovery
+ by Prometheus.
+ properties:
+ endpoints:
+ description: A list of endpoints allowed as part of this ServiceMonitor.
+ items:
+ description: Endpoint defines a scrapeable endpoint serving Prometheus
+ metrics.
+ properties:
+ authorization:
+ description: Authorization section for this endpoint
+ properties:
+ credentials:
+ description: The secret's key that contains the credentials
+ of the request
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type:
+ description: Set the authentication type. Defaults to Bearer,
+ Basic will cause an error
+ type: string
+ type: object
+ basicAuth:
+ description: 'BasicAuth allow an endpoint to authenticate over
+ basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints'
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerTokenFile:
+ description: File to read bearer token for scraping targets.
+ type: string
+ bearerTokenSecret:
+ description: Secret to mount to read bearer token for scraping
+ targets. The secret needs to be in the same namespace as the
+ service monitor and accessible by the Prometheus Operator.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ followRedirects:
+ description: FollowRedirects configures whether scrape requests
+ follow HTTP 3xx redirects.
+ type: boolean
+ honorLabels:
+ description: HonorLabels chooses the metric's labels on collisions
+ with target labels.
+ type: boolean
+ honorTimestamps:
+ description: HonorTimestamps controls whether Prometheus respects
+ the timestamps present in scraped data.
+ type: boolean
+ interval:
+ description: Interval at which metrics should be scraped
+ type: string
+ metricRelabelings:
+ description: MetricRelabelConfigs to apply to samples before
+ ingestion.
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the
+ label set, being applied to samples before ingestion. It
+ defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex
+ capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name
+ which may only contain ASCII letters, numbers, as
+ well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ oauth2:
+ description: OAuth2 for the URL. Only valid in Prometheus versions
+ 2.27.0 and newer.
+ properties:
+ clientId:
+ description: The secret or configmap containing the OAuth2
+ client id
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ clientSecret:
+ description: The secret containing the OAuth2 client 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ endpointParams:
+ additionalProperties:
+ type: string
+ description: Parameters to append to the token URL
+ type: object
+ scopes:
+ description: OAuth2 scopes used for the token request
+ items:
+ type: string
+ type: array
+ tokenUrl:
+ description: The URL to fetch the token from
+ minLength: 1
+ type: string
+ required:
+ - clientId
+ - clientSecret
+ - tokenUrl
+ type: object
+ params:
+ additionalProperties:
+ items:
+ type: string
+ type: array
+ description: Optional HTTP URL parameters
+ type: object
+ path:
+ description: HTTP path to scrape for metrics.
+ type: string
+ port:
+ description: Name of the service port this endpoint refers to.
+ Mutually exclusive with targetPort.
+ type: string
+ proxyUrl:
+ description: ProxyURL eg http://proxyserver:2195 Directs scrapes
+ to proxy through this endpoint.
+ type: string
+ relabelings:
+ description: 'RelabelConfigs to apply to samples before scraping.
+ Prometheus Operator automatically adds relabelings for a few
+ standard Kubernetes fields. The original scrape job''s name
+ is available via the `__tmp_prometheus_job_name` label. More
+ info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config'
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the
+ label set, being applied to samples before ingestion. It
+ defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex
+ capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name
+ which may only contain ASCII letters, numbers, as
+ well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ scheme:
+ description: HTTP scheme to use for scraping.
+ type: string
+ scrapeTimeout:
+ description: Timeout after which the scrape is ended
+ type: string
+ targetPort:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the target port of the Pod behind
+ the Service, the port must be specified with container port
+ property. Mutually exclusive with port.
+ x-kubernetes-int-or-string: true
+ tlsConfig:
+ description: TLS configuration to use when scraping the endpoint
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ type: object
+ type: array
+ jobLabel:
+ description: "Chooses the label of the Kubernetes `Endpoints`. Its
+ value will be used for the `job`-label's value of the created metrics.
+ \n Default & fallback value: the name of the respective Kubernetes
+ `Endpoint`."
+ type: string
+ labelLimit:
+ description: Per-scrape limit on number of labels that will be accepted
+ for a sample. Only valid in Prometheus versions 2.27.0 and newer.
+ format: int64
+ type: integer
+ labelNameLengthLimit:
+ description: Per-scrape limit on length of labels name that will be
+ accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ labelValueLengthLimit:
+ description: Per-scrape limit on length of labels value that will
+ be accepted for a sample. Only valid in Prometheus versions 2.27.0
+ and newer.
+ format: int64
+ type: integer
+ namespaceSelector:
+ description: Selector to select which namespaces the Kubernetes Endpoints
+ objects are discovered from.
+ properties:
+ any:
+ description: Boolean describing whether all namespaces are selected
+ in contrast to a list restricting them.
+ type: boolean
+ matchNames:
+ description: List of namespace names to select from.
+ items:
+ type: string
+ type: array
+ type: object
+ podTargetLabels:
+ description: PodTargetLabels transfers labels on the Kubernetes `Pod`
+ onto the created metrics.
+ items:
+ type: string
+ type: array
+ sampleLimit:
+ description: SampleLimit defines per-scrape limit on number of scraped
+ samples that will be accepted.
+ format: int64
+ type: integer
+ selector:
+ description: Selector to select Endpoints objects.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ targetLabels:
+ description: TargetLabels transfers labels from the Kubernetes `Service`
+ onto the created metrics.
+ items:
+ type: string
+ type: array
+ targetLimit:
+ description: TargetLimit defines a limit on the number of scraped
+ targets that will be accepted.
+ format: int64
+ type: integer
+ required:
+ - endpoints
+ - selector
+ type: object
+ required:
+ - spec
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml
new file mode 100644
index 0000000..69a5abc
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml
@@ -0,0 +1,7087 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: grafanaagents.monitoring.grafana.com
+spec:
+ group: monitoring.grafana.com
+ names:
+ categories:
+ - agent-operator
+ kind: GrafanaAgent
+ listKind: GrafanaAgentList
+ plural: grafanaagents
+ singular: grafanaagent
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: GrafanaAgent defines a Grafana Agent deployment.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Spec holds the specification of the desired behavior for
+ the Grafana Agent cluster.
+ properties:
+ affinity:
+ description: Affinity, if specified, controls pod scheduling constraints.
+ properties:
+ nodeAffinity:
+ description: Describes node affinity scheduling rules for the
+ pod.
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods to
+ nodes that satisfy the affinity expressions specified by
+ this field, but it may choose a node that violates one or
+ more of the expressions. The node that is most preferred
+ is the one with the greatest sum of weights, i.e. for each
+ node that meets all of the scheduling requirements (resource
+ request, requiredDuringScheduling affinity expressions,
+ etc.), compute a sum by iterating through the elements of
+ this field and adding "weight" to the sum if the node matches
+ the corresponding matchExpressions; the node(s) with the
+ highest sum are the most preferred.
+ items:
+ description: An empty preferred scheduling term matches
+ all objects with implicit weight 0 (i.e. it's a no-op).
+ A null preferred scheduling term matches no objects (i.e.
+ is also a no-op).
+ properties:
+ preference:
+ description: A node selector term, associated with the
+ corresponding weight.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists, DoesNotExist. Gt, and
+ Lt.
+ type: string
+ values:
+ description: An array of string values. If
+ the operator is In or NotIn, the values
+ array must be non-empty. If the operator
+ is Exists or DoesNotExist, the values array
+ must be empty. If the operator is Gt or
+ Lt, the values array must have a single
+ element, which will be interpreted as an
+ integer. This array is replaced during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists, DoesNotExist. Gt, and
+ Lt.
+ type: string
+ values:
+ description: An array of string values. If
+ the operator is In or NotIn, the values
+ array must be non-empty. If the operator
+ is Exists or DoesNotExist, the values array
+ must be empty. If the operator is Gt or
+ Lt, the values array must have a single
+ element, which will be interpreted as an
+ integer. This array is replaced during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ weight:
+ description: Weight associated with matching the corresponding
+ nodeSelectorTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - preference
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by this
+ field are not met at scheduling time, the pod will not be
+ scheduled onto the node. If the affinity requirements specified
+ by this field cease to be met at some point during pod execution
+ (e.g. due to an update), the system may or may not try to
+ eventually evict the pod from its node.
+ properties:
+ nodeSelectorTerms:
+ description: Required. A list of node selector terms.
+ The terms are ORed.
+ items:
+ description: A null or empty node selector term matches
+ no objects. The requirements of them are ANDed. The
+ TopologySelectorTerm type implements a subset of the
+ NodeSelectorTerm.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists, DoesNotExist. Gt, and
+ Lt.
+ type: string
+ values:
+ description: An array of string values. If
+ the operator is In or NotIn, the values
+ array must be non-empty. If the operator
+ is Exists or DoesNotExist, the values array
+ must be empty. If the operator is Gt or
+ Lt, the values array must have a single
+ element, which will be interpreted as an
+ integer. This array is replaced during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists, DoesNotExist. Gt, and
+ Lt.
+ type: string
+ values:
+ description: An array of string values. If
+ the operator is In or NotIn, the values
+ array must be non-empty. If the operator
+ is Exists or DoesNotExist, the values array
+ must be empty. If the operator is Gt or
+ Lt, the values array must have a single
+ element, which will be interpreted as an
+ integer. This array is replaced during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ type: array
+ required:
+ - nodeSelectorTerms
+ type: object
+ type: object
+ podAffinity:
+ description: Describes pod affinity scheduling rules (e.g. co-locate
+ this pod in the same node, zone, etc. as some other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods to
+ nodes that satisfy the affinity expressions specified by
+ this field, but it may choose a node that violates one or
+ more of the expressions. The node that is most preferred
+ is the one with the greatest sum of weights, i.e. for each
+ node that meets all of the scheduling requirements (resource
+ request, requiredDuringScheduling affinity expressions,
+ etc.), compute a sum by iterating through the elements of
+ this field and adding "weight" to the sum if the node has
+ pods which matches the corresponding podAffinityTerm; the
+ node(s) with the highest sum are the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces. This field is beta-level
+ and is only honored when PodAffinityNamespaceSelector
+ feature is enabled.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace"
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the corresponding
+ podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by this
+ field are not met at scheduling time, the pod will not be
+ scheduled onto the node. If the affinity requirements specified
+ by this field cease to be met at some point during pod execution
+ (e.g. due to a pod label update), the system may or may
+ not try to eventually evict the pod from its node. When
+ there are multiple elements, the lists of nodes corresponding
+ to each podAffinityTerm are intersected, i.e. all terms
+ must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not co-located
+ (anti-affinity) with, where co-located is defined as running
+ on a node whose value of the label with key <topologyKey>
+ matches that of any node on which a pod of the set of
+ pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty. If the
+ operator is Exists or DoesNotExist, the
+ values array must be empty. This array is
+ replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is "In",
+ and the values array contains only "value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied to the
+ union of the namespaces selected by this field and
+ the ones listed in the namespaces field. null selector
+ and null or empty namespaces list means "this pod's
+ namespace". An empty selector ({}) matches all namespaces.
+ This field is beta-level and is only honored when
+ PodAffinityNamespaceSelector feature is enabled.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty. If the
+ operator is Exists or DoesNotExist, the
+ values array must be empty. This array is
+ replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is "In",
+ and the values array contains only "value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list of namespace
+ names that the term applies to. The term is applied
+ to the union of the namespaces listed in this field
+ and the ones selected by namespaceSelector. null or
+ empty namespaces list and null namespaceSelector means
+ "this pod's namespace"
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods matching
+ the labelSelector in the specified namespaces, where
+ co-located is defined as running on a node whose value
+ of the label with key topologyKey matches that of
+ any node on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ description: Describes pod anti-affinity scheduling rules (e.g.
+ avoid putting this pod in the same node, zone, etc. as some
+ other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods to
+ nodes that satisfy the anti-affinity expressions specified
+ by this field, but it may choose a node that violates one
+ or more of the expressions. The node that is most preferred
+ is the one with the greatest sum of weights, i.e. for each
+ node that meets all of the scheduling requirements (resource
+ request, requiredDuringScheduling anti-affinity expressions,
+ etc.), compute a sum by iterating through the elements of
+ this field and adding "weight" to the sum if the node has
+ pods which matches the corresponding podAffinityTerm; the
+ node(s) with the highest sum are the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces. This field is beta-level
+ and is only honored when PodAffinityNamespaceSelector
+ feature is enabled.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace"
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the corresponding
+ podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the anti-affinity requirements specified by
+ this field are not met at scheduling time, the pod will
+ not be scheduled onto the node. If the anti-affinity requirements
+ specified by this field cease to be met at some point during
+ pod execution (e.g. due to a pod label update), the system
+ may or may not try to eventually evict the pod from its
+ node. When there are multiple elements, the lists of nodes
+ corresponding to each podAffinityTerm are intersected, i.e.
+ all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not co-located
+ (anti-affinity) with, where co-located is defined as running
+ on a node whose value of the label with key <topologyKey>
+ matches that of any node on which a pod of the set of
+ pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty. If the
+ operator is Exists or DoesNotExist, the
+ values array must be empty. This array is
+ replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is "In",
+ and the values array contains only "value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied to the
+ union of the namespaces selected by this field and
+ the ones listed in the namespaces field. null selector
+ and null or empty namespaces list means "this pod's
+ namespace". An empty selector ({}) matches all namespaces.
+ This field is beta-level and is only honored when
+ PodAffinityNamespaceSelector feature is enabled.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a
+ selector that contains values, a key, and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty. If the
+ operator is Exists or DoesNotExist, the
+ values array must be empty. This array is
+ replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is "In",
+ and the values array contains only "value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list of namespace
+ names that the term applies to. The term is applied
+ to the union of the namespaces listed in this field
+ and the ones selected by namespaceSelector. null or
+ empty namespaces list and null namespaceSelector means
+ "this pod's namespace"
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods matching
+ the labelSelector in the specified namespaces, where
+ co-located is defined as running on a node whose value
+ of the label with key topologyKey matches that of
+ any node on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ type: object
+ apiServer:
+ description: APIServerConfig allows specifying a host and auth methods
+ to access the Kubernetes API server. If left empty, the Agent will
+ assume that it is running inside of the cluster and will discover
+ API servers automatically and use the pod's CA certificate and bearer
+ token file at /var/run/secrets/kubernetes.io/serviceaccount.
+ properties:
+ authorization:
+ description: Authorization section for accessing apiserver
+ properties:
+ credentials:
+ description: The secret's key that contains the credentials
+ of the request
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ credentialsFile:
+ description: File to read a secret from, mutually exclusive
+ with Credentials (from SafeAuthorization)
+ type: string
+ type:
+ description: Set the authentication type. Defaults to Bearer,
+ Basic will cause an error
+ type: string
+ type: object
+ basicAuth:
+ description: BasicAuth allow an endpoint to authenticate over
+ basic authentication
+ properties:
+ password:
+ description: The secret in the service monitor namespace that
+ contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace that
+ contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerToken:
+ description: Bearer token for accessing apiserver.
+ type: string
+ bearerTokenFile:
+ description: File to read bearer token for accessing apiserver.
+ type: string
+ host:
+ description: Host of apiserver. A valid string consisting of a
+ hostname or IP followed by an optional port number
+ type: string
+ tlsConfig:
+ description: TLS Config to use for accessing apiserver.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ required:
+ - host
+ type: object
+ configMaps:
+ description: ConfigMaps is a liset of config maps in the same namespace
+ as the GrafanaAgent object which will be mounted into each running
+ Grafana Agent pod. The ConfigMaps are mounted into /etc/grafana-agent/extra-configmaps/<configmap-name>.
+ items:
+ type: string
+ type: array
+ containers:
+ description: 'Containers allows injecting additional containers or
+ modifying operator generated containers. This can be used to allow
+ adding an authentication proxy to a Grafana Agent pod or to change
+ the behavior of an operator-generated container. Containers described
+ here modify an operator generated container if they share the same
+ name and modifications are done via a strategic merge patch. The
+ current container names are: `grafana-agent` and `config-reloader`.
+ Overriding containers is entirely outside the scope of what the
+ Grafana Agent team will support and by doing so, you accept that
+ this behavior may break at any time without notice.'
+ items:
+ description: A single application container that you want to run
+ within a pod.
+ properties:
+ args:
+ description: 'Arguments to the entrypoint. The docker image''s
+ CMD is used if this is not provided. Variable references $(VAR_NAME)
+ are expanded using the container''s environment. If a variable
+ cannot be resolved, the reference in the input string will
+ be unchanged. Double $$ are reduced to a single $, which allows
+ for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+ produce the string literal "$(VAR_NAME)". Escaped references
+ will never be expanded, regardless of whether the variable
+ exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell'
+ items:
+ type: string
+ type: array
+ command:
+ description: 'Entrypoint array. Not executed within a shell.
+ The docker image''s ENTRYPOINT is used if this is not provided.
+ Variable references $(VAR_NAME) are expanded using the container''s
+ environment. If a variable cannot be resolved, the reference
+ in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax:
+ i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether
+ the variable exists or not. Cannot be updated. More info:
+ https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell'
+ items:
+ type: string
+ type: array
+ env:
+ description: List of environment variables to set in the container.
+ Cannot be updated.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be
+ a C_IDENTIFIER.
+ type: string
+ value:
+ description: 'Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in
+ the container and any service environment variables.
+ If a variable cannot be resolved, the reference in the
+ input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME)
+ syntax: i.e. "$$(VAR_NAME)" will produce the string
+ literal "$(VAR_NAME)". Escaped references will never
+ be expanded, regardless of whether the variable exists
+ or not. Defaults to "".'
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ description: 'Selects a field of the pod: supports
+ metadata.name, metadata.namespace, `metadata.labels[''<KEY>'']`,
+ `metadata.annotations[''<KEY>'']`, spec.nodeName,
+ spec.serviceAccountName, status.hostIP, status.podIP,
+ status.podIPs.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ description: 'Selects a resource of the container:
+ only resources limits and requests (limits.cpu,
+ limits.memory, limits.ephemeral-storage, requests.cpu,
+ requests.memory and requests.ephemeral-storage)
+ are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ envFrom:
+ description: List of sources to populate environment variables
+ in the container. The keys defined within a source must be
+ a C_IDENTIFIER. All invalid keys will be reported as an event
+ when the container is starting. When a key exists in multiple
+ sources, the value associated with the last source will take
+ precedence. Values defined by an Env with a duplicate key
+ will take precedence. Cannot be updated.
+ items:
+ description: EnvFromSource represents the source of a set
+ of ConfigMaps
+ properties:
+ configMapRef:
+ description: The ConfigMap to select from
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap must be
+ defined
+ type: boolean
+ type: object
+ prefix:
+ description: An optional identifier to prepend to each
+ key in the ConfigMap. Must be a C_IDENTIFIER.
+ type: string
+ secretRef:
+ description: The Secret to select from
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret must be defined
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
+ This field is optional to allow higher level config management
+ to default or override container images in workload controllers
+ like Deployments and StatefulSets.'
+ type: string
+ imagePullPolicy:
+ description: 'Image pull policy. One of Always, Never, IfNotPresent.
+ Defaults to Always if :latest tag is specified, or IfNotPresent
+ otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images'
+ type: string
+ lifecycle:
+ description: Actions that the management system should take
+ in response to container lifecycle events. Cannot be updated.
+ properties:
+ postStart:
+ description: 'PostStart is called immediately after a container
+ is created. If the handler fails, the container is terminated
+ and restarted according to its restart policy. Other management
+ of the container blocks until the hook completes. More
+ info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for
+ the command is root ('/') in the container's
+ filesystem. The command is simply exec'd, it is
+ not run inside a shell, so traditional shell instructions
+ ('|', etc) won't work. To use a shell, you need
+ to explicitly call out to that shell. Exit status
+ of 0 is treated as live/healthy and non-zero is
+ unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to
+ the pod IP. You probably want to set "Host" in
+ httpHeaders instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request.
+ HTTP allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the
+ host. Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ tcpSocket:
+ description: Deprecated. TCPSocket is NOT supported
+ as a LifecycleHandler and kept for the backward compatibility.
+ There are no validation of this field and lifecycle
+ hooks will fail in runtime when tcp handler is specified.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to,
+ defaults to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ type: object
+ preStop:
+ description: 'PreStop is called immediately before a container
+ is terminated due to an API request or management event
+ such as liveness/startup probe failure, preemption, resource
+ contention, etc. The handler is not called if the container
+ crashes or exits. The Pod''s termination grace period
+ countdown begins before the PreStop hook is executed.
+ Regardless of the outcome of the handler, the container
+ will eventually terminate within the Pod''s termination
+ grace period (unless delayed by finalizers). Other management
+ of the container blocks until the hook completes or until
+ the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for
+ the command is root ('/') in the container's
+ filesystem. The command is simply exec'd, it is
+ not run inside a shell, so traditional shell instructions
+ ('|', etc) won't work. To use a shell, you need
+ to explicitly call out to that shell. Exit status
+ of 0 is treated as live/healthy and non-zero is
+ unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to
+ the pod IP. You probably want to set "Host" in
+ httpHeaders instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request.
+ HTTP allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the
+ host. Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ tcpSocket:
+ description: Deprecated. TCPSocket is NOT supported
+ as a LifecycleHandler and kept for the backward compatibility.
+ There are no validation of this field and lifecycle
+ hooks will fail in runtime when tcp handler is specified.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to,
+ defaults to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ description: 'Periodic probe of container liveness. Container
+ will be restarted if the probe fails. Cannot be updated. More
+ info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ name:
+ description: Name of the container specified as a DNS_LABEL.
+ Each container in a pod must have a unique name (DNS_LABEL).
+ Cannot be updated.
+ type: string
+ ports:
+ description: List of ports to expose from the container. Exposing
+ a port here gives the system additional information about
+ the network connections a container uses, but is primarily
+ informational. Not specifying a port here DOES NOT prevent
+ that port from being exposed. Any port which is listening
+ on the default "0.0.0.0" address inside a container will be
+ accessible from the network. Cannot be updated.
+ items:
+ description: ContainerPort represents a network port in a
+ single container.
+ properties:
+ containerPort:
+ description: Number of port to expose on the pod's IP
+ address. This must be a valid port number, 0 < x < 65536.
+ format: int32
+ type: integer
+ hostIP:
+ description: What host IP to bind the external port to.
+ type: string
+ hostPort:
+ description: Number of port to expose on the host. If
+ specified, this must be a valid port number, 0 < x <
+ 65536. If HostNetwork is specified, this must match
+ ContainerPort. Most containers do not need this.
+ format: int32
+ type: integer
+ name:
+ description: If specified, this must be an IANA_SVC_NAME
+ and unique within the pod. Each named port in a pod
+ must have a unique name. Name for the port that can
+ be referred to by services.
+ type: string
+ protocol:
+ default: TCP
+ description: Protocol for port. Must be UDP, TCP, or SCTP.
+ Defaults to "TCP".
+ type: string
+ required:
+ - containerPort
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - containerPort
+ - protocol
+ x-kubernetes-list-type: map
+ readinessProbe:
+ description: 'Periodic probe of container service readiness.
+ Container will be removed from service endpoints if the probe
+ fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ resources:
+ description: 'Compute Resources required by this container.
+ Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified,
+ otherwise to an implementation-defined value. More info:
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ securityContext:
+ description: 'SecurityContext defines the security options the
+ container should be run with. If set, the fields of SecurityContext
+ override the equivalent fields of PodSecurityContext. More
+ info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/'
+ properties:
+ allowPrivilegeEscalation:
+ description: 'AllowPrivilegeEscalation controls whether
+ a process can gain more privileges than its parent process.
+ This bool directly controls if the no_new_privs flag will
+ be set on the container process. AllowPrivilegeEscalation
+ is true always when the container is: 1) run as Privileged
+ 2) has CAP_SYS_ADMIN Note that this field cannot be set
+ when spec.os.name is windows.'
+ type: boolean
+ capabilities:
+ description: The capabilities to add/drop when running containers.
+ Defaults to the default set of capabilities granted by
+ the container runtime. Note that this field cannot be
+ set when spec.os.name is windows.
+ properties:
+ add:
+ description: Added capabilities
+ items:
+ description: Capability represent POSIX capabilities
+ type
+ type: string
+ type: array
+ drop:
+ description: Removed capabilities
+ items:
+ description: Capability represent POSIX capabilities
+ type
+ type: string
+ type: array
+ type: object
+ privileged:
+ description: Run container in privileged mode. Processes
+ in privileged containers are essentially equivalent to
+ root on the host. Defaults to false. Note that this field
+ cannot be set when spec.os.name is windows.
+ type: boolean
+ procMount:
+ description: procMount denotes the type of proc mount to
+ use for the containers. The default is DefaultProcMount
+ which uses the container runtime defaults for readonly
+ paths and masked paths. This requires the ProcMountType
+ feature flag to be enabled. Note that this field cannot
+ be set when spec.os.name is windows.
+ type: string
+ readOnlyRootFilesystem:
+ description: Whether this container has a read-only root
+ filesystem. Default is false. Note that this field cannot
+ be set when spec.os.name is windows.
+ type: boolean
+ runAsGroup:
+ description: The GID to run the entrypoint of the container
+ process. Uses runtime default if unset. May also be set
+ in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is windows.
+ format: int64
+ type: integer
+ runAsNonRoot:
+ description: Indicates that the container must run as a
+ non-root user. If true, the Kubelet will validate the
+ image at runtime to ensure that it does not run as UID
+ 0 (root) and fail to start the container if it does. If
+ unset or false, no such validation will be performed.
+ May also be set in PodSecurityContext. If set in both
+ SecurityContext and PodSecurityContext, the value specified
+ in SecurityContext takes precedence.
+ type: boolean
+ runAsUser:
+ description: The UID to run the entrypoint of the container
+ process. Defaults to user specified in image metadata
+ if unspecified. May also be set in PodSecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the
+ value specified in SecurityContext takes precedence. Note
+ that this field cannot be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ seLinuxOptions:
+ description: The SELinux context to be applied to the container.
+ If unspecified, the container runtime will allocate a
+ random SELinux context for each container. May also be
+ set in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is windows.
+ properties:
+ level:
+ description: Level is SELinux level label that applies
+ to the container.
+ type: string
+ role:
+ description: Role is a SELinux role label that applies
+ to the container.
+ type: string
+ type:
+ description: Type is a SELinux type label that applies
+ to the container.
+ type: string
+ user:
+ description: User is a SELinux user label that applies
+ to the container.
+ type: string
+ type: object
+ seccompProfile:
+ description: The seccomp options to use by this container.
+ If seccomp options are provided at both the pod & container
+ level, the container options override the pod options.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ properties:
+ localhostProfile:
+ description: localhostProfile indicates a profile defined
+ in a file on the node should be used. The profile
+ must be preconfigured on the node to work. Must be
+ a descending path, relative to the kubelet's configured
+ seccomp profile location. Must only be set if type
+ is "Localhost".
+ type: string
+ type:
+ description: "type indicates which kind of seccomp profile
+ will be applied. Valid options are: \n Localhost -
+ a profile defined in a file on the node should be
+ used. RuntimeDefault - the container runtime default
+ profile should be used. Unconfined - no profile should
+ be applied."
+ type: string
+ required:
+ - type
+ type: object
+ windowsOptions:
+ description: The Windows specific settings applied to all
+ containers. If unspecified, the options from the PodSecurityContext
+ will be used. If set in both SecurityContext and PodSecurityContext,
+ the value specified in SecurityContext takes precedence.
+ Note that this field cannot be set when spec.os.name is
+ linux.
+ properties:
+ gmsaCredentialSpec:
+ description: GMSACredentialSpec is where the GMSA admission
+ webhook (https://github.com/kubernetes-sigs/windows-gmsa)
+ inlines the contents of the GMSA credential spec named
+ by the GMSACredentialSpecName field.
+ type: string
+ gmsaCredentialSpecName:
+ description: GMSACredentialSpecName is the name of the
+ GMSA credential spec to use.
+ type: string
+ hostProcess:
+ description: HostProcess determines if a container should
+ be run as a 'Host Process' container. This field is
+ alpha-level and will only be honored by components
+ that enable the WindowsHostProcessContainers feature
+ flag. Setting this field without the feature flag
+ will result in errors when validating the Pod. All
+ of a Pod's containers must have the same effective
+ HostProcess value (it is not allowed to have a mix
+ of HostProcess containers and non-HostProcess containers). In
+ addition, if HostProcess is true then HostNetwork
+ must also be set to true.
+ type: boolean
+ runAsUserName:
+ description: The UserName in Windows to run the entrypoint
+ of the container process. Defaults to the user specified
+ in image metadata if unspecified. May also be set
+ in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence.
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ description: 'StartupProbe indicates that the Pod has successfully
+ initialized. If specified, no other probes are executed until
+ this completes successfully. If this probe fails, the Pod
+ will be restarted, just as if the livenessProbe failed. This
+ can be used to provide different probe parameters at the beginning
+ of a Pod''s lifecycle, when it might take a long time to load
+ data or warm a cache, than during steady-state operation.
+ This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ stdin:
+ description: Whether this container should allocate a buffer
+ for stdin in the container runtime. If this is not set, reads
+ from stdin in the container will always result in EOF. Default
+ is false.
+ type: boolean
+ stdinOnce:
+ description: Whether the container runtime should close the
+ stdin channel after it has been opened by a single attach.
+ When stdin is true the stdin stream will remain open across
+ multiple attach sessions. If stdinOnce is set to true, stdin
+ is opened on container start, is empty until the first client
+ attaches to stdin, and then remains open and accepts data
+ until the client disconnects, at which time stdin is closed
+ and remains closed until the container is restarted. If this
+ flag is false, a container processes that reads from stdin
+ will never receive an EOF. Default is false
+ type: boolean
+ terminationMessagePath:
+ description: 'Optional: Path at which the file to which the
+ container''s termination message will be written is mounted
+ into the container''s filesystem. Message written is intended
+ to be brief final status, such as an assertion failure message.
+ Will be truncated by the node if greater than 4096 bytes.
+ The total message length across all containers will be limited
+ to 12kb. Defaults to /dev/termination-log. Cannot be updated.'
+ type: string
+ terminationMessagePolicy:
+ description: Indicate how the termination message should be
+ populated. File will use the contents of terminationMessagePath
+ to populate the container status message on both success and
+ failure. FallbackToLogsOnError will use the last chunk of
+ container log output if the termination message file is empty
+ and the container exited with an error. The log output is
+ limited to 2048 bytes or 80 lines, whichever is smaller. Defaults
+ to File. Cannot be updated.
+ type: string
+ tty:
+ description: Whether this container should allocate a TTY for
+ itself, also requires 'stdin' to be true. Default is false.
+ type: boolean
+ volumeDevices:
+ description: volumeDevices is the list of block devices to be
+ used by the container.
+ items:
+ description: volumeDevice describes a mapping of a raw block
+ device within a container.
+ properties:
+ devicePath:
+ description: devicePath is the path inside of the container
+ that the device will be mapped to.
+ type: string
+ name:
+ description: name must match the name of a persistentVolumeClaim
+ in the pod
+ type: string
+ required:
+ - devicePath
+ - name
+ type: object
+ type: array
+ volumeMounts:
+ description: Pod volumes to mount into the container's filesystem.
+ Cannot be updated.
+ items:
+ description: VolumeMount describes a mounting of a Volume
+ within a container.
+ properties:
+ mountPath:
+ description: Path within the container at which the volume
+ should be mounted. Must not contain ':'.
+ type: string
+ mountPropagation:
+ description: mountPropagation determines how mounts are
+ propagated from the host to container and the other
+ way around. When not set, MountPropagationNone is used.
+ This field is beta in 1.10.
+ type: string
+ name:
+ description: This must match the Name of a Volume.
+ type: string
+ readOnly:
+ description: Mounted read-only if true, read-write otherwise
+ (false or unspecified). Defaults to false.
+ type: boolean
+ subPath:
+ description: Path within the volume from which the container's
+ volume should be mounted. Defaults to "" (volume's root).
+ type: string
+ subPathExpr:
+ description: Expanded path within the volume from which
+ the container's volume should be mounted. Behaves similarly
+ to SubPath but environment variable references $(VAR_NAME)
+ are expanded using the container's environment. Defaults
+ to "" (volume's root). SubPathExpr and SubPath are mutually
+ exclusive.
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ type: array
+ workingDir:
+ description: Container's working directory. If not specified,
+ the container runtime's default will be used, which might
+ be configured in the container image. Cannot be updated.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ enableConfigReadAPI:
+ default: false
+ description: enableConfigReadAPI enables the read API for viewing
+ currently running config port 8080 on the agent.
+ type: boolean
+ image:
+ description: Image, when specified, overrides the image used to run
+ the Agent. It should be specified along with a tag. Version must
+ still be set to ensure the Grafana Agent Operator knows which version
+ of Grafana Agent is being configured.
+ type: string
+ imagePullSecrets:
+ description: 'ImagePullSecrets holds an optional list of references
+ to secrets within the same namespace to use for pulling the Grafana
+ Agent image from registries. More info: https://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod'
+ items:
+ description: LocalObjectReference contains enough information to
+ let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ type: array
+ initContainers:
+ description: 'InitContainers allows adding initContainers to the pod
+ definition. These can be used to, for example, fetch secrets for
+ injection into the Grafana Agent configuration from external sources.
+ Any errors during the execution of an initContainer will lead to
+ a restart of the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
+ Using initContainers for any use case other than secret fetching
+ is entirely outside the scope of what the Grafana Agent maintainers
+ will support and by doing so, you accept that this behavior may
+ break at any time without notice.'
+ items:
+ description: A single application container that you want to run
+ within a pod.
+ properties:
+ args:
+ description: 'Arguments to the entrypoint. The docker image''s
+ CMD is used if this is not provided. Variable references $(VAR_NAME)
+ are expanded using the container''s environment. If a variable
+ cannot be resolved, the reference in the input string will
+ be unchanged. Double $$ are reduced to a single $, which allows
+ for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
+ produce the string literal "$(VAR_NAME)". Escaped references
+ will never be expanded, regardless of whether the variable
+ exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell'
+ items:
+ type: string
+ type: array
+ command:
+ description: 'Entrypoint array. Not executed within a shell.
+ The docker image''s ENTRYPOINT is used if this is not provided.
+ Variable references $(VAR_NAME) are expanded using the container''s
+ environment. If a variable cannot be resolved, the reference
+ in the input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME) syntax:
+ i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless of whether
+ the variable exists or not. Cannot be updated. More info:
+ https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell'
+ items:
+ type: string
+ type: array
+ env:
+ description: List of environment variables to set in the container.
+ Cannot be updated.
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be
+ a C_IDENTIFIER.
+ type: string
+ value:
+ description: 'Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in
+ the container and any service environment variables.
+ If a variable cannot be resolved, the reference in the
+ input string will be unchanged. Double $$ are reduced
+ to a single $, which allows for escaping the $(VAR_NAME)
+ syntax: i.e. "$$(VAR_NAME)" will produce the string
+ literal "$(VAR_NAME)". Escaped references will never
+ be expanded, regardless of whether the variable exists
+ or not. Defaults to "".'
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ description: 'Selects a field of the pod: supports
+ metadata.name, metadata.namespace, `metadata.labels[''<KEY>'']`,
+ `metadata.annotations[''<KEY>'']`, spec.nodeName,
+ spec.serviceAccountName, status.hostIP, status.podIP,
+ status.podIPs.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ description: 'Selects a resource of the container:
+ only resources limits and requests (limits.cpu,
+ limits.memory, limits.ephemeral-storage, requests.cpu,
+ requests.memory and requests.ephemeral-storage)
+ are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ envFrom:
+ description: List of sources to populate environment variables
+ in the container. The keys defined within a source must be
+ a C_IDENTIFIER. All invalid keys will be reported as an event
+ when the container is starting. When a key exists in multiple
+ sources, the value associated with the last source will take
+ precedence. Values defined by an Env with a duplicate key
+ will take precedence. Cannot be updated.
+ items:
+ description: EnvFromSource represents the source of a set
+ of ConfigMaps
+ properties:
+ configMapRef:
+ description: The ConfigMap to select from
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap must be
+ defined
+ type: boolean
+ type: object
+ prefix:
+ description: An optional identifier to prepend to each
+ key in the ConfigMap. Must be a C_IDENTIFIER.
+ type: string
+ secretRef:
+ description: The Secret to select from
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret must be defined
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
+ This field is optional to allow higher level config management
+ to default or override container images in workload controllers
+ like Deployments and StatefulSets.'
+ type: string
+ imagePullPolicy:
+ description: 'Image pull policy. One of Always, Never, IfNotPresent.
+ Defaults to Always if :latest tag is specified, or IfNotPresent
+ otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images'
+ type: string
+ lifecycle:
+ description: Actions that the management system should take
+ in response to container lifecycle events. Cannot be updated.
+ properties:
+ postStart:
+ description: 'PostStart is called immediately after a container
+ is created. If the handler fails, the container is terminated
+ and restarted according to its restart policy. Other management
+ of the container blocks until the hook completes. More
+ info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for
+ the command is root ('/') in the container's
+ filesystem. The command is simply exec'd, it is
+ not run inside a shell, so traditional shell instructions
+ ('|', etc) won't work. To use a shell, you need
+ to explicitly call out to that shell. Exit status
+ of 0 is treated as live/healthy and non-zero is
+ unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to
+ the pod IP. You probably want to set "Host" in
+ httpHeaders instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request.
+ HTTP allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the
+ host. Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ tcpSocket:
+ description: Deprecated. TCPSocket is NOT supported
+ as a LifecycleHandler and kept for the backward compatibility.
+ There are no validation of this field and lifecycle
+ hooks will fail in runtime when tcp handler is specified.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to,
+ defaults to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ type: object
+ preStop:
+ description: 'PreStop is called immediately before a container
+ is terminated due to an API request or management event
+ such as liveness/startup probe failure, preemption, resource
+ contention, etc. The handler is not called if the container
+ crashes or exits. The Pod''s termination grace period
+ countdown begins before the PreStop hook is executed.
+ Regardless of the outcome of the handler, the container
+ will eventually terminate within the Pod''s termination
+ grace period (unless delayed by finalizers). Other management
+ of the container blocks until the hook completes or until
+ the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for
+ the command is root ('/') in the container's
+ filesystem. The command is simply exec'd, it is
+ not run inside a shell, so traditional shell instructions
+ ('|', etc) won't work. To use a shell, you need
+ to explicitly call out to that shell. Exit status
+ of 0 is treated as live/healthy and non-zero is
+ unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to
+ the pod IP. You probably want to set "Host" in
+ httpHeaders instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request.
+ HTTP allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the
+ host. Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ tcpSocket:
+ description: Deprecated. TCPSocket is NOT supported
+ as a LifecycleHandler and kept for the backward compatibility.
+ There are no validation of this field and lifecycle
+ hooks will fail in runtime when tcp handler is specified.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to,
+ defaults to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access
+ on the container. Number must be in the range
+ 1 to 65535. Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ description: 'Periodic probe of container liveness. Container
+ will be restarted if the probe fails. Cannot be updated. More
+ info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ name:
+ description: Name of the container specified as a DNS_LABEL.
+ Each container in a pod must have a unique name (DNS_LABEL).
+ Cannot be updated.
+ type: string
+ ports:
+ description: List of ports to expose from the container. Exposing
+ a port here gives the system additional information about
+ the network connections a container uses, but is primarily
+ informational. Not specifying a port here DOES NOT prevent
+ that port from being exposed. Any port which is listening
+ on the default "0.0.0.0" address inside a container will be
+ accessible from the network. Cannot be updated.
+ items:
+ description: ContainerPort represents a network port in a
+ single container.
+ properties:
+ containerPort:
+ description: Number of port to expose on the pod's IP
+ address. This must be a valid port number, 0 < x < 65536.
+ format: int32
+ type: integer
+ hostIP:
+ description: What host IP to bind the external port to.
+ type: string
+ hostPort:
+ description: Number of port to expose on the host. If
+ specified, this must be a valid port number, 0 < x <
+ 65536. If HostNetwork is specified, this must match
+ ContainerPort. Most containers do not need this.
+ format: int32
+ type: integer
+ name:
+ description: If specified, this must be an IANA_SVC_NAME
+ and unique within the pod. Each named port in a pod
+ must have a unique name. Name for the port that can
+ be referred to by services.
+ type: string
+ protocol:
+ default: TCP
+ description: Protocol for port. Must be UDP, TCP, or SCTP.
+ Defaults to "TCP".
+ type: string
+ required:
+ - containerPort
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - containerPort
+ - protocol
+ x-kubernetes-list-type: map
+ readinessProbe:
+ description: 'Periodic probe of container service readiness.
+ Container will be removed from service endpoints if the probe
+ fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ resources:
+ description: 'Compute Resources required by this container.
+ Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified,
+ otherwise to an implementation-defined value. More info:
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ securityContext:
+ description: 'SecurityContext defines the security options the
+ container should be run with. If set, the fields of SecurityContext
+ override the equivalent fields of PodSecurityContext. More
+ info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/'
+ properties:
+ allowPrivilegeEscalation:
+ description: 'AllowPrivilegeEscalation controls whether
+ a process can gain more privileges than its parent process.
+ This bool directly controls if the no_new_privs flag will
+ be set on the container process. AllowPrivilegeEscalation
+ is true always when the container is: 1) run as Privileged
+ 2) has CAP_SYS_ADMIN Note that this field cannot be set
+ when spec.os.name is windows.'
+ type: boolean
+ capabilities:
+ description: The capabilities to add/drop when running containers.
+ Defaults to the default set of capabilities granted by
+ the container runtime. Note that this field cannot be
+ set when spec.os.name is windows.
+ properties:
+ add:
+ description: Added capabilities
+ items:
+ description: Capability represent POSIX capabilities
+ type
+ type: string
+ type: array
+ drop:
+ description: Removed capabilities
+ items:
+ description: Capability represent POSIX capabilities
+ type
+ type: string
+ type: array
+ type: object
+ privileged:
+ description: Run container in privileged mode. Processes
+ in privileged containers are essentially equivalent to
+ root on the host. Defaults to false. Note that this field
+ cannot be set when spec.os.name is windows.
+ type: boolean
+ procMount:
+ description: procMount denotes the type of proc mount to
+ use for the containers. The default is DefaultProcMount
+ which uses the container runtime defaults for readonly
+ paths and masked paths. This requires the ProcMountType
+ feature flag to be enabled. Note that this field cannot
+ be set when spec.os.name is windows.
+ type: string
+ readOnlyRootFilesystem:
+ description: Whether this container has a read-only root
+ filesystem. Default is false. Note that this field cannot
+ be set when spec.os.name is windows.
+ type: boolean
+ runAsGroup:
+ description: The GID to run the entrypoint of the container
+ process. Uses runtime default if unset. May also be set
+ in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is windows.
+ format: int64
+ type: integer
+ runAsNonRoot:
+ description: Indicates that the container must run as a
+ non-root user. If true, the Kubelet will validate the
+ image at runtime to ensure that it does not run as UID
+ 0 (root) and fail to start the container if it does. If
+ unset or false, no such validation will be performed.
+ May also be set in PodSecurityContext. If set in both
+ SecurityContext and PodSecurityContext, the value specified
+ in SecurityContext takes precedence.
+ type: boolean
+ runAsUser:
+ description: The UID to run the entrypoint of the container
+ process. Defaults to user specified in image metadata
+ if unspecified. May also be set in PodSecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the
+ value specified in SecurityContext takes precedence. Note
+ that this field cannot be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ seLinuxOptions:
+ description: The SELinux context to be applied to the container.
+ If unspecified, the container runtime will allocate a
+ random SELinux context for each container. May also be
+ set in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is windows.
+ properties:
+ level:
+ description: Level is SELinux level label that applies
+ to the container.
+ type: string
+ role:
+ description: Role is a SELinux role label that applies
+ to the container.
+ type: string
+ type:
+ description: Type is a SELinux type label that applies
+ to the container.
+ type: string
+ user:
+ description: User is a SELinux user label that applies
+ to the container.
+ type: string
+ type: object
+ seccompProfile:
+ description: The seccomp options to use by this container.
+ If seccomp options are provided at both the pod & container
+ level, the container options override the pod options.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ properties:
+ localhostProfile:
+ description: localhostProfile indicates a profile defined
+ in a file on the node should be used. The profile
+ must be preconfigured on the node to work. Must be
+ a descending path, relative to the kubelet's configured
+ seccomp profile location. Must only be set if type
+ is "Localhost".
+ type: string
+ type:
+ description: "type indicates which kind of seccomp profile
+ will be applied. Valid options are: \n Localhost -
+ a profile defined in a file on the node should be
+ used. RuntimeDefault - the container runtime default
+ profile should be used. Unconfined - no profile should
+ be applied."
+ type: string
+ required:
+ - type
+ type: object
+ windowsOptions:
+ description: The Windows specific settings applied to all
+ containers. If unspecified, the options from the PodSecurityContext
+ will be used. If set in both SecurityContext and PodSecurityContext,
+ the value specified in SecurityContext takes precedence.
+ Note that this field cannot be set when spec.os.name is
+ linux.
+ properties:
+ gmsaCredentialSpec:
+ description: GMSACredentialSpec is where the GMSA admission
+ webhook (https://github.com/kubernetes-sigs/windows-gmsa)
+ inlines the contents of the GMSA credential spec named
+ by the GMSACredentialSpecName field.
+ type: string
+ gmsaCredentialSpecName:
+ description: GMSACredentialSpecName is the name of the
+ GMSA credential spec to use.
+ type: string
+ hostProcess:
+ description: HostProcess determines if a container should
+ be run as a 'Host Process' container. This field is
+ alpha-level and will only be honored by components
+ that enable the WindowsHostProcessContainers feature
+ flag. Setting this field without the feature flag
+ will result in errors when validating the Pod. All
+ of a Pod's containers must have the same effective
+ HostProcess value (it is not allowed to have a mix
+ of HostProcess containers and non-HostProcess containers). In
+ addition, if HostProcess is true then HostNetwork
+ must also be set to true.
+ type: boolean
+ runAsUserName:
+ description: The UserName in Windows to run the entrypoint
+ of the container process. Defaults to the user specified
+ in image metadata if unspecified. May also be set
+ in PodSecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence.
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ description: 'StartupProbe indicates that the Pod has successfully
+ initialized. If specified, no other probes are executed until
+ this completes successfully. If this probe fails, the Pod
+ will be restarted, just as if the livenessProbe failed. This
+ can be used to provide different probe parameters at the beginning
+ of a Pod''s lifecycle, when it might take a long time to load
+ data or warm a cache, than during steady-state operation.
+ This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ properties:
+ exec:
+ description: Exec specifies the action to take.
+ properties:
+ command:
+ description: Command is the command line to execute
+ inside the container, the working directory for the
+ command is root ('/') in the container's filesystem.
+ The command is simply exec'd, it is not run inside
+ a shell, so traditional shell instructions ('|', etc)
+ won't work. To use a shell, you need to explicitly
+ call out to that shell. Exit status of 0 is treated
+ as live/healthy and non-zero is unhealthy.
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ description: Minimum consecutive failures for the probe
+ to be considered failed after having succeeded. Defaults
+ to 3. Minimum value is 1.
+ format: int32
+ type: integer
+ grpc:
+ description: GRPC specifies an action involving a GRPC port.
+ This is an alpha field and requires enabling GRPCContainerProbe
+ feature gate.
+ properties:
+ port:
+ description: Port number of the gRPC service. Number
+ must be in the range 1 to 65535.
+ format: int32
+ type: integer
+ service:
+ description: "Service is the name of the service to
+ place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
+ \n If this is not specified, the default behavior
+ is defined by gRPC."
+ type: string
+ required:
+ - port
+ type: object
+ httpGet:
+ description: HTTPGet specifies the http request to perform.
+ properties:
+ host:
+ description: Host name to connect to, defaults to the
+ pod IP. You probably want to set "Host" in httpHeaders
+ instead.
+ type: string
+ httpHeaders:
+ description: Custom headers to set in the request. HTTP
+ allows repeated headers.
+ items:
+ description: HTTPHeader describes a custom header
+ to be used in HTTP probes
+ properties:
+ name:
+ description: The header field name
+ type: string
+ value:
+ description: The header field value
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ path:
+ description: Path to access on the HTTP server.
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Name or number of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ scheme:
+ description: Scheme to use for connecting to the host.
+ Defaults to HTTP.
+ type: string
+ required:
+ - port
+ type: object
+ initialDelaySeconds:
+ description: 'Number of seconds after the container has
+ started before liveness probes are initiated. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ periodSeconds:
+ description: How often (in seconds) to perform the probe.
+ Default to 10 seconds. Minimum value is 1.
+ format: int32
+ type: integer
+ successThreshold:
+ description: Minimum consecutive successes for the probe
+ to be considered successful after having failed. Defaults
+ to 1. Must be 1 for liveness and startup. Minimum value
+ is 1.
+ format: int32
+ type: integer
+ tcpSocket:
+ description: TCPSocket specifies an action involving a TCP
+ port.
+ properties:
+ host:
+ description: 'Optional: Host name to connect to, defaults
+ to the pod IP.'
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Number or name of the port to access on
+ the container. Number must be in the range 1 to 65535.
+ Name must be an IANA_SVC_NAME.
+ x-kubernetes-int-or-string: true
+ required:
+ - port
+ type: object
+ terminationGracePeriodSeconds:
+ description: Optional duration in seconds the pod needs
+ to terminate gracefully upon probe failure. The grace
+ period is the duration in seconds after the processes
+ running in the pod are sent a termination signal and the
+ time when the processes are forcibly halted with a kill
+ signal. Set this value longer than the expected cleanup
+ time for your process. If this value is nil, the pod's
+ terminationGracePeriodSeconds will be used. Otherwise,
+ this value overrides the value provided by the pod spec.
+ Value must be non-negative integer. The value zero indicates
+ stop immediately via the kill signal (no opportunity to
+ shut down). This is a beta field and requires enabling
+ ProbeTerminationGracePeriod feature gate. Minimum value
+ is 1. spec.terminationGracePeriodSeconds is used if unset.
+ format: int64
+ type: integer
+ timeoutSeconds:
+ description: 'Number of seconds after which the probe times
+ out. Defaults to 1 second. Minimum value is 1. More info:
+ https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
+ format: int32
+ type: integer
+ type: object
+ stdin:
+ description: Whether this container should allocate a buffer
+ for stdin in the container runtime. If this is not set, reads
+ from stdin in the container will always result in EOF. Default
+ is false.
+ type: boolean
+ stdinOnce:
+ description: Whether the container runtime should close the
+ stdin channel after it has been opened by a single attach.
+ When stdin is true the stdin stream will remain open across
+ multiple attach sessions. If stdinOnce is set to true, stdin
+ is opened on container start, is empty until the first client
+ attaches to stdin, and then remains open and accepts data
+ until the client disconnects, at which time stdin is closed
+ and remains closed until the container is restarted. If this
+ flag is false, a container processes that reads from stdin
+ will never receive an EOF. Default is false
+ type: boolean
+ terminationMessagePath:
+ description: 'Optional: Path at which the file to which the
+ container''s termination message will be written is mounted
+ into the container''s filesystem. Message written is intended
+ to be brief final status, such as an assertion failure message.
+ Will be truncated by the node if greater than 4096 bytes.
+ The total message length across all containers will be limited
+ to 12kb. Defaults to /dev/termination-log. Cannot be updated.'
+ type: string
+ terminationMessagePolicy:
+ description: Indicate how the termination message should be
+ populated. File will use the contents of terminationMessagePath
+ to populate the container status message on both success and
+ failure. FallbackToLogsOnError will use the last chunk of
+ container log output if the termination message file is empty
+ and the container exited with an error. The log output is
+ limited to 2048 bytes or 80 lines, whichever is smaller. Defaults
+ to File. Cannot be updated.
+ type: string
+ tty:
+ description: Whether this container should allocate a TTY for
+ itself, also requires 'stdin' to be true. Default is false.
+ type: boolean
+ volumeDevices:
+ description: volumeDevices is the list of block devices to be
+ used by the container.
+ items:
+ description: volumeDevice describes a mapping of a raw block
+ device within a container.
+ properties:
+ devicePath:
+ description: devicePath is the path inside of the container
+ that the device will be mapped to.
+ type: string
+ name:
+ description: name must match the name of a persistentVolumeClaim
+ in the pod
+ type: string
+ required:
+ - devicePath
+ - name
+ type: object
+ type: array
+ volumeMounts:
+ description: Pod volumes to mount into the container's filesystem.
+ Cannot be updated.
+ items:
+ description: VolumeMount describes a mounting of a Volume
+ within a container.
+ properties:
+ mountPath:
+ description: Path within the container at which the volume
+ should be mounted. Must not contain ':'.
+ type: string
+ mountPropagation:
+ description: mountPropagation determines how mounts are
+ propagated from the host to container and the other
+ way around. When not set, MountPropagationNone is used.
+ This field is beta in 1.10.
+ type: string
+ name:
+ description: This must match the Name of a Volume.
+ type: string
+ readOnly:
+ description: Mounted read-only if true, read-write otherwise
+ (false or unspecified). Defaults to false.
+ type: boolean
+ subPath:
+ description: Path within the volume from which the container's
+ volume should be mounted. Defaults to "" (volume's root).
+ type: string
+ subPathExpr:
+ description: Expanded path within the volume from which
+ the container's volume should be mounted. Behaves similarly
+ to SubPath but environment variable references $(VAR_NAME)
+ are expanded using the container's environment. Defaults
+ to "" (volume's root). SubPathExpr and SubPath are mutually
+ exclusive.
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ type: array
+ workingDir:
+ description: Container's working directory. If not specified,
+ the container runtime's default will be used, which might
+ be configured in the container image. Cannot be updated.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ integrations:
+ description: Integrations controls the integration subsystem of the
+ Agent and settings unique to integration-specific pods that are
+ deployed.
+ properties:
+ namespaceSelector:
+ description: "Label selector for namespaces to search when discovering
+ integration resources. If nil, integration resources are only
+ discovered in the namespace of the GrafanaAgent resource. \n
+ Set to `{}` to search all namespaces."
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ selector:
+ description: Label selector to find Integration resources to run.
+ When nil, no integration resources will be defined.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ type: object
+ logFormat:
+ description: LogFormat controls the logging format of the generated
+ pods. Defaults to "logfmt" if not set.
+ type: string
+ logLevel:
+ description: LogLevel controls the log level of the generated pods.
+ Defaults to "info" if not set.
+ type: string
+ logs:
+ description: Logs controls the logging subsystem of the Agent and
+ settings unique to logging-specific pods that are deployed.
+ properties:
+ clients:
+ description: Global set of clients to use when a discovered LogsInstance
+ does not have any clients defined.
+ items:
+ description: LogsClientSpec defines the client integration for
+ logs, indicating which Loki server to send logs to.
+ properties:
+ backoffConfig:
+ description: Configures how to retry requests to Loki when
+ a request fails. Defaults to a minPeriod of 500ms, maxPeriod
+ of 5m, and maxRetries of 10.
+ properties:
+ maxPeriod:
+ description: Maximum backoff time between retries.
+ type: string
+ maxRetries:
+ description: Maximum number of retries to perform before
+ giving up a request.
+ type: integer
+ minPeriod:
+ description: Initial backoff time between retries. Time
+ between retries is increased exponentially.
+ type: string
+ type: object
+ basicAuth:
+ description: BasicAuth for the Loki server.
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ batchSize:
+ description: Maximum batch size (in bytes) of logs to accumulate
+ before sending the batch to Loki.
+ type: integer
+ batchWait:
+ description: Maximum amount of time to wait before sending
+ a batch, even if that batch isn't full.
+ type: string
+ bearerToken:
+ description: BearerToken used for remote_write.
+ type: string
+ bearerTokenFile:
+ description: BearerTokenFile used to read bearer token.
+ type: string
+ externalLabels:
+ additionalProperties:
+ type: string
+ description: ExternalLabels are labels to add to any time
+ series when sending data to Loki.
+ type: object
+ proxyUrl:
+ description: ProxyURL to proxy requests through. Optional.
+ type: string
+ tenantId:
+ description: Tenant ID used by default to push logs to Loki.
+ If omitted assumes remote Loki is running in single-tenant
+ mode or an authentication layer is used to inject an X-Scope-OrgID
+ header.
+ type: string
+ timeout:
+ description: Maximum time to wait for a server to respond
+ to a request.
+ type: string
+ tlsConfig:
+ description: TLSConfig to use for the client. Only used
+ when the protocol of the URL is https.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for
+ the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file
+ for the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for
+ the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for
+ the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ url:
+ description: 'URL is the URL where Loki is listening. Must
+ be a full HTTP URL, including protocol. Required. Example:
+ https://logs-prod-us-central1.grafana.net/loki/api/v1/push.'
+ type: string
+ required:
+ - url
+ type: object
+ type: array
+ enforcedNamespaceLabel:
+ description: EnforcedNamespaceLabel enforces adding a namespace
+ label of origin for each metric that is user-created. The label
+ value will always be the namespace of the object that is being
+ created.
+ type: string
+ ignoreNamespaceSelectors:
+ description: IgnoreNamespaceSelectors, if true, will ignore NamespaceSelector
+ settings from the PodLogs configs, and they will only discover
+ endpoints within their current namespace.
+ type: boolean
+ instanceNamespaceSelector:
+ description: InstanceNamespaceSelector are the set of labels to
+ determine which namespaces to watch for LogInstances. If not
+ provided, only checks own namespace.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ instanceSelector:
+ description: InstanceSelector determines which LogInstances should
+ be selected for running. Each instance runs its own set of Prometheus
+ components, including service discovery, scraping, and remote_write.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ logsExternalLabelName:
+ description: LogsExternalLabelName is the name of the external
+ label used to denote Grafana Agent cluster. Defaults to "cluster."
+ External label will _not_ be added when value is set to the
+ empty string.
+ type: string
+ type: object
+ metrics:
+ description: Metrics controls the metrics subsystem of the Agent and
+ settings unique to metrics-specific pods that are deployed.
+ properties:
+ arbitraryFSAccessThroughSMs:
+ description: ArbitraryFSAccessThroughSMs configures whether configuration
+ based on a ServiceMonitor can access arbitrary files on the
+ file system of the Grafana Agent container e.g. bearer token
+ files.
+ properties:
+ deny:
+ type: boolean
+ type: object
+ enforcedNamespaceLabel:
+ description: EnforcedNamespaceLabel enforces adding a namespace
+ label of origin for each metric that is user-created. The label
+ value will always be the namespace of the object that is being
+ created.
+ type: string
+ enforcedSampleLimit:
+ description: EnforcedSampleLimit defines global limit on the number
+ of scraped samples that will be accepted. This overrides any
+ SampleLimit set per ServiceMonitor and/or PodMonitor. It is
+ meant to be used by admins to enforce the SampleLimit to keep
+ the overall number of samples and series under the desired limit.
+ Note that if a SampleLimit from a ServiceMonitor or PodMonitor
+ is lower, that value will be used instead.
+ format: int64
+ type: integer
+ enforcedTargetLimit:
+ description: EnforcedTargetLimit defines a global limit on the
+ number of scraped targets. This overrides any TargetLimit set
+ per ServiceMonitor and/or PodMonitor. It is meant to be used
+ by admins to enforce the TargetLimit to keep the overall number
+ of targets under the desired limit. Note that if a TargetLimit
+ from a ServiceMonitor or PodMonitor is higher, that value will
+ be used instead.
+ format: int64
+ type: integer
+ externalLabels:
+ additionalProperties:
+ type: string
+ description: ExternalLabels are labels to add to any time series
+ when sending data over remote_write.
+ type: object
+ ignoreNamespaceSelectors:
+ description: IgnoreNamespaceSelectors, if true, will ignore NamespaceSelector
+ settings from the PodMonitor and ServiceMonitor configs, and
+ they will only discover endpoints within their current namespace.
+ type: boolean
+ instanceNamespaceSelector:
+ description: InstanceNamespaceSelector are the set of labels to
+ determine which namespaces to watch for MetricsInstances. If
+ not provided, only checks own namespace.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ instanceSelector:
+ description: InstanceSelector determines which MetricsInstances
+ should be selected for running. Each instance runs its own set
+ of Metrics components, including service discovery, scraping,
+ and remote_write.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If
+ the operator is In or NotIn, the values array must
+ be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced
+ during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A
+ single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is "key",
+ the operator is "In", and the values array contains only
+ "value". The requirements are ANDed.
+ type: object
+ type: object
+ metricsExternalLabelName:
+ description: MetricsExternalLabelName is the name of the external
+ label used to denote Grafana Agent cluster. Defaults to "cluster."
+ External label will _not_ be added when value is set to the
+ empty string.
+ type: string
+ overrideHonorLabels:
+ description: OverrideHonorLabels, if true, overrides all configured
+ honor_labels read from ServiceMonitor or PodMonitor to false.
+ type: boolean
+ overrideHonorTimestamps:
+ description: OverrideHonorTimestamps allows to globally enforce
+ honoring timestamps in all scrape configs.
+ type: boolean
+ remoteWrite:
+ description: RemoteWrite controls default remote_write settings
+ for all instances. If an instance does not provide its own remoteWrite
+ settings, these will be used instead.
+ items:
+ description: RemoteWriteSpec defines the remote_write configuration
+ for Prometheus.
+ properties:
+ basicAuth:
+ description: BasicAuth for the URL.
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerToken:
+ description: BearerToken used for remote_write.
+ type: string
+ bearerTokenFile:
+ description: BearerTokenFile used to read bearer token.
+ type: string
+ headers:
+ additionalProperties:
+ type: string
+ description: Headers is a set of custom HTTP headers to
+ be sent along with each remote_write request. Be aware
+ that any headers set by Grafana Agent itself can't be
+ overwritten.
+ type: object
+ metadataConfig:
+ description: MetadataConfig configures the sending of series
+ metadata to remote storage.
+ properties:
+ send:
+ description: Send enables metric metadata to be sent
+ to remote storage.
+ type: boolean
+ sendInterval:
+ description: SendInterval controls how frequently metric
+ metadata is sent to remote storage.
+ type: string
+ type: object
+ name:
+ description: Name of the remote_write queue. Must be unique
+ if specified. The name is used in metrics and logging
+ in order to differentiate queues.
+ type: string
+ proxyUrl:
+ description: ProxyURL to proxy requests through. Optional.
+ type: string
+ queueConfig:
+ description: QueueConfig allows tuning of the remote_write
+ queue parameters.
+ properties:
+ batchSendDeadline:
+ description: BatchSendDeadline is the maximum time a
+ sample will wait in buffer.
+ type: string
+ capacity:
+ description: Capacity is the number of samples to buffer
+ per shard before we start dropping them.
+ type: integer
+ maxBackoff:
+ description: MaxBackoff is the maximum retry delay.
+ type: string
+ maxRetries:
+ description: MaxRetries is the maximum number of times
+ to retry a batch on recoverable errors.
+ type: integer
+ maxSamplesPerSend:
+ description: MaxSamplesPerSend is the maximum number
+ of samples per send.
+ type: integer
+ maxShards:
+ description: MaxShards is the maximum number of shards,
+ i.e. amount of concurrency.
+ type: integer
+ minBackoff:
+ description: MinBackoff is the initial retry delay.
+ Gets doubled for every retry.
+ type: string
+ minShards:
+ description: MinShards is the minimum number of shards,
+ i.e. amount of concurrency.
+ type: integer
+ retryOnRateLimit:
+ description: RetryOnRateLimit retries requests when
+ encountering rate limits.
+ type: boolean
+ type: object
+ remoteTimeout:
+ description: RemoteTimeout is the timeout for requests to
+ the remote_write endpoint.
+ type: string
+ sigv4:
+ description: SigV4 configures SigV4-based authentication
+ to the remote_write endpoint. Will be used if SigV4 is
+ defined, even with an empty object.
+ properties:
+ accessKey:
+ description: AccessKey holds the secret of the AWS API
+ access key to use for signing. If not provided, The
+ environment variable AWS_ACCESS_KEY_ID is used.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ profile:
+ description: Profile is the named AWS profile to use
+ for authentication.
+ type: string
+ region:
+ description: Region of the AWS endpoint. If blank, the
+ region from the default credentials chain is used.
+ type: string
+ roleARN:
+ description: RoleARN is the AWS Role ARN to use for
+ authentication, as an alternative for using the AWS
+ API keys.
+ type: string
+ secretKey:
+ description: SecretKey of the AWS API to use for signing.
+ If blank, the environment variable AWS_SECRET_ACCESS_KEY
+ is used.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ tlsConfig:
+ description: TLSConfig to use for remote_write.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for
+ the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file
+ for the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for
+ the targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion,
+ kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for
+ the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ url:
+ description: URL of the endpoint to send samples to.
+ type: string
+ writeRelabelConfigs:
+ description: WriteRelabelConfigs holds relabel_configs to
+ relabel samples before they are sent to the remote_write
+ endpoint.
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of
+ the label set, being applied to samples before ingestion.
+ It defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the
+ extracted value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex
+ replace is performed if the regular expression matches.
+ Regex capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated
+ source label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from
+ existing labels. Their content is concatenated using
+ the configured separator and matched against the
+ configured regular expression for the replace, keep,
+ and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label
+ name which may only contain ASCII letters, numbers,
+ as well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is
+ written in a replace action. It is mandatory for
+ replace actions. Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ required:
+ - url
+ type: object
+ type: array
+ replicaExternalLabelName:
+ description: ReplicaExternalLabelName is the name of the metrics
+ external label used to denote replica name. Defaults to __replica__.
+ External label will _not_ be added when value is set to the
+ empty string.
+ type: string
+ replicas:
+ description: Replicas of each shard to deploy for metrics pods.
+ Number of replicas multiplied by the number of shards is the
+ total number of pods created.
+ format: int32
+ type: integer
+ scrapeInterval:
+ description: ScrapeInterval is the time between consecutive scrapes.
+ type: string
+ scrapeTimeout:
+ description: ScrapeTimeout is the time to wait for a target to
+ respond before marking a scrape as failed.
+ type: string
+ shards:
+ description: Shards to distribute targets onto. Number of replicas
+ multiplied by the number of shards is the total number of pods
+ created. Note that scaling down shards will not reshard data
+ onto remaining instances, it must be manually moved. Increasing
+ shards will not reshard data either but it will continue to
+ be available from the same instances. Sharding is performed
+ on the content of the __address__ target meta-label.
+ format: int32
+ type: integer
+ type: object
+ nodeSelector:
+ additionalProperties:
+ type: string
+ description: NodeSelector defines which nodes pods should be scheduling
+ on.
+ type: object
+ paused:
+ description: Paused prevents actions except for deletion to be performed
+ on the underlying managed objects.
+ type: boolean
+ podMetadata:
+ description: PodMetadata configures Labels and Annotations which are
+ propagated to created Grafana Agent pods.
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: 'Annotations is an unstructured key value map stored
+ with a resource that may be set by external tools to store and
+ retrieve arbitrary metadata. They are not queryable and should
+ be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+ type: object
+ labels:
+ additionalProperties:
+ type: string
+ description: 'Map of string keys and values that can be used to
+ organize and categorize (scope and select) objects. May match
+ selectors of replication controllers and services. More info:
+ http://kubernetes.io/docs/user-guide/labels'
+ type: object
+ name:
+ description: 'Name must be unique within a namespace. Is required
+ when creating resources, although some resources may allow a
+ client to request the generation of an appropriate name automatically.
+ Name is primarily intended for creation idempotence and configuration
+ definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
+ type: string
+ type: object
+ portName:
+ description: Port name used for the pods and governing service. This
+ defaults to agent-metrics.
+ type: string
+ priorityClassName:
+ description: PriorityClassName is the priority class assigned to pods.
+ type: string
+ resources:
+ description: Resources holds requests and limits for individual pods.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute resources
+ allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ secrets:
+ description: Secrets is a list of secrets in the same namespace as
+ the GrafanaAgent object which will be mounted into each running
+ Grafana Agent pod. The secrets are mounted into /etc/grafana-agent/extra-secrets/<secret-name>.
+ items:
+ type: string
+ type: array
+ securityContext:
+ description: SecurityContext holds pod-level security attributes and
+ common container settings. When unspecified, defaults to the default
+ PodSecurityContext.
+ properties:
+ fsGroup:
+ description: "A special supplemental group that applies to all
+ containers in a pod. Some volume types allow the Kubelet to
+ change the ownership of that volume to be owned by the pod:
+ \n 1. The owning GID will be the FSGroup 2. The setgid bit is
+ set (new files created in the volume will be owned by FSGroup)
+ 3. The permission bits are OR'd with rw-rw---- \n If unset,
+ the Kubelet will not modify the ownership and permissions of
+ any volume. Note that this field cannot be set when spec.os.name
+ is windows."
+ format: int64
+ type: integer
+ fsGroupChangePolicy:
+ description: 'fsGroupChangePolicy defines behavior of changing
+ ownership and permission of the volume before being exposed
+ inside Pod. This field will only apply to volume types which
+ support fsGroup based ownership(and permissions). It will have
+ no effect on ephemeral volume types such as: secret, configmaps
+ and emptydir. Valid values are "OnRootMismatch" and "Always".
+ If not specified, "Always" is used. Note that this field cannot
+ be set when spec.os.name is windows.'
+ type: string
+ runAsGroup:
+ description: The GID to run the entrypoint of the container process.
+ Uses runtime default if unset. May also be set in SecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the value
+ specified in SecurityContext takes precedence for that container.
+ Note that this field cannot be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ runAsNonRoot:
+ description: Indicates that the container must run as a non-root
+ user. If true, the Kubelet will validate the image at runtime
+ to ensure that it does not run as UID 0 (root) and fail to start
+ the container if it does. If unset or false, no such validation
+ will be performed. May also be set in SecurityContext. If set
+ in both SecurityContext and PodSecurityContext, the value specified
+ in SecurityContext takes precedence.
+ type: boolean
+ runAsUser:
+ description: The UID to run the entrypoint of the container process.
+ Defaults to user specified in image metadata if unspecified.
+ May also be set in SecurityContext. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence for that container. Note that this field cannot
+ be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ seLinuxOptions:
+ description: The SELinux context to be applied to all containers.
+ If unspecified, the container runtime will allocate a random
+ SELinux context for each container. May also be set in SecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the value
+ specified in SecurityContext takes precedence for that container.
+ Note that this field cannot be set when spec.os.name is windows.
+ properties:
+ level:
+ description: Level is SELinux level label that applies to
+ the container.
+ type: string
+ role:
+ description: Role is a SELinux role label that applies to
+ the container.
+ type: string
+ type:
+ description: Type is a SELinux type label that applies to
+ the container.
+ type: string
+ user:
+ description: User is a SELinux user label that applies to
+ the container.
+ type: string
+ type: object
+ seccompProfile:
+ description: The seccomp options to use by the containers in this
+ pod. Note that this field cannot be set when spec.os.name is
+ windows.
+ properties:
+ localhostProfile:
+ description: localhostProfile indicates a profile defined
+ in a file on the node should be used. The profile must be
+ preconfigured on the node to work. Must be a descending
+ path, relative to the kubelet's configured seccomp profile
+ location. Must only be set if type is "Localhost".
+ type: string
+ type:
+ description: "type indicates which kind of seccomp profile
+ will be applied. Valid options are: \n Localhost - a profile
+ defined in a file on the node should be used. RuntimeDefault
+ - the container runtime default profile should be used.
+ Unconfined - no profile should be applied."
+ type: string
+ required:
+ - type
+ type: object
+ supplementalGroups:
+ description: A list of groups applied to the first process run
+ in each container, in addition to the container's primary GID. If
+ unspecified, no groups will be added to any container. Note
+ that this field cannot be set when spec.os.name is windows.
+ items:
+ format: int64
+ type: integer
+ type: array
+ sysctls:
+ description: Sysctls hold a list of namespaced sysctls used for
+ the pod. Pods with unsupported sysctls (by the container runtime)
+ might fail to launch. Note that this field cannot be set when
+ spec.os.name is windows.
+ items:
+ description: Sysctl defines a kernel parameter to be set
+ properties:
+ name:
+ description: Name of a property to set
+ type: string
+ value:
+ description: Value of a property to set
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ windowsOptions:
+ description: The Windows specific settings applied to all containers.
+ If unspecified, the options within a container's SecurityContext
+ will be used. If set in both SecurityContext and PodSecurityContext,
+ the value specified in SecurityContext takes precedence. Note
+ that this field cannot be set when spec.os.name is linux.
+ properties:
+ gmsaCredentialSpec:
+ description: GMSACredentialSpec is where the GMSA admission
+ webhook (https://github.com/kubernetes-sigs/windows-gmsa)
+ inlines the contents of the GMSA credential spec named by
+ the GMSACredentialSpecName field.
+ type: string
+ gmsaCredentialSpecName:
+ description: GMSACredentialSpecName is the name of the GMSA
+ credential spec to use.
+ type: string
+ hostProcess:
+ description: HostProcess determines if a container should
+ be run as a 'Host Process' container. This field is alpha-level
+ and will only be honored by components that enable the WindowsHostProcessContainers
+ feature flag. Setting this field without the feature flag
+ will result in errors when validating the Pod. All of a
+ Pod's containers must have the same effective HostProcess
+ value (it is not allowed to have a mix of HostProcess containers
+ and non-HostProcess containers). In addition, if HostProcess
+ is true then HostNetwork must also be set to true.
+ type: boolean
+ runAsUserName:
+ description: The UserName in Windows to run the entrypoint
+ of the container process. Defaults to the user specified
+ in image metadata if unspecified. May also be set in PodSecurityContext.
+ If set in both SecurityContext and PodSecurityContext, the
+ value specified in SecurityContext takes precedence.
+ type: string
+ type: object
+ type: object
+ serviceAccountName:
+ description: ServiceAccountName is the name of the ServiceAccount
+ to use for running Grafana Agent pods.
+ type: string
+ storage:
+ description: Storage spec to specify how storage will be used.
+ properties:
+ disableMountSubPath:
+ description: 'Deprecated: subPath usage will be disabled by default
+ in a future release, this option will become unnecessary. DisableMountSubPath
+ allows to remove any subPath usage in volume mounts.'
+ type: boolean
+ emptyDir:
+ description: 'EmptyDirVolumeSource to be used by the Prometheus
+ StatefulSets. If specified, used in place of any volumeClaimTemplate.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir'
+ properties:
+ medium:
+ description: 'What type of storage medium should back this
+ directory. The default is "" which means to use the node''s
+ default medium. Must be an empty string (default) or Memory.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'Total amount of local storage required for this
+ EmptyDir volume. The size limit is also applicable for memory
+ medium. The maximum usage on memory medium EmptyDir would
+ be the minimum value between the SizeLimit specified here
+ and the sum of memory limits of all containers in a pod.
+ The default is nil which means that the limit is undefined.
+ More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ description: 'EphemeralVolumeSource to be used by the Prometheus
+ StatefulSets. This is a beta field in k8s 1.21, for lower versions,
+ starting with k8s 1.19, it requires enabling the GenericEphemeralVolume
+ feature gate. More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes'
+ properties:
+ volumeClaimTemplate:
+ description: "Will be used to create a stand-alone PVC to
+ provision the volume. The pod in which this EphemeralVolumeSource
+ is embedded will be the owner of the PVC, i.e. the PVC will
+ be deleted together with the pod. The name of the PVC will
+ be `<pod name>-<volume name>` where `<volume name>` is the
+ name from the `PodSpec.Volumes` array entry. Pod validation
+ will reject the pod if the concatenated name is not valid
+ for a PVC (for example, too long). \n An existing PVC with
+ that name that is not owned by the pod will *not* be used
+ for the pod to avoid using an unrelated volume by mistake.
+ Starting the pod is then blocked until the unrelated PVC
+ is removed. If such a pre-created PVC is meant to be used
+ by the pod, the PVC has to updated with an owner reference
+ to the pod once the pod exists. Normally this should not
+ be necessary, but it may be useful when manually reconstructing
+ a broken cluster. \n This field is read-only and no changes
+ will be made by Kubernetes to the PVC after it has been
+ created. \n Required, must not be nil."
+ properties:
+ metadata:
+ description: May contain labels and annotations that will
+ be copied into the PVC when creating it. No other fields
+ are allowed and will be rejected during validation.
+ type: object
+ spec:
+ description: The specification for the PersistentVolumeClaim.
+ The entire content is copied unchanged into the PVC
+ that gets created from this template. The same fields
+ as in a PersistentVolumeClaim are also valid here.
+ properties:
+ accessModes:
+ description: 'AccessModes contains the desired access
+ modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'This field can be used to specify either:
+ * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If the
+ provisioner or an external controller can support
+ the specified data source, it will create a new
+ volume based on the contents of the specified data
+ source. If the AnyVolumeDataSource feature gate
+ is enabled, this field will always have the same
+ contents as the DataSourceRef field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API group.
+ For any other third-party types, APIGroup is
+ required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ dataSourceRef:
+ description: 'Specifies the object from which to populate
+ the volume with data, if a non-empty volume is desired.
+ This may be any local object from a non-empty API
+ group (non core object) or a PersistentVolumeClaim
+ object. When this field is specified, volume binding
+ will only succeed if the type of the specified object
+ matches some installed volume populator or dynamic
+ provisioner. This field will replace the functionality
+ of the DataSource field and as such if both fields
+ are non-empty, they must have the same value. For
+ backwards compatibility, both fields (DataSource
+ and DataSourceRef) will be set to the same value
+ automatically if one of them is empty and the other
+ is non-empty. There are two important differences
+ between DataSource and DataSourceRef: * While DataSource
+ only allows two specific types of objects, DataSourceRef
+ allows any non-core object, as well as PersistentVolumeClaim
+ objects. * While DataSource ignores disallowed values
+ (dropping them), DataSourceRef preserves all values,
+ and generates an error if a disallowed value is
+ specified. (Alpha) Using this field requires the
+ AnyVolumeDataSource feature gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API group.
+ For any other third-party types, APIGroup is
+ required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ description: 'Resources represents the minimum resources
+ the volume should have. If RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to specify
+ resource requirements that are lower than previous
+ value but must still be higher than capacity recorded
+ in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount
+ of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount
+ of compute resources required. If Requests is
+ omitted for a container, it defaults to Limits
+ if that is explicitly specified, otherwise to
+ an implementation-defined value. More info:
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: A label query over volumes to consider
+ for binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement is
+ a selector that contains values, a key, and
+ an operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty. If
+ the operator is Exists or DoesNotExist,
+ the values array must be empty. This array
+ is replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is "In",
+ and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ storageClassName:
+ description: 'Name of the StorageClass required by
+ the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of volume
+ is required by the claim. Value of Filesystem is
+ implied when not included in claim spec.
+ type: string
+ volumeName:
+ description: VolumeName is the binding reference to
+ the PersistentVolume backing this claim.
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ volumeClaimTemplate:
+ description: A PVC spec to be used by the Prometheus StatefulSets.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this
+ representation of an object. Servers should convert recognized
+ schemas to the latest internal value, and may reject unrecognized
+ values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST
+ resource this object represents. Servers may infer this
+ from the endpoint the client submits requests to. Cannot
+ be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ description: EmbeddedMetadata contains metadata relevant to
+ an EmbeddedResource.
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: 'Annotations is an unstructured key value
+ map stored with a resource that may be set by external
+ tools to store and retrieve arbitrary metadata. They
+ are not queryable and should be preserved when modifying
+ objects. More info: http://kubernetes.io/docs/user-guide/annotations'
+ type: object
+ labels:
+ additionalProperties:
+ type: string
+ description: 'Map of string keys and values that can be
+ used to organize and categorize (scope and select) objects.
+ May match selectors of replication controllers and services.
+ More info: http://kubernetes.io/docs/user-guide/labels'
+ type: object
+ name:
+ description: 'Name must be unique within a namespace.
+ Is required when creating resources, although some resources
+ may allow a client to request the generation of an appropriate
+ name automatically. Name is primarily intended for creation
+ idempotence and configuration definition. Cannot be
+ updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names'
+ type: string
+ type: object
+ spec:
+ description: 'Spec defines the desired characteristics of
+ a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ properties:
+ accessModes:
+ description: 'AccessModes contains the desired access
+ modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'This field can be used to specify either:
+ * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If the provisioner
+ or an external controller can support the specified
+ data source, it will create a new volume based on the
+ contents of the specified data source. If the AnyVolumeDataSource
+ feature gate is enabled, this field will always have
+ the same contents as the DataSourceRef field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API group.
+ For any other third-party types, APIGroup is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being referenced
+ type: string
+ name:
+ description: Name is the name of resource being referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ dataSourceRef:
+ description: 'Specifies the object from which to populate
+ the volume with data, if a non-empty volume is desired.
+ This may be any local object from a non-empty API group
+ (non core object) or a PersistentVolumeClaim object.
+ When this field is specified, volume binding will only
+ succeed if the type of the specified object matches
+ some installed volume populator or dynamic provisioner.
+ This field will replace the functionality of the DataSource
+ field and as such if both fields are non-empty, they
+ must have the same value. For backwards compatibility,
+ both fields (DataSource and DataSourceRef) will be set
+ to the same value automatically if one of them is empty
+ and the other is non-empty. There are two important
+ differences between DataSource and DataSourceRef: *
+ While DataSource only allows two specific types of objects,
+ DataSourceRef allows any non-core object, as well as
+ PersistentVolumeClaim objects. * While DataSource ignores
+ disallowed values (dropping them), DataSourceRef preserves
+ all values, and generates an error if a disallowed value
+ is specified. (Alpha) Using this field requires the
+ AnyVolumeDataSource feature gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API group.
+ For any other third-party types, APIGroup is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being referenced
+ type: string
+ name:
+ description: Name is the name of resource being referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ description: 'Resources represents the minimum resources
+ the volume should have. If RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to specify resource
+ requirements that are lower than previous value but
+ must still be higher than capacity recorded in the status
+ field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount
+ of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount
+ of compute resources required. If Requests is omitted
+ for a container, it defaults to Limits if that is
+ explicitly specified, otherwise to an implementation-defined
+ value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: A label query over volumes to consider for
+ binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In,
+ NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values.
+ If the operator is In or NotIn, the values
+ array must be non-empty. If the operator is
+ Exists or DoesNotExist, the values array must
+ be empty. This array is replaced during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs.
+ A single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field
+ is "key", the operator is "In", and the values array
+ contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ storageClassName:
+ description: 'Name of the StorageClass required by the
+ claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of volume is
+ required by the claim. Value of Filesystem is implied
+ when not included in claim spec.
+ type: string
+ volumeName:
+ description: VolumeName is the binding reference to the
+ PersistentVolume backing this claim.
+ type: string
+ type: object
+ status:
+ description: 'Status represents the current information/status
+ of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ properties:
+ accessModes:
+ description: 'AccessModes contains the actual access modes
+ the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ allocatedResources:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: The storage resource within AllocatedResources
+ tracks the capacity allocated to a PVC. It may be larger
+ than the actual capacity when a volume expansion operation
+ is requested. For storage quota, the larger value from
+ allocatedResources and PVC.spec.resources is used. If
+ allocatedResources is not set, PVC.spec.resources alone
+ is used for quota calculation. If a volume expansion
+ capacity request is lowered, allocatedResources is only
+ lowered if there are no expansion operations in progress
+ and if the actual volume capacity is equal or lower
+ than the requested capacity. This is an alpha field
+ and requires enabling RecoverVolumeExpansionFailure
+ feature.
+ type: object
+ capacity:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: Represents the actual resources of the underlying
+ volume.
+ type: object
+ conditions:
+ description: Current Condition of persistent volume claim.
+ If underlying persistent volume is being resized then
+ the Condition will be set to 'ResizeStarted'.
+ items:
+ description: PersistentVolumeClaimCondition contails
+ details about state of pvc
+ properties:
+ lastProbeTime:
+ description: Last time we probed the condition.
+ format: date-time
+ type: string
+ lastTransitionTime:
+ description: Last time the condition transitioned
+ from one status to another.
+ format: date-time
+ type: string
+ message:
+ description: Human-readable message indicating details
+ about last transition.
+ type: string
+ reason:
+ description: Unique, this should be a short, machine
+ understandable string that gives the reason for
+ condition's last transition. If it reports "ResizeStarted"
+ that means the underlying persistent volume is
+ being resized.
+ type: string
+ status:
+ type: string
+ type:
+ description: PersistentVolumeClaimConditionType
+ is a valid value of PersistentVolumeClaimCondition.Type
+ type: string
+ required:
+ - status
+ - type
+ type: object
+ type: array
+ phase:
+ description: Phase represents the current phase of PersistentVolumeClaim.
+ type: string
+ resizeStatus:
+ description: ResizeStatus stores status of resize operation.
+ ResizeStatus is not set by default but when expansion
+ is complete resizeStatus is set to empty string by resize
+ controller or kubelet. This is an alpha field and requires
+ enabling RecoverVolumeExpansionFailure feature.
+ type: string
+ type: object
+ type: object
+ type: object
+ tolerations:
+ description: Tolerations, if specified, controls the pod's tolerations.
+ items:
+ description: The pod this Toleration is attached to tolerates any
+ taint that matches the triple <key,value,effect> using the matching
+ operator <operator>.
+ properties:
+ effect:
+ description: Effect indicates the taint effect to match. Empty
+ means match all taint effects. When specified, allowed values
+ are NoSchedule, PreferNoSchedule and NoExecute.
+ type: string
+ key:
+ description: Key is the taint key that the toleration applies
+ to. Empty means match all taint keys. If the key is empty,
+ operator must be Exists; this combination means to match all
+ values and all keys.
+ type: string
+ operator:
+ description: Operator represents a key's relationship to the
+ value. Valid operators are Exists and Equal. Defaults to Equal.
+ Exists is equivalent to wildcard for value, so that a pod
+ can tolerate all taints of a particular category.
+ type: string
+ tolerationSeconds:
+ description: TolerationSeconds represents the period of time
+ the toleration (which must be of effect NoExecute, otherwise
+ this field is ignored) tolerates the taint. By default, it
+ is not set, which means tolerate the taint forever (do not
+ evict). Zero and negative values will be treated as 0 (evict
+ immediately) by the system.
+ format: int64
+ type: integer
+ value:
+ description: Value is the taint value the toleration matches
+ to. If the operator is Exists, the value should be empty,
+ otherwise just a regular string.
+ type: string
+ type: object
+ type: array
+ topologySpreadConstraints:
+ description: TopologySpreadConstraints, if specified, controls the
+ pod's topology spread constraints.
+ items:
+ description: TopologySpreadConstraint specifies how to spread matching
+ pods among the given topology.
+ properties:
+ labelSelector:
+ description: LabelSelector is used to find matching pods. Pods
+ that match this label selector are counted to determine the
+ number of pods in their corresponding topology domain.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector
+ that contains values, a key, and an operator that relates
+ the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's relationship
+ to a set of values. Valid operators are In, NotIn,
+ Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values.
+ If the operator is In or NotIn, the values array
+ must be non-empty. If the operator is Exists or
+ DoesNotExist, the values array must be empty. This
+ array is replaced during a strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs.
+ A single {key,value} in the matchLabels map is equivalent
+ to an element of matchExpressions, whose key field is
+ "key", the operator is "In", and the values array contains
+ only "value". The requirements are ANDed.
+ type: object
+ type: object
+ maxSkew:
+ description: 'MaxSkew describes the degree to which pods may
+ be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`,
+ it is the maximum permitted difference between the number
+ of matching pods in the target topology and the global minimum.
+ For example, in a 3-zone cluster, MaxSkew is set to 1, and
+ pods with the same labelSelector spread as 1/1/0: | zone1
+ | zone2 | zone3 | | P | P | | - if MaxSkew is
+ 1, incoming pod can only be scheduled to zone3 to become 1/1/1;
+ scheduling it onto zone1(zone2) would make the ActualSkew(2-0)
+ on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming
+ pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`,
+ it is used to give higher precedence to topologies that satisfy
+ it. It''s a required field. Default value is 1 and 0 is not
+ allowed.'
+ format: int32
+ type: integer
+ topologyKey:
+ description: TopologyKey is the key of node labels. Nodes that
+ have a label with this key and identical values are considered
+ to be in the same topology. We consider each <key, value>
+ as a "bucket", and try to put balanced number of pods into
+ each bucket. It's a required field.
+ type: string
+ whenUnsatisfiable:
+ description: 'WhenUnsatisfiable indicates how to deal with a
+ pod if it doesn''t satisfy the spread constraint. - DoNotSchedule
+ (default) tells the scheduler not to schedule it. - ScheduleAnyway
+ tells the scheduler to schedule the pod in any location, but
+ giving higher precedence to topologies that would help reduce
+ the skew. A constraint is considered "Unsatisfiable" for an
+ incoming pod if and only if every possible node assignment
+ for that pod would violate "MaxSkew" on some topology. For
+ example, in a 3-zone cluster, MaxSkew is set to 1, and pods
+ with the same labelSelector spread as 3/1/1: | zone1 | zone2
+ | zone3 | | P P P | P | P | If WhenUnsatisfiable is
+ set to DoNotSchedule, incoming pod can only be scheduled to
+ zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on
+ zone2(zone3) satisfies MaxSkew(1). In other words, the cluster
+ can still be imbalanced, but scheduler won''t make it *more*
+ imbalanced. It''s a required field.'
+ type: string
+ required:
+ - maxSkew
+ - topologyKey
+ - whenUnsatisfiable
+ type: object
+ type: array
+ version:
+ description: Version of Grafana Agent to be deployed.
+ type: string
+ volumeMounts:
+ description: VolumeMounts allows configuration of additional VolumeMounts
+ on the output StatefulSet definition. VolumEMounts specified will
+ be appended to other VolumeMounts in the Grafana Agent container
+ that are generated as a result of StorageSpec objects.
+ items:
+ description: VolumeMount describes a mounting of a Volume within
+ a container.
+ properties:
+ mountPath:
+ description: Path within the container at which the volume should
+ be mounted. Must not contain ':'.
+ type: string
+ mountPropagation:
+ description: mountPropagation determines how mounts are propagated
+ from the host to container and the other way around. When
+ not set, MountPropagationNone is used. This field is beta
+ in 1.10.
+ type: string
+ name:
+ description: This must match the Name of a Volume.
+ type: string
+ readOnly:
+ description: Mounted read-only if true, read-write otherwise
+ (false or unspecified). Defaults to false.
+ type: boolean
+ subPath:
+ description: Path within the volume from which the container's
+ volume should be mounted. Defaults to "" (volume's root).
+ type: string
+ subPathExpr:
+ description: Expanded path within the volume from which the
+ container's volume should be mounted. Behaves similarly to
+ SubPath but environment variable references $(VAR_NAME) are
+ expanded using the container's environment. Defaults to ""
+ (volume's root). SubPathExpr and SubPath are mutually exclusive.
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ type: array
+ volumes:
+ description: Volumes allows configuration of additional volumes on
+ the output StatefulSet definition. Volumes specified will be appended
+ to other volumes that are generated as a result of StorageSpec objects.
+ items:
+ description: Volume represents a named volume in a pod that may
+ be accessed by any container in the pod.
+ properties:
+ awsElasticBlockStore:
+ description: 'AWSElasticBlockStore represents an AWS Disk resource
+ that is attached to a kubelet''s host machine and then exposed
+ to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ partition:
+ description: 'The partition in the volume that you want
+ to mount. If omitted, the default is to mount by volume
+ name. Examples: For volume /dev/sda1, you specify the
+ partition as "1". Similarly, the volume partition for
+ /dev/sda is "0" (or you can leave the property empty).'
+ format: int32
+ type: integer
+ readOnly:
+ description: 'Specify "true" to force and set the ReadOnly
+ property in VolumeMounts to "true". If omitted, the default
+ is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ type: boolean
+ volumeID:
+ description: 'Unique ID of the persistent disk resource
+ in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ description: AzureDisk represents an Azure Data Disk mount on
+ the host and bind mount to the pod.
+ properties:
+ cachingMode:
+ description: 'Host Caching mode: None, Read Only, Read Write.'
+ type: string
+ diskName:
+ description: The Name of the data disk in the blob storage
+ type: string
+ diskURI:
+ description: The URI the data disk in the blob storage
+ type: string
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ kind:
+ description: 'Expected values Shared: multiple blob disks
+ per storage account Dedicated: single blob disk per storage
+ account Managed: azure managed data disk (only in managed
+ availability set). defaults to shared'
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ description: AzureFile represents an Azure File Service mount
+ on the host and bind mount to the pod.
+ properties:
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretName:
+ description: the name of secret that contains Azure Storage
+ Account Name and Key
+ type: string
+ shareName:
+ description: Share Name
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ description: CephFS represents a Ceph FS mount on the host that
+ shares a pod's lifetime
+ properties:
+ monitors:
+ description: 'Required: Monitors is a collection of Ceph
+ monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ items:
+ type: string
+ type: array
+ path:
+ description: 'Optional: Used as the mounted root, rather
+ than the full Ceph tree, default is /'
+ type: string
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.
+ More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: boolean
+ secretFile:
+ description: 'Optional: SecretFile is the path to key ring
+ for User, default is /etc/ceph/user.secret More info:
+ https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: string
+ secretRef:
+ description: 'Optional: SecretRef is reference to the authentication
+ secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ user:
+ description: 'Optional: User is the rados user name, default
+ is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ description: 'Cinder represents a cinder volume attached and
+ mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ properties:
+ fsType:
+ description: 'Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Examples:
+ "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+ if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: string
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.
+ More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: boolean
+ secretRef:
+ description: 'Optional: points to a secret object containing
+ parameters used to connect to OpenStack.'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ volumeID:
+ description: 'volume id used to identify the volume in cinder.
+ More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ description: ConfigMap represents a configMap that should populate
+ this volume
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits used to set permissions
+ on created files by default. Must be an octal value between
+ 0000 and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires decimal
+ values for mode bits. Defaults to 0644. Directories within
+ the path are not affected by this setting. This might
+ be in conflict with other options that affect the file
+ mode, like fsGroup, and the result can be other mode bits
+ set.'
+ format: int32
+ type: integer
+ items:
+ description: If unspecified, each key-value pair in the
+ Data field of the referenced ConfigMap will be projected
+ into the volume as a file whose name is the key and content
+ is the value. If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys will not be
+ present. If a key is specified which is not present in
+ the ConfigMap, the volume setup will error unless it is
+ marked optional. Paths must be relative and may not contain
+ the '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file to map
+ the key to. May not be an absolute path. May not
+ contain the path element '..'. May not start with
+ the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its keys must
+ be defined
+ type: boolean
+ type: object
+ csi:
+ description: CSI (Container Storage Interface) represents ephemeral
+ storage that is handled by certain external CSI drivers (Beta
+ feature).
+ properties:
+ driver:
+ description: Driver is the name of the CSI driver that handles
+ this volume. Consult with your admin for the correct name
+ as registered in the cluster.
+ type: string
+ fsType:
+ description: Filesystem type to mount. Ex. "ext4", "xfs",
+ "ntfs". If not provided, the empty value is passed to
+ the associated CSI driver which will determine the default
+ filesystem to apply.
+ type: string
+ nodePublishSecretRef:
+ description: NodePublishSecretRef is a reference to the
+ secret object containing sensitive information to pass
+ to the CSI driver to complete the CSI NodePublishVolume
+ and NodeUnpublishVolume calls. This field is optional,
+ and may be empty if no secret is required. If the secret
+ object contains more than one secret, all secret references
+ are passed.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ readOnly:
+ description: Specifies a read-only configuration for the
+ volume. Defaults to false (read/write).
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ description: VolumeAttributes stores driver-specific properties
+ that are passed to the CSI driver. Consult your driver's
+ documentation for supported values.
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ description: DownwardAPI represents downward API about the pod
+ that should populate this volume
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits to use on created files
+ by default. Must be a Optional: mode bits used to set
+ permissions on created files by default. Must be an octal
+ value between 0000 and 0777 or a decimal value between
+ 0 and 511. YAML accepts both octal and decimal values,
+ JSON requires decimal values for mode bits. Defaults to
+ 0644. Directories within the path are not affected by
+ this setting. This might be in conflict with other options
+ that affect the file mode, like fsGroup, and the result
+ can be other mode bits set.'
+ format: int32
+ type: integer
+ items:
+ description: Items is a list of downward API volume file
+ items:
+ description: DownwardAPIVolumeFile represents information
+ to create the file containing the pod field
+ properties:
+ fieldRef:
+ description: 'Required: Selects a field of the pod:
+ only annotations, labels, name and namespace are
+ supported.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file, must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: 'Required: Path is the relative path
+ name of the file to be created. Must not be absolute
+ or contain the ''..'' path. Must be utf-8 encoded.
+ The first item of the relative path must not start
+ with ''..'''
+ type: string
+ resourceFieldRef:
+ description: 'Selects a resource of the container:
+ only resources limits and requests (limits.cpu,
+ limits.memory, requests.cpu and requests.memory)
+ are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ description: 'EmptyDir represents a temporary directory that
+ shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+ properties:
+ medium:
+ description: 'What type of storage medium should back this
+ directory. The default is "" which means to use the node''s
+ default medium. Must be an empty string (default) or Memory.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'Total amount of local storage required for
+ this EmptyDir volume. The size limit is also applicable
+ for memory medium. The maximum usage on memory medium
+ EmptyDir would be the minimum value between the SizeLimit
+ specified here and the sum of memory limits of all containers
+ in a pod. The default is nil which means that the limit
+ is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ description: "Ephemeral represents a volume that is handled
+ by a cluster storage driver. The volume's lifecycle is tied
+ to the pod that defines it - it will be created before the
+ pod starts, and deleted when the pod is removed. \n Use this
+ if: a) the volume is only needed while the pod runs, b) features
+ of normal volumes like restoring from snapshot or capacity
+ tracking are needed, c) the storage driver is specified through
+ a storage class, and d) the storage driver supports dynamic
+ volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource
+ for more information on the connection between this volume
+ type and PersistentVolumeClaim). \n Use PersistentVolumeClaim
+ or one of the vendor-specific APIs for volumes that persist
+ for longer than the lifecycle of an individual pod. \n Use
+ CSI for light-weight local ephemeral volumes if the CSI driver
+ is meant to be used that way - see the documentation of the
+ driver for more information. \n A pod can use both types of
+ ephemeral volumes and persistent volumes at the same time."
+ properties:
+ volumeClaimTemplate:
+ description: "Will be used to create a stand-alone PVC to
+ provision the volume. The pod in which this EphemeralVolumeSource
+ is embedded will be the owner of the PVC, i.e. the PVC
+ will be deleted together with the pod. The name of the
+ PVC will be `<pod name>-<volume name>` where `<volume
+ name>` is the name from the `PodSpec.Volumes` array entry.
+ Pod validation will reject the pod if the concatenated
+ name is not valid for a PVC (for example, too long). \n
+ An existing PVC with that name that is not owned by the
+ pod will *not* be used for the pod to avoid using an unrelated
+ volume by mistake. Starting the pod is then blocked until
+ the unrelated PVC is removed. If such a pre-created PVC
+ is meant to be used by the pod, the PVC has to updated
+ with an owner reference to the pod once the pod exists.
+ Normally this should not be necessary, but it may be useful
+ when manually reconstructing a broken cluster. \n This
+ field is read-only and no changes will be made by Kubernetes
+ to the PVC after it has been created. \n Required, must
+ not be nil."
+ properties:
+ metadata:
+ description: May contain labels and annotations that
+ will be copied into the PVC when creating it. No other
+ fields are allowed and will be rejected during validation.
+ type: object
+ spec:
+ description: The specification for the PersistentVolumeClaim.
+ The entire content is copied unchanged into the PVC
+ that gets created from this template. The same fields
+ as in a PersistentVolumeClaim are also valid here.
+ properties:
+ accessModes:
+ description: 'AccessModes contains the desired access
+ modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'This field can be used to specify
+ either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If the
+ provisioner or an external controller can support
+ the specified data source, it will create a new
+ volume based on the contents of the specified
+ data source. If the AnyVolumeDataSource feature
+ gate is enabled, this field will always have the
+ same contents as the DataSourceRef field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API
+ group. For any other third-party types, APIGroup
+ is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ dataSourceRef:
+ description: 'Specifies the object from which to
+ populate the volume with data, if a non-empty
+ volume is desired. This may be any local object
+ from a non-empty API group (non core object) or
+ a PersistentVolumeClaim object. When this field
+ is specified, volume binding will only succeed
+ if the type of the specified object matches some
+ installed volume populator or dynamic provisioner.
+ This field will replace the functionality of the
+ DataSource field and as such if both fields are
+ non-empty, they must have the same value. For
+ backwards compatibility, both fields (DataSource
+ and DataSourceRef) will be set to the same value
+ automatically if one of them is empty and the
+ other is non-empty. There are two important differences
+ between DataSource and DataSourceRef: * While
+ DataSource only allows two specific types of objects,
+ DataSourceRef allows any non-core object, as well
+ as PersistentVolumeClaim objects. * While DataSource
+ ignores disallowed values (dropping them), DataSourceRef
+ preserves all values, and generates an error if
+ a disallowed value is specified. (Alpha) Using
+ this field requires the AnyVolumeDataSource feature
+ gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API
+ group. For any other third-party types, APIGroup
+ is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ description: 'Resources represents the minimum resources
+ the volume should have. If RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to specify
+ resource requirements that are lower than previous
+ value but must still be higher than capacity recorded
+ in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount
+ of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum
+ amount of compute resources required. If Requests
+ is omitted for a container, it defaults to
+ Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info:
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: A label query over volumes to consider
+ for binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ storageClassName:
+ description: 'Name of the StorageClass required
+ by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of volume
+ is required by the claim. Value of Filesystem
+ is implied when not included in claim spec.
+ type: string
+ volumeName:
+ description: VolumeName is the binding reference
+ to the PersistentVolume backing this claim.
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ description: FC represents a Fibre Channel resource that is
+ attached to a kubelet's host machine and then exposed to the
+ pod.
+ properties:
+ fsType:
+ description: 'Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ lun:
+ description: 'Optional: FC target lun number'
+ format: int32
+ type: integer
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.'
+ type: boolean
+ targetWWNs:
+ description: 'Optional: FC target worldwide names (WWNs)'
+ items:
+ type: string
+ type: array
+ wwids:
+ description: 'Optional: FC volume world wide identifiers
+ (wwids) Either wwids or combination of targetWWNs and
+ lun must be set, but not both simultaneously.'
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ description: FlexVolume represents a generic volume resource
+ that is provisioned/attached using an exec based plugin.
+ properties:
+ driver:
+ description: Driver is the name of the driver to use for
+ this volume.
+ type: string
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". The default filesystem depends on FlexVolume
+ script.
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ description: 'Optional: Extra command options if any.'
+ type: object
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.'
+ type: boolean
+ secretRef:
+ description: 'Optional: SecretRef is reference to the secret
+ object containing sensitive information to pass to the
+ plugin scripts. This may be empty if no secret object
+ is specified. If the secret object contains more than
+ one secret, all secrets are passed to the plugin scripts.'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ description: Flocker represents a Flocker volume attached to
+ a kubelet's host machine. This depends on the Flocker control
+ service being running
+ properties:
+ datasetName:
+ description: Name of the dataset stored as metadata -> name
+ on the dataset for Flocker should be considered as deprecated
+ type: string
+ datasetUUID:
+ description: UUID of the dataset. This is unique identifier
+ of a Flocker dataset
+ type: string
+ type: object
+ gcePersistentDisk:
+ description: 'GCEPersistentDisk represents a GCE Disk resource
+ that is attached to a kubelet''s host machine and then exposed
+ to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ partition:
+ description: 'The partition in the volume that you want
+ to mount. If omitted, the default is to mount by volume
+ name. Examples: For volume /dev/sda1, you specify the
+ partition as "1". Similarly, the volume partition for
+ /dev/sda is "0" (or you can leave the property empty).
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ format: int32
+ type: integer
+ pdName:
+ description: 'Unique name of the PD resource in GCE. Used
+ to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ description: 'GitRepo represents a git repository at a particular
+ revision. DEPRECATED: GitRepo is deprecated. To provision
+ a container with a git repo, mount an EmptyDir into an InitContainer
+ that clones the repo using git, then mount the EmptyDir into
+ the Pod''s container.'
+ properties:
+ directory:
+ description: Target directory name. Must not contain or
+ start with '..'. If '.' is supplied, the volume directory
+ will be the git repository. Otherwise, if specified,
+ the volume will contain the git repository in the subdirectory
+ with the given name.
+ type: string
+ repository:
+ description: Repository URL
+ type: string
+ revision:
+ description: Commit hash for the specified revision.
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ description: 'Glusterfs represents a Glusterfs mount on the
+ host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md'
+ properties:
+ endpoints:
+ description: 'EndpointsName is the endpoint name that details
+ Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: string
+ path:
+ description: 'Path is the Glusterfs volume path. More info:
+ https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the Glusterfs volume
+ to be mounted with read-only permissions. Defaults to
+ false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ description: 'HostPath represents a pre-existing file or directory
+ on the host machine that is directly exposed to the container.
+ This is generally used for system agents or other privileged
+ things that are allowed to see the host machine. Most containers
+ will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
+ --- TODO(jonesdl) We need to restrict who can use host directory
+ mounts and who can/can not mount host directories as read/write.'
+ properties:
+ path:
+ description: 'Path of the directory on the host. If the
+ path is a symlink, it will follow the link to the real
+ path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
+ type: string
+ type:
+ description: 'Type for HostPath Volume Defaults to "" More
+ info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ description: 'ISCSI represents an ISCSI Disk resource that is
+ attached to a kubelet''s host machine and then exposed to
+ the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md'
+ properties:
+ chapAuthDiscovery:
+ description: whether support iSCSI Discovery CHAP authentication
+ type: boolean
+ chapAuthSession:
+ description: whether support iSCSI Session CHAP authentication
+ type: boolean
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ initiatorName:
+ description: Custom iSCSI Initiator Name. If initiatorName
+ is specified with iscsiInterface simultaneously, new iSCSI
+ interface <target portal>:<volume name> will be created
+ for the connection.
+ type: string
+ iqn:
+ description: Target iSCSI Qualified Name.
+ type: string
+ iscsiInterface:
+ description: iSCSI Interface Name that uses an iSCSI transport.
+ Defaults to 'default' (tcp).
+ type: string
+ lun:
+ description: iSCSI Target Lun number.
+ format: int32
+ type: integer
+ portals:
+ description: iSCSI Target Portal List. The portal is either
+ an IP or ip_addr:port if the port is other than default
+ (typically TCP ports 860 and 3260).
+ items:
+ type: string
+ type: array
+ readOnly:
+ description: ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false.
+ type: boolean
+ secretRef:
+ description: CHAP Secret for iSCSI target and initiator
+ authentication
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ targetPortal:
+ description: iSCSI Target Portal. The Portal is either an
+ IP or ip_addr:port if the port is other than default (typically
+ TCP ports 860 and 3260).
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ description: 'Volume''s name. Must be a DNS_LABEL and unique
+ within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ nfs:
+ description: 'NFS represents an NFS mount on the host that shares
+ a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ properties:
+ path:
+ description: 'Path that is exported by the NFS server. More
+ info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the NFS export to
+ be mounted with read-only permissions. Defaults to false.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: boolean
+ server:
+ description: 'Server is the hostname or IP address of the
+ NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ description: 'PersistentVolumeClaimVolumeSource represents a
+ reference to a PersistentVolumeClaim in the same namespace.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ properties:
+ claimName:
+ description: 'ClaimName is the name of a PersistentVolumeClaim
+ in the same namespace as the pod using this volume. More
+ info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ type: string
+ readOnly:
+ description: Will force the ReadOnly setting in VolumeMounts.
+ Default false.
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ description: PhotonPersistentDisk represents a PhotonController
+ persistent disk attached and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ pdID:
+ description: ID that identifies Photon Controller persistent
+ disk
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ description: PortworxVolume represents a portworx volume attached
+ and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: FSType represents the filesystem type to mount
+ Must be a filesystem type supported by the host operating
+ system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4"
+ if unspecified.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ volumeID:
+ description: VolumeID uniquely identifies a Portworx volume
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ description: Items for all in one resources secrets, configmaps,
+ and downward API
+ properties:
+ defaultMode:
+ description: Mode bits used to set permissions on created
+ files by default. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML accepts
+ both octal and decimal values, JSON requires decimal values
+ for mode bits. Directories within the path are not affected
+ by this setting. This might be in conflict with other
+ options that affect the file mode, like fsGroup, and the
+ result can be other mode bits set.
+ format: int32
+ type: integer
+ sources:
+ description: list of volume projections
+ items:
+ description: Projection that may be projected along with
+ other supported volume types
+ properties:
+ configMap:
+ description: information about the configMap data
+ to project
+ properties:
+ items:
+ description: If unspecified, each key-value pair
+ in the Data field of the referenced ConfigMap
+ will be projected into the volume as a file
+ whose name is the key and content is the value.
+ If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys
+ will not be present. If a key is specified which
+ is not present in the ConfigMap, the volume
+ setup will error unless it is marked optional.
+ Paths must be relative and may not contain the
+ '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within
+ a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file. Must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file
+ to map the key to. May not be an absolute
+ path. May not contain the path element
+ '..'. May not start with the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its keys must be defined
+ type: boolean
+ type: object
+ downwardAPI:
+ description: information about the downwardAPI data
+ to project
+ properties:
+ items:
+ description: Items is a list of DownwardAPIVolume
+ file
+ items:
+ description: DownwardAPIVolumeFile represents
+ information to create the file containing
+ the pod field
+ properties:
+ fieldRef:
+ description: 'Required: Selects a field
+ of the pod: only annotations, labels,
+ name and namespace are supported.'
+ properties:
+ apiVersion:
+ description: Version of the schema the
+ FieldPath is written in terms of,
+ defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select
+ in the specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file, must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: 'Required: Path is the relative
+ path name of the file to be created. Must
+ not be absolute or contain the ''..''
+ path. Must be utf-8 encoded. The first
+ item of the relative path must not start
+ with ''..'''
+ type: string
+ resourceFieldRef:
+ description: 'Selects a resource of the
+ container: only resources limits and requests
+ (limits.cpu, limits.memory, requests.cpu
+ and requests.memory) are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required
+ for volumes, optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format
+ of the exposed resources, defaults
+ to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to
+ select'
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ description: information about the secret data to
+ project
+ properties:
+ items:
+ description: If unspecified, each key-value pair
+ in the Data field of the referenced Secret will
+ be projected into the volume as a file whose
+ name is the key and content is the value. If
+ specified, the listed keys will be projected
+ into the specified paths, and unlisted keys
+ will not be present. If a key is specified which
+ is not present in the Secret, the volume setup
+ will error unless it is marked optional. Paths
+ must be relative and may not contain the '..'
+ path or start with '..'.
+ items:
+ description: Maps a string key to a path within
+ a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file. Must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file
+ to map the key to. May not be an absolute
+ path. May not contain the path element
+ '..'. May not start with the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ type: object
+ serviceAccountToken:
+ description: information about the serviceAccountToken
+ data to project
+ properties:
+ audience:
+ description: Audience is the intended audience
+ of the token. A recipient of a token must identify
+ itself with an identifier specified in the audience
+ of the token, and otherwise should reject the
+ token. The audience defaults to the identifier
+ of the apiserver.
+ type: string
+ expirationSeconds:
+ description: ExpirationSeconds is the requested
+ duration of validity of the service account
+ token. As the token approaches expiration, the
+ kubelet volume plugin will proactively rotate
+ the service account token. The kubelet will
+ start trying to rotate the token if the token
+ is older than 80 percent of its time to live
+ or if the token is older than 24 hours.Defaults
+ to 1 hour and must be at least 10 minutes.
+ format: int64
+ type: integer
+ path:
+ description: Path is the path relative to the
+ mount point of the file to project the token
+ into.
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ description: Quobyte represents a Quobyte mount on the host
+ that shares a pod's lifetime
+ properties:
+ group:
+ description: Group to map volume access to Default is no
+ group
+ type: string
+ readOnly:
+ description: ReadOnly here will force the Quobyte volume
+ to be mounted with read-only permissions. Defaults to
+ false.
+ type: boolean
+ registry:
+ description: Registry represents a single or multiple Quobyte
+ Registry services specified as a string as host:port pair
+ (multiple entries are separated with commas) which acts
+ as the central registry for volumes
+ type: string
+ tenant:
+ description: Tenant owning the given Quobyte volume in the
+ Backend Used with dynamically provisioned Quobyte volumes,
+ value is set by the plugin
+ type: string
+ user:
+ description: User to map volume access to Defaults to serivceaccount
+ user
+ type: string
+ volume:
+ description: Volume is a string that references an already
+ created Quobyte volume by name.
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ description: 'RBD represents a Rados Block Device mount on the
+ host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ image:
+ description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ keyring:
+ description: 'Keyring is the path to key ring for RBDUser.
+ Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ monitors:
+ description: 'A collection of Ceph monitors. More info:
+ https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ items:
+ type: string
+ type: array
+ pool:
+ description: 'The rados pool name. Default is rbd. More
+ info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: boolean
+ secretRef:
+ description: 'SecretRef is name of the authentication secret
+ for RBDUser. If provided overrides keyring. Default is
+ nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ user:
+ description: 'The rados user name. Default is admin. More
+ info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ description: ScaleIO represents a ScaleIO persistent volume
+ attached and mounted on Kubernetes nodes.
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Default is "xfs".
+ type: string
+ gateway:
+ description: The host address of the ScaleIO API Gateway.
+ type: string
+ protectionDomain:
+ description: The name of the ScaleIO Protection Domain for
+ the configured storage.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretRef:
+ description: SecretRef references to the secret for ScaleIO
+ user and other sensitive information. If this is not provided,
+ Login operation will fail.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ sslEnabled:
+ description: Flag to enable/disable SSL communication with
+ Gateway, default false
+ type: boolean
+ storageMode:
+ description: Indicates whether the storage for a volume
+ should be ThickProvisioned or ThinProvisioned. Default
+ is ThinProvisioned.
+ type: string
+ storagePool:
+ description: The ScaleIO Storage Pool associated with the
+ protection domain.
+ type: string
+ system:
+ description: The name of the storage system as configured
+ in ScaleIO.
+ type: string
+ volumeName:
+ description: The name of a volume already created in the
+ ScaleIO system that is associated with this volume source.
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ description: 'Secret represents a secret that should populate
+ this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits used to set permissions
+ on created files by default. Must be an octal value between
+ 0000 and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires decimal
+ values for mode bits. Defaults to 0644. Directories within
+ the path are not affected by this setting. This might
+ be in conflict with other options that affect the file
+ mode, like fsGroup, and the result can be other mode bits
+ set.'
+ format: int32
+ type: integer
+ items:
+ description: If unspecified, each key-value pair in the
+ Data field of the referenced Secret will be projected
+ into the volume as a file whose name is the key and content
+ is the value. If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys will not be
+ present. If a key is specified which is not present in
+ the Secret, the volume setup will error unless it is marked
+ optional. Paths must be relative and may not contain the
+ '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file to map
+ the key to. May not be an absolute path. May not
+ contain the path element '..'. May not start with
+ the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ description: Specify whether the Secret or its keys must
+ be defined
+ type: boolean
+ secretName:
+ description: 'Name of the secret in the pod''s namespace
+ to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
+ type: string
+ type: object
+ storageos:
+ description: StorageOS represents a StorageOS volume attached
+ and mounted on Kubernetes nodes.
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretRef:
+ description: SecretRef specifies the secret to use for obtaining
+ the StorageOS API credentials. If not specified, default
+ values will be attempted.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ volumeName:
+ description: VolumeName is the human-readable name of the
+ StorageOS volume. Volume names are only unique within
+ a namespace.
+ type: string
+ volumeNamespace:
+ description: VolumeNamespace specifies the scope of the
+ volume within StorageOS. If no namespace is specified
+ then the Pod's namespace will be used. This allows the
+ Kubernetes name scoping to be mirrored within StorageOS
+ for tighter integration. Set VolumeName to any name to
+ override the default behaviour. Set to "default" if you
+ are not using namespaces within StorageOS. Namespaces
+ that do not pre-exist within StorageOS will be created.
+ type: string
+ type: object
+ vsphereVolume:
+ description: VsphereVolume represents a vSphere volume attached
+ and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ storagePolicyID:
+ description: Storage Policy Based Management (SPBM) profile
+ ID associated with the StoragePolicyName.
+ type: string
+ storagePolicyName:
+ description: Storage Policy Based Management (SPBM) profile
+ name.
+ type: string
+ volumePath:
+ description: Path that identifies vSphere volume vmdk
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml
new file mode 100644
index 0000000..18bd037
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml
@@ -0,0 +1,1657 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: integrations.monitoring.grafana.com
+spec:
+ group: monitoring.grafana.com
+ names:
+ categories:
+ - agent-operator
+ kind: Integration
+ listKind: IntegrationList
+ plural: integrations
+ singular: integration
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: "Integration runs a single Grafana Agent integration. Integrations
+ that generate telemetry must be configured to send that telemetry somewhere;
+ such as autoscrape for exporter-based integrations. \n Integrations have
+ access to the LogsInstances and MetricsInstances in the same GrafanaAgent
+ resource set, referenced by the <namespace>/<name> of the *Instance resource.
+ \n For example, if there is a default/production MetricsInstance, you can
+ configure a supported integration's autoscrape block with: \n autoscrape:
+ enable: true metrics_instance: default/production \n There is currently
+ no way for telemetry created by an Operator-managed integration to be collected
+ from outside of the integration itself."
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specifies the desired behavior of the Integration.
+ properties:
+ config:
+ description: "The configuration for the named integration. Note that
+ integrations are deployed with the integrations-next feature flag,
+ which has different common settings: \n https://grafana.com/docs/agent/latest/configuration/integrations/integrations-next/"
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ configMaps:
+ description: "An extra list of keys from ConfigMaps in the same namespace
+ as the Integration which will be mounted into the Grafana Agent
+ pod running this integration. \n ConfigMaps will be mounted at /etc/grafana-agent/integrations/configMaps/<configmap_namespace>/<configmap_name>/<key>."
+ items:
+ description: Selects a key from a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: array
+ name:
+ description: Name of the integration to run (e.g., "node_exporter",
+ "mysqld_exporter").
+ type: string
+ secrets:
+ description: "An extra list of keys from Secrets in the same namespace
+ as the Integration which will be mounted into the Grafana Agent
+ pod running this integration. \n Secrets will be mounted at /etc/grafana-agent/integrations/secrets/<secret_namespace>/<secret_name>/<key>."
+ items:
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: array
+ type:
+ description: Type informs Grafana Agent Operator how to manage the
+ integration being configured.
+ properties:
+ allNodes:
+ description: When true, the configured integration should be run
+ on every Node in the cluster. This is required for integrations
+ that generate Node-specific metrics like node_exporter, otherwise
+ it must be false to avoid generating duplicate metrics.
+ type: boolean
+ unique:
+ description: Whether this integration can only be defined once
+ for a Grafana Agent process, such as statsd_exporter. It is
+ invalid for a GrafanaAgent to discover multiple unique Integrations
+ with the same integration name (i.e., a single GrafanaAgent
+ cannot deploy two statsd_exporters).
+ type: boolean
+ type: object
+ volumeMounts:
+ description: "An extra list of VolumeMounts to be associated with
+ the Grafana Agent pods running this integration. VolumeMount names
+ will be mutated to be unique across all used IntegrationSpecs. \n
+ Mount paths should include the namespace/name of the Integration
+ CR to avoid potentially colliding with other resources."
+ items:
+ description: VolumeMount describes a mounting of a Volume within
+ a container.
+ properties:
+ mountPath:
+ description: Path within the container at which the volume should
+ be mounted. Must not contain ':'.
+ type: string
+ mountPropagation:
+ description: mountPropagation determines how mounts are propagated
+ from the host to container and the other way around. When
+ not set, MountPropagationNone is used. This field is beta
+ in 1.10.
+ type: string
+ name:
+ description: This must match the Name of a Volume.
+ type: string
+ readOnly:
+ description: Mounted read-only if true, read-write otherwise
+ (false or unspecified). Defaults to false.
+ type: boolean
+ subPath:
+ description: Path within the volume from which the container's
+ volume should be mounted. Defaults to "" (volume's root).
+ type: string
+ subPathExpr:
+ description: Expanded path within the volume from which the
+ container's volume should be mounted. Behaves similarly to
+ SubPath but environment variable references $(VAR_NAME) are
+ expanded using the container's environment. Defaults to ""
+ (volume's root). SubPathExpr and SubPath are mutually exclusive.
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ type: array
+ volumes:
+ description: "An extra list of Volumes to be associated with the Grafana
+ Agent pods running this integration. Volume names will be mutated
+ to be unique across all Integrations. Note that the specified volumes
+ should be able to tolerate existing on multiple pods at once when
+ type is daemonset. \n Don't use volumes for loading secrets/configMaps
+ from the same namespace as the Integration; use the secrets and
+ configMaps fields instead."
+ items:
+ description: Volume represents a named volume in a pod that may
+ be accessed by any container in the pod.
+ properties:
+ awsElasticBlockStore:
+ description: 'AWSElasticBlockStore represents an AWS Disk resource
+ that is attached to a kubelet''s host machine and then exposed
+ to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ partition:
+ description: 'The partition in the volume that you want
+ to mount. If omitted, the default is to mount by volume
+ name. Examples: For volume /dev/sda1, you specify the
+ partition as "1". Similarly, the volume partition for
+ /dev/sda is "0" (or you can leave the property empty).'
+ format: int32
+ type: integer
+ readOnly:
+ description: 'Specify "true" to force and set the ReadOnly
+ property in VolumeMounts to "true". If omitted, the default
+ is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ type: boolean
+ volumeID:
+ description: 'Unique ID of the persistent disk resource
+ in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ description: AzureDisk represents an Azure Data Disk mount on
+ the host and bind mount to the pod.
+ properties:
+ cachingMode:
+ description: 'Host Caching mode: None, Read Only, Read Write.'
+ type: string
+ diskName:
+ description: The Name of the data disk in the blob storage
+ type: string
+ diskURI:
+ description: The URI the data disk in the blob storage
+ type: string
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ kind:
+ description: 'Expected values Shared: multiple blob disks
+ per storage account Dedicated: single blob disk per storage
+ account Managed: azure managed data disk (only in managed
+ availability set). defaults to shared'
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ description: AzureFile represents an Azure File Service mount
+ on the host and bind mount to the pod.
+ properties:
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretName:
+ description: the name of secret that contains Azure Storage
+ Account Name and Key
+ type: string
+ shareName:
+ description: Share Name
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ description: CephFS represents a Ceph FS mount on the host that
+ shares a pod's lifetime
+ properties:
+ monitors:
+ description: 'Required: Monitors is a collection of Ceph
+ monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ items:
+ type: string
+ type: array
+ path:
+ description: 'Optional: Used as the mounted root, rather
+ than the full Ceph tree, default is /'
+ type: string
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.
+ More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: boolean
+ secretFile:
+ description: 'Optional: SecretFile is the path to key ring
+ for User, default is /etc/ceph/user.secret More info:
+ https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: string
+ secretRef:
+ description: 'Optional: SecretRef is reference to the authentication
+ secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ user:
+ description: 'Optional: User is the rados user name, default
+ is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ description: 'Cinder represents a cinder volume attached and
+ mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ properties:
+ fsType:
+ description: 'Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Examples:
+ "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+ if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: string
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.
+ More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: boolean
+ secretRef:
+ description: 'Optional: points to a secret object containing
+ parameters used to connect to OpenStack.'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ volumeID:
+ description: 'volume id used to identify the volume in cinder.
+ More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ description: ConfigMap represents a configMap that should populate
+ this volume
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits used to set permissions
+ on created files by default. Must be an octal value between
+ 0000 and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires decimal
+ values for mode bits. Defaults to 0644. Directories within
+ the path are not affected by this setting. This might
+ be in conflict with other options that affect the file
+ mode, like fsGroup, and the result can be other mode bits
+ set.'
+ format: int32
+ type: integer
+ items:
+ description: If unspecified, each key-value pair in the
+ Data field of the referenced ConfigMap will be projected
+ into the volume as a file whose name is the key and content
+ is the value. If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys will not be
+ present. If a key is specified which is not present in
+ the ConfigMap, the volume setup will error unless it is
+ marked optional. Paths must be relative and may not contain
+ the '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file to map
+ the key to. May not be an absolute path. May not
+ contain the path element '..'. May not start with
+ the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its keys must
+ be defined
+ type: boolean
+ type: object
+ csi:
+ description: CSI (Container Storage Interface) represents ephemeral
+ storage that is handled by certain external CSI drivers (Beta
+ feature).
+ properties:
+ driver:
+ description: Driver is the name of the CSI driver that handles
+ this volume. Consult with your admin for the correct name
+ as registered in the cluster.
+ type: string
+ fsType:
+ description: Filesystem type to mount. Ex. "ext4", "xfs",
+ "ntfs". If not provided, the empty value is passed to
+ the associated CSI driver which will determine the default
+ filesystem to apply.
+ type: string
+ nodePublishSecretRef:
+ description: NodePublishSecretRef is a reference to the
+ secret object containing sensitive information to pass
+ to the CSI driver to complete the CSI NodePublishVolume
+ and NodeUnpublishVolume calls. This field is optional,
+ and may be empty if no secret is required. If the secret
+ object contains more than one secret, all secret references
+ are passed.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ readOnly:
+ description: Specifies a read-only configuration for the
+ volume. Defaults to false (read/write).
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ description: VolumeAttributes stores driver-specific properties
+ that are passed to the CSI driver. Consult your driver's
+ documentation for supported values.
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ description: DownwardAPI represents downward API about the pod
+ that should populate this volume
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits to use on created files
+ by default. Must be a Optional: mode bits used to set
+ permissions on created files by default. Must be an octal
+ value between 0000 and 0777 or a decimal value between
+ 0 and 511. YAML accepts both octal and decimal values,
+ JSON requires decimal values for mode bits. Defaults to
+ 0644. Directories within the path are not affected by
+ this setting. This might be in conflict with other options
+ that affect the file mode, like fsGroup, and the result
+ can be other mode bits set.'
+ format: int32
+ type: integer
+ items:
+ description: Items is a list of downward API volume file
+ items:
+ description: DownwardAPIVolumeFile represents information
+ to create the file containing the pod field
+ properties:
+ fieldRef:
+ description: 'Required: Selects a field of the pod:
+ only annotations, labels, name and namespace are
+ supported.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file, must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: 'Required: Path is the relative path
+ name of the file to be created. Must not be absolute
+ or contain the ''..'' path. Must be utf-8 encoded.
+ The first item of the relative path must not start
+ with ''..'''
+ type: string
+ resourceFieldRef:
+ description: 'Selects a resource of the container:
+ only resources limits and requests (limits.cpu,
+ limits.memory, requests.cpu and requests.memory)
+ are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ description: 'EmptyDir represents a temporary directory that
+ shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+ properties:
+ medium:
+ description: 'What type of storage medium should back this
+ directory. The default is "" which means to use the node''s
+ default medium. Must be an empty string (default) or Memory.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'Total amount of local storage required for
+ this EmptyDir volume. The size limit is also applicable
+ for memory medium. The maximum usage on memory medium
+ EmptyDir would be the minimum value between the SizeLimit
+ specified here and the sum of memory limits of all containers
+ in a pod. The default is nil which means that the limit
+ is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ description: "Ephemeral represents a volume that is handled
+ by a cluster storage driver. The volume's lifecycle is tied
+ to the pod that defines it - it will be created before the
+ pod starts, and deleted when the pod is removed. \n Use this
+ if: a) the volume is only needed while the pod runs, b) features
+ of normal volumes like restoring from snapshot or capacity
+ tracking are needed, c) the storage driver is specified through
+ a storage class, and d) the storage driver supports dynamic
+ volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource
+ for more information on the connection between this volume
+ type and PersistentVolumeClaim). \n Use PersistentVolumeClaim
+ or one of the vendor-specific APIs for volumes that persist
+ for longer than the lifecycle of an individual pod. \n Use
+ CSI for light-weight local ephemeral volumes if the CSI driver
+ is meant to be used that way - see the documentation of the
+ driver for more information. \n A pod can use both types of
+ ephemeral volumes and persistent volumes at the same time."
+ properties:
+ volumeClaimTemplate:
+ description: "Will be used to create a stand-alone PVC to
+ provision the volume. The pod in which this EphemeralVolumeSource
+ is embedded will be the owner of the PVC, i.e. the PVC
+ will be deleted together with the pod. The name of the
+ PVC will be `<pod name>-<volume name>` where `<volume
+ name>` is the name from the `PodSpec.Volumes` array entry.
+ Pod validation will reject the pod if the concatenated
+ name is not valid for a PVC (for example, too long). \n
+ An existing PVC with that name that is not owned by the
+ pod will *not* be used for the pod to avoid using an unrelated
+ volume by mistake. Starting the pod is then blocked until
+ the unrelated PVC is removed. If such a pre-created PVC
+ is meant to be used by the pod, the PVC has to updated
+ with an owner reference to the pod once the pod exists.
+ Normally this should not be necessary, but it may be useful
+ when manually reconstructing a broken cluster. \n This
+ field is read-only and no changes will be made by Kubernetes
+ to the PVC after it has been created. \n Required, must
+ not be nil."
+ properties:
+ metadata:
+ description: May contain labels and annotations that
+ will be copied into the PVC when creating it. No other
+ fields are allowed and will be rejected during validation.
+ type: object
+ spec:
+ description: The specification for the PersistentVolumeClaim.
+ The entire content is copied unchanged into the PVC
+ that gets created from this template. The same fields
+ as in a PersistentVolumeClaim are also valid here.
+ properties:
+ accessModes:
+ description: 'AccessModes contains the desired access
+ modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'This field can be used to specify
+ either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If the
+ provisioner or an external controller can support
+ the specified data source, it will create a new
+ volume based on the contents of the specified
+ data source. If the AnyVolumeDataSource feature
+ gate is enabled, this field will always have the
+ same contents as the DataSourceRef field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API
+ group. For any other third-party types, APIGroup
+ is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ dataSourceRef:
+ description: 'Specifies the object from which to
+ populate the volume with data, if a non-empty
+ volume is desired. This may be any local object
+ from a non-empty API group (non core object) or
+ a PersistentVolumeClaim object. When this field
+ is specified, volume binding will only succeed
+ if the type of the specified object matches some
+ installed volume populator or dynamic provisioner.
+ This field will replace the functionality of the
+ DataSource field and as such if both fields are
+ non-empty, they must have the same value. For
+ backwards compatibility, both fields (DataSource
+ and DataSourceRef) will be set to the same value
+ automatically if one of them is empty and the
+ other is non-empty. There are two important differences
+ between DataSource and DataSourceRef: * While
+ DataSource only allows two specific types of objects,
+ DataSourceRef allows any non-core object, as well
+ as PersistentVolumeClaim objects. * While DataSource
+ ignores disallowed values (dropping them), DataSourceRef
+ preserves all values, and generates an error if
+ a disallowed value is specified. (Alpha) Using
+ this field requires the AnyVolumeDataSource feature
+ gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the resource
+ being referenced. If APIGroup is not specified,
+ the specified Kind must be in the core API
+ group. For any other third-party types, APIGroup
+ is required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
+ referenced
+ type: string
+ name:
+ description: Name is the name of resource being
+ referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ description: 'Resources represents the minimum resources
+ the volume should have. If RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to specify
+ resource requirements that are lower than previous
+ value but must still be higher than capacity recorded
+ in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount
+ of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum
+ amount of compute resources required. If Requests
+ is omitted for a container, it defaults to
+ Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info:
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: A label query over volumes to consider
+ for binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: A label selector requirement
+ is a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a key's
+ relationship to a set of values. Valid
+ operators are In, NotIn, Exists and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
+ values. If the operator is In or NotIn,
+ the values array must be non-empty.
+ If the operator is Exists or DoesNotExist,
+ the values array must be empty. This
+ array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
+ pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions,
+ whose key field is "key", the operator is
+ "In", and the values array contains only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ storageClassName:
+ description: 'Name of the StorageClass required
+ by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of volume
+ is required by the claim. Value of Filesystem
+ is implied when not included in claim spec.
+ type: string
+ volumeName:
+ description: VolumeName is the binding reference
+ to the PersistentVolume backing this claim.
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ description: FC represents a Fibre Channel resource that is
+ attached to a kubelet's host machine and then exposed to the
+ pod.
+ properties:
+ fsType:
+ description: 'Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ lun:
+ description: 'Optional: FC target lun number'
+ format: int32
+ type: integer
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.'
+ type: boolean
+ targetWWNs:
+ description: 'Optional: FC target worldwide names (WWNs)'
+ items:
+ type: string
+ type: array
+ wwids:
+ description: 'Optional: FC volume world wide identifiers
+ (wwids) Either wwids or combination of targetWWNs and
+ lun must be set, but not both simultaneously.'
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ description: FlexVolume represents a generic volume resource
+ that is provisioned/attached using an exec based plugin.
+ properties:
+ driver:
+ description: Driver is the name of the driver to use for
+ this volume.
+ type: string
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". The default filesystem depends on FlexVolume
+ script.
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ description: 'Optional: Extra command options if any.'
+ type: object
+ readOnly:
+ description: 'Optional: Defaults to false (read/write).
+ ReadOnly here will force the ReadOnly setting in VolumeMounts.'
+ type: boolean
+ secretRef:
+ description: 'Optional: SecretRef is reference to the secret
+ object containing sensitive information to pass to the
+ plugin scripts. This may be empty if no secret object
+ is specified. If the secret object contains more than
+ one secret, all secrets are passed to the plugin scripts.'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ description: Flocker represents a Flocker volume attached to
+ a kubelet's host machine. This depends on the Flocker control
+ service being running
+ properties:
+ datasetName:
+ description: Name of the dataset stored as metadata -> name
+ on the dataset for Flocker should be considered as deprecated
+ type: string
+ datasetUUID:
+ description: UUID of the dataset. This is unique identifier
+ of a Flocker dataset
+ type: string
+ type: object
+ gcePersistentDisk:
+ description: 'GCEPersistentDisk represents a GCE Disk resource
+ that is attached to a kubelet''s host machine and then exposed
+ to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ partition:
+ description: 'The partition in the volume that you want
+ to mount. If omitted, the default is to mount by volume
+ name. Examples: For volume /dev/sda1, you specify the
+ partition as "1". Similarly, the volume partition for
+ /dev/sda is "0" (or you can leave the property empty).
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ format: int32
+ type: integer
+ pdName:
+ description: 'Unique name of the PD resource in GCE. Used
+ to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ description: 'GitRepo represents a git repository at a particular
+ revision. DEPRECATED: GitRepo is deprecated. To provision
+ a container with a git repo, mount an EmptyDir into an InitContainer
+ that clones the repo using git, then mount the EmptyDir into
+ the Pod''s container.'
+ properties:
+ directory:
+ description: Target directory name. Must not contain or
+ start with '..'. If '.' is supplied, the volume directory
+ will be the git repository. Otherwise, if specified,
+ the volume will contain the git repository in the subdirectory
+ with the given name.
+ type: string
+ repository:
+ description: Repository URL
+ type: string
+ revision:
+ description: Commit hash for the specified revision.
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ description: 'Glusterfs represents a Glusterfs mount on the
+ host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md'
+ properties:
+ endpoints:
+ description: 'EndpointsName is the endpoint name that details
+ Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: string
+ path:
+ description: 'Path is the Glusterfs volume path. More info:
+ https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the Glusterfs volume
+ to be mounted with read-only permissions. Defaults to
+ false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ description: 'HostPath represents a pre-existing file or directory
+ on the host machine that is directly exposed to the container.
+ This is generally used for system agents or other privileged
+ things that are allowed to see the host machine. Most containers
+ will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath
+ --- TODO(jonesdl) We need to restrict who can use host directory
+ mounts and who can/can not mount host directories as read/write.'
+ properties:
+ path:
+ description: 'Path of the directory on the host. If the
+ path is a symlink, it will follow the link to the real
+ path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
+ type: string
+ type:
+ description: 'Type for HostPath Volume Defaults to "" More
+ info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ description: 'ISCSI represents an ISCSI Disk resource that is
+ attached to a kubelet''s host machine and then exposed to
+ the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md'
+ properties:
+ chapAuthDiscovery:
+ description: whether support iSCSI Discovery CHAP authentication
+ type: boolean
+ chapAuthSession:
+ description: whether support iSCSI Session CHAP authentication
+ type: boolean
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ initiatorName:
+ description: Custom iSCSI Initiator Name. If initiatorName
+ is specified with iscsiInterface simultaneously, new iSCSI
+ interface <target portal>:<volume name> will be created
+ for the connection.
+ type: string
+ iqn:
+ description: Target iSCSI Qualified Name.
+ type: string
+ iscsiInterface:
+ description: iSCSI Interface Name that uses an iSCSI transport.
+ Defaults to 'default' (tcp).
+ type: string
+ lun:
+ description: iSCSI Target Lun number.
+ format: int32
+ type: integer
+ portals:
+ description: iSCSI Target Portal List. The portal is either
+ an IP or ip_addr:port if the port is other than default
+ (typically TCP ports 860 and 3260).
+ items:
+ type: string
+ type: array
+ readOnly:
+ description: ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false.
+ type: boolean
+ secretRef:
+ description: CHAP Secret for iSCSI target and initiator
+ authentication
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ targetPortal:
+ description: iSCSI Target Portal. The Portal is either an
+ IP or ip_addr:port if the port is other than default (typically
+ TCP ports 860 and 3260).
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ description: 'Volume''s name. Must be a DNS_LABEL and unique
+ within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
+ type: string
+ nfs:
+ description: 'NFS represents an NFS mount on the host that shares
+ a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ properties:
+ path:
+ description: 'Path that is exported by the NFS server. More
+ info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the NFS export to
+ be mounted with read-only permissions. Defaults to false.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: boolean
+ server:
+ description: 'Server is the hostname or IP address of the
+ NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ description: 'PersistentVolumeClaimVolumeSource represents a
+ reference to a PersistentVolumeClaim in the same namespace.
+ More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ properties:
+ claimName:
+ description: 'ClaimName is the name of a PersistentVolumeClaim
+ in the same namespace as the pod using this volume. More
+ info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
+ type: string
+ readOnly:
+ description: Will force the ReadOnly setting in VolumeMounts.
+ Default false.
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ description: PhotonPersistentDisk represents a PhotonController
+ persistent disk attached and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ pdID:
+ description: ID that identifies Photon Controller persistent
+ disk
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ description: PortworxVolume represents a portworx volume attached
+ and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: FSType represents the filesystem type to mount
+ Must be a filesystem type supported by the host operating
+ system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4"
+ if unspecified.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ volumeID:
+ description: VolumeID uniquely identifies a Portworx volume
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ description: Items for all in one resources secrets, configmaps,
+ and downward API
+ properties:
+ defaultMode:
+ description: Mode bits used to set permissions on created
+ files by default. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML accepts
+ both octal and decimal values, JSON requires decimal values
+ for mode bits. Directories within the path are not affected
+ by this setting. This might be in conflict with other
+ options that affect the file mode, like fsGroup, and the
+ result can be other mode bits set.
+ format: int32
+ type: integer
+ sources:
+ description: list of volume projections
+ items:
+ description: Projection that may be projected along with
+ other supported volume types
+ properties:
+ configMap:
+ description: information about the configMap data
+ to project
+ properties:
+ items:
+ description: If unspecified, each key-value pair
+ in the Data field of the referenced ConfigMap
+ will be projected into the volume as a file
+ whose name is the key and content is the value.
+ If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys
+ will not be present. If a key is specified which
+ is not present in the ConfigMap, the volume
+ setup will error unless it is marked optional.
+ Paths must be relative and may not contain the
+ '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within
+ a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file. Must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file
+ to map the key to. May not be an absolute
+ path. May not contain the path element
+ '..'. May not start with the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or
+ its keys must be defined
+ type: boolean
+ type: object
+ downwardAPI:
+ description: information about the downwardAPI data
+ to project
+ properties:
+ items:
+ description: Items is a list of DownwardAPIVolume
+ file
+ items:
+ description: DownwardAPIVolumeFile represents
+ information to create the file containing
+ the pod field
+ properties:
+ fieldRef:
+ description: 'Required: Selects a field
+ of the pod: only annotations, labels,
+ name and namespace are supported.'
+ properties:
+ apiVersion:
+ description: Version of the schema the
+ FieldPath is written in terms of,
+ defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select
+ in the specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file, must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: 'Required: Path is the relative
+ path name of the file to be created. Must
+ not be absolute or contain the ''..''
+ path. Must be utf-8 encoded. The first
+ item of the relative path must not start
+ with ''..'''
+ type: string
+ resourceFieldRef:
+ description: 'Selects a resource of the
+ container: only resources limits and requests
+ (limits.cpu, limits.memory, requests.cpu
+ and requests.memory) are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required
+ for volumes, optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format
+ of the exposed resources, defaults
+ to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to
+ select'
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ description: information about the secret data to
+ project
+ properties:
+ items:
+ description: If unspecified, each key-value pair
+ in the Data field of the referenced Secret will
+ be projected into the volume as a file whose
+ name is the key and content is the value. If
+ specified, the listed keys will be projected
+ into the specified paths, and unlisted keys
+ will not be present. If a key is specified which
+ is not present in the Secret, the volume setup
+ will error unless it is marked optional. Paths
+ must be relative and may not contain the '..'
+ path or start with '..'.
+ items:
+ description: Maps a string key to a path within
+ a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to
+ set permissions on this file. Must be
+ an octal value between 0000 and 0777 or
+ a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values,
+ JSON requires decimal values for mode
+ bits. If not specified, the volume defaultMode
+ will be used. This might be in conflict
+ with other options that affect the file
+ mode, like fsGroup, and the result can
+ be other mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file
+ to map the key to. May not be an absolute
+ path. May not contain the path element
+ '..'. May not start with the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ description: 'Name of the referent. More info:
+ https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its
+ key must be defined
+ type: boolean
+ type: object
+ serviceAccountToken:
+ description: information about the serviceAccountToken
+ data to project
+ properties:
+ audience:
+ description: Audience is the intended audience
+ of the token. A recipient of a token must identify
+ itself with an identifier specified in the audience
+ of the token, and otherwise should reject the
+ token. The audience defaults to the identifier
+ of the apiserver.
+ type: string
+ expirationSeconds:
+ description: ExpirationSeconds is the requested
+ duration of validity of the service account
+ token. As the token approaches expiration, the
+ kubelet volume plugin will proactively rotate
+ the service account token. The kubelet will
+ start trying to rotate the token if the token
+ is older than 80 percent of its time to live
+ or if the token is older than 24 hours.Defaults
+ to 1 hour and must be at least 10 minutes.
+ format: int64
+ type: integer
+ path:
+ description: Path is the path relative to the
+ mount point of the file to project the token
+ into.
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ description: Quobyte represents a Quobyte mount on the host
+ that shares a pod's lifetime
+ properties:
+ group:
+ description: Group to map volume access to Default is no
+ group
+ type: string
+ readOnly:
+ description: ReadOnly here will force the Quobyte volume
+ to be mounted with read-only permissions. Defaults to
+ false.
+ type: boolean
+ registry:
+ description: Registry represents a single or multiple Quobyte
+ Registry services specified as a string as host:port pair
+ (multiple entries are separated with commas) which acts
+ as the central registry for volumes
+ type: string
+ tenant:
+ description: Tenant owning the given Quobyte volume in the
+ Backend Used with dynamically provisioned Quobyte volumes,
+ value is set by the plugin
+ type: string
+ user:
+ description: User to map volume access to Defaults to serivceaccount
+ user
+ type: string
+ volume:
+ description: Volume is a string that references an already
+ created Quobyte volume by name.
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ description: 'RBD represents a Rados Block Device mount on the
+ host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md'
+ properties:
+ fsType:
+ description: 'Filesystem type of the volume that you want
+ to mount. Tip: Ensure that the filesystem type is supported
+ by the host operating system. Examples: "ext4", "xfs",
+ "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
+ TODO: how do we prevent errors in the filesystem from
+ compromising the machine'
+ type: string
+ image:
+ description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ keyring:
+ description: 'Keyring is the path to key ring for RBDUser.
+ Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ monitors:
+ description: 'A collection of Ceph monitors. More info:
+ https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ items:
+ type: string
+ type: array
+ pool:
+ description: 'The rados pool name. Default is rbd. More
+ info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ readOnly:
+ description: 'ReadOnly here will force the ReadOnly setting
+ in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: boolean
+ secretRef:
+ description: 'SecretRef is name of the authentication secret
+ for RBDUser. If provided overrides keyring. Default is
+ nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ user:
+ description: 'The rados user name. Default is admin. More
+ info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ description: ScaleIO represents a ScaleIO persistent volume
+ attached and mounted on Kubernetes nodes.
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Default is "xfs".
+ type: string
+ gateway:
+ description: The host address of the ScaleIO API Gateway.
+ type: string
+ protectionDomain:
+ description: The name of the ScaleIO Protection Domain for
+ the configured storage.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretRef:
+ description: SecretRef references to the secret for ScaleIO
+ user and other sensitive information. If this is not provided,
+ Login operation will fail.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ sslEnabled:
+ description: Flag to enable/disable SSL communication with
+ Gateway, default false
+ type: boolean
+ storageMode:
+ description: Indicates whether the storage for a volume
+ should be ThickProvisioned or ThinProvisioned. Default
+ is ThinProvisioned.
+ type: string
+ storagePool:
+ description: The ScaleIO Storage Pool associated with the
+ protection domain.
+ type: string
+ system:
+ description: The name of the storage system as configured
+ in ScaleIO.
+ type: string
+ volumeName:
+ description: The name of a volume already created in the
+ ScaleIO system that is associated with this volume source.
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ description: 'Secret represents a secret that should populate
+ this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
+ properties:
+ defaultMode:
+ description: 'Optional: mode bits used to set permissions
+ on created files by default. Must be an octal value between
+ 0000 and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires decimal
+ values for mode bits. Defaults to 0644. Directories within
+ the path are not affected by this setting. This might
+ be in conflict with other options that affect the file
+ mode, like fsGroup, and the result can be other mode bits
+ set.'
+ format: int32
+ type: integer
+ items:
+ description: If unspecified, each key-value pair in the
+ Data field of the referenced Secret will be projected
+ into the volume as a file whose name is the key and content
+ is the value. If specified, the listed keys will be projected
+ into the specified paths, and unlisted keys will not be
+ present. If a key is specified which is not present in
+ the Secret, the volume setup will error unless it is marked
+ optional. Paths must be relative and may not contain the
+ '..' path or start with '..'.
+ items:
+ description: Maps a string key to a path within a volume.
+ properties:
+ key:
+ description: The key to project.
+ type: string
+ mode:
+ description: 'Optional: mode bits used to set permissions
+ on this file. Must be an octal value between 0000
+ and 0777 or a decimal value between 0 and 511. YAML
+ accepts both octal and decimal values, JSON requires
+ decimal values for mode bits. If not specified,
+ the volume defaultMode will be used. This might
+ be in conflict with other options that affect the
+ file mode, like fsGroup, and the result can be other
+ mode bits set.'
+ format: int32
+ type: integer
+ path:
+ description: The relative path of the file to map
+ the key to. May not be an absolute path. May not
+ contain the path element '..'. May not start with
+ the string '..'.
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ description: Specify whether the Secret or its keys must
+ be defined
+ type: boolean
+ secretName:
+ description: 'Name of the secret in the pod''s namespace
+ to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
+ type: string
+ type: object
+ storageos:
+ description: StorageOS represents a StorageOS volume attached
+ and mounted on Kubernetes nodes.
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ readOnly:
+ description: Defaults to false (read/write). ReadOnly here
+ will force the ReadOnly setting in VolumeMounts.
+ type: boolean
+ secretRef:
+ description: SecretRef specifies the secret to use for obtaining
+ the StorageOS API credentials. If not specified, default
+ values will be attempted.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ volumeName:
+ description: VolumeName is the human-readable name of the
+ StorageOS volume. Volume names are only unique within
+ a namespace.
+ type: string
+ volumeNamespace:
+ description: VolumeNamespace specifies the scope of the
+ volume within StorageOS. If no namespace is specified
+ then the Pod's namespace will be used. This allows the
+ Kubernetes name scoping to be mirrored within StorageOS
+ for tighter integration. Set VolumeName to any name to
+ override the default behaviour. Set to "default" if you
+ are not using namespaces within StorageOS. Namespaces
+ that do not pre-exist within StorageOS will be created.
+ type: string
+ type: object
+ vsphereVolume:
+ description: VsphereVolume represents a vSphere volume attached
+ and mounted on kubelets host machine
+ properties:
+ fsType:
+ description: Filesystem type to mount. Must be a filesystem
+ type supported by the host operating system. Ex. "ext4",
+ "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+ type: string
+ storagePolicyID:
+ description: Storage Policy Based Management (SPBM) profile
+ ID associated with the StoragePolicyName.
+ type: string
+ storagePolicyName:
+ description: Storage Policy Based Management (SPBM) profile
+ name.
+ type: string
+ volumePath:
+ description: Path that identifies vSphere volume vmdk
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ required:
+ - config
+ - name
+ - type
+ type: object
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml
new file mode 100644
index 0000000..0546c2a
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml
@@ -0,0 +1,411 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: logsinstances.monitoring.grafana.com
+spec:
+ group: monitoring.grafana.com
+ names:
+ categories:
+ - agent-operator
+ kind: LogsInstance
+ listKind: LogsInstanceList
+ plural: logsinstances
+ singular: logsinstance
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: LogsInstance controls an individual logs instance within a Grafana
+ Agent deployment.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Spec holds the specification of the desired behavior for
+ the logs instance.
+ properties:
+ additionalScrapeConfigs:
+ description: "AdditionalScrapeConfigs allows specifying a key of a
+ Secret containing additional Grafana Agent logging scrape configurations.
+ Scrape configurations specified are appended to the configurations
+ generated by the Grafana Agent Operator. \n Job configurations specified
+ must have the form as specified in the official Promtail documentation:
+ \n https://grafana.com/docs/loki/latest/clients/promtail/configuration/#scrape_configs
+ \n 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 Grafana Agent. It is advised to review both
+ Grafana Agent and Promtail release notes to ensure that no incompatible
+ scrape configs are going to break Grafana Agent after the upgrade."
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ clients:
+ description: Clients controls where logs are written to for this instance.
+ items:
+ description: LogsClientSpec defines the client integration for logs,
+ indicating which Loki server to send logs to.
+ properties:
+ backoffConfig:
+ description: Configures how to retry requests to Loki when a
+ request fails. Defaults to a minPeriod of 500ms, maxPeriod
+ of 5m, and maxRetries of 10.
+ properties:
+ maxPeriod:
+ description: Maximum backoff time between retries.
+ type: string
+ maxRetries:
+ description: Maximum number of retries to perform before
+ giving up a request.
+ type: integer
+ minPeriod:
+ description: Initial backoff time between retries. Time
+ between retries is increased exponentially.
+ type: string
+ type: object
+ basicAuth:
+ description: BasicAuth for the Loki server.
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ batchSize:
+ description: Maximum batch size (in bytes) of logs to accumulate
+ before sending the batch to Loki.
+ type: integer
+ batchWait:
+ description: Maximum amount of time to wait before sending a
+ batch, even if that batch isn't full.
+ type: string
+ bearerToken:
+ description: BearerToken used for remote_write.
+ type: string
+ bearerTokenFile:
+ description: BearerTokenFile used to read bearer token.
+ type: string
+ externalLabels:
+ additionalProperties:
+ type: string
+ description: ExternalLabels are labels to add to any time series
+ when sending data to Loki.
+ type: object
+ proxyUrl:
+ description: ProxyURL to proxy requests through. Optional.
+ type: string
+ tenantId:
+ description: Tenant ID used by default to push logs to Loki.
+ If omitted assumes remote Loki is running in single-tenant
+ mode or an authentication layer is used to inject an X-Scope-OrgID
+ header.
+ type: string
+ timeout:
+ description: Maximum time to wait for a server to respond to
+ a request.
+ type: string
+ tlsConfig:
+ description: TLSConfig to use for the client. Only used when
+ the protocol of the URL is https.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ url:
+ description: 'URL is the URL where Loki is listening. Must be
+ a full HTTP URL, including protocol. Required. Example: https://logs-prod-us-central1.grafana.net/loki/api/v1/push.'
+ type: string
+ required:
+ - url
+ type: object
+ type: array
+ podLogsNamespaceSelector:
+ description: Set of labels to determine which namespaces should be
+ watched for PodLogs. If not provided, checks only namespace of the
+ instance.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ podLogsSelector:
+ description: Determines which PodLogs should be selected for including
+ in this instance.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ targetConfig:
+ description: Configures how tailed targets will be watched.
+ properties:
+ syncPeriod:
+ description: Period to resync directories being watched and files
+ being tailed to discover new ones or stop watching removed ones.
+ type: string
+ type: object
+ type: object
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml
new file mode 100644
index 0000000..648ae96
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml
@@ -0,0 +1,751 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: metricsinstances.monitoring.grafana.com
+spec:
+ group: monitoring.grafana.com
+ names:
+ categories:
+ - agent-operator
+ kind: MetricsInstance
+ listKind: MetricsInstanceList
+ plural: metricsinstances
+ singular: metricsinstance
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: MetricsInstance controls an individual Metrics instance within
+ a Grafana Agent deployment.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Spec holds the specification of the desired behavior for
+ the Metrics instance.
+ properties:
+ additionalScrapeConfigs:
+ description: 'AdditionalScrapeConfigs allows specifying a key of a
+ Secret containing additional Grafana Agent Prometheus scrape configurations.
+ SCrape configurations specified are appended to the configurations
+ generated by the Grafana Agent 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 Grafana Agent. It is advised to review both
+ Grafana Agent and Prometheus release notes to ensure that no incompatible
+ scrape configs are going to break Grafana Agent after the upgrade.'
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ maxWALTime:
+ description: MaxWALTime is the maximum amount of time series and asmples
+ may exist in the WAL before being forcibly deleted.
+ type: string
+ minWALTime:
+ description: MinWALTime is the minimum amount of time series and samples
+ may exist in the WAL before being considered for deletion.
+ type: string
+ podMonitorNamespaceSelector:
+ description: PodMonitorNamespaceSelector are the set of labels to
+ determine which namespaces to watch for PodMonitor discovery. If
+ nil, only checks own namespace.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ podMonitorSelector:
+ description: PodMonitorSelector determines which PodMonitors should
+ be selected for target discovery. Experimental.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ probeNamespaceSelector:
+ description: ProbeNamespaceSelector are the set of labels to determine
+ which namespaces to watch for Probe discovery. If nil, only checks
+ own namespace.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ probeSelector:
+ description: ProbeSelector determines which Probes should be selected
+ for target discovery.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ remoteFlushDeadline:
+ description: RemoteFlushDeadline is the deadline for flushing data
+ when an instance shuts down.
+ type: string
+ remoteWrite:
+ description: RemoteWrite controls remote_write settings for this instance.
+ items:
+ description: RemoteWriteSpec defines the remote_write configuration
+ for Prometheus.
+ properties:
+ basicAuth:
+ description: BasicAuth for the URL.
+ properties:
+ password:
+ description: The secret in the service monitor namespace
+ that contains the password for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ username:
+ description: The secret in the service monitor namespace
+ that contains the username for authentication.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ bearerToken:
+ description: BearerToken used for remote_write.
+ type: string
+ bearerTokenFile:
+ description: BearerTokenFile used to read bearer token.
+ type: string
+ headers:
+ additionalProperties:
+ type: string
+ description: Headers is a set of custom HTTP headers to be sent
+ along with each remote_write request. Be aware that any headers
+ set by Grafana Agent itself can't be overwritten.
+ type: object
+ metadataConfig:
+ description: MetadataConfig configures the sending of series
+ metadata to remote storage.
+ properties:
+ send:
+ description: Send enables metric metadata to be sent to
+ remote storage.
+ type: boolean
+ sendInterval:
+ description: SendInterval controls how frequently metric
+ metadata is sent to remote storage.
+ type: string
+ type: object
+ name:
+ description: Name of the remote_write queue. Must be unique
+ if specified. The name is used in metrics and logging in order
+ to differentiate queues.
+ type: string
+ proxyUrl:
+ description: ProxyURL to proxy requests through. Optional.
+ type: string
+ queueConfig:
+ description: QueueConfig allows tuning of the remote_write queue
+ parameters.
+ properties:
+ batchSendDeadline:
+ description: BatchSendDeadline is the maximum time a sample
+ will wait in buffer.
+ type: string
+ capacity:
+ description: Capacity is the number of samples to buffer
+ per shard before we start dropping them.
+ type: integer
+ maxBackoff:
+ description: MaxBackoff is the maximum retry delay.
+ type: string
+ maxRetries:
+ description: MaxRetries is the maximum number of times to
+ retry a batch on recoverable errors.
+ type: integer
+ maxSamplesPerSend:
+ description: MaxSamplesPerSend is the maximum number of
+ samples per send.
+ type: integer
+ maxShards:
+ description: MaxShards is the maximum number of shards,
+ i.e. amount of concurrency.
+ type: integer
+ minBackoff:
+ description: MinBackoff is the initial retry delay. Gets
+ doubled for every retry.
+ type: string
+ minShards:
+ description: MinShards is the minimum number of shards,
+ i.e. amount of concurrency.
+ type: integer
+ retryOnRateLimit:
+ description: RetryOnRateLimit retries requests when encountering
+ rate limits.
+ type: boolean
+ type: object
+ remoteTimeout:
+ description: RemoteTimeout is the timeout for requests to the
+ remote_write endpoint.
+ type: string
+ sigv4:
+ description: SigV4 configures SigV4-based authentication to
+ the remote_write endpoint. Will be used if SigV4 is defined,
+ even with an empty object.
+ properties:
+ accessKey:
+ description: AccessKey holds the secret of the AWS API access
+ key to use for signing. If not provided, The environment
+ variable AWS_ACCESS_KEY_ID is used.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ profile:
+ description: Profile is the named AWS profile to use for
+ authentication.
+ type: string
+ region:
+ description: Region of the AWS endpoint. If blank, the region
+ from the default credentials chain is used.
+ type: string
+ roleARN:
+ description: RoleARN is the AWS Role ARN to use for authentication,
+ as an alternative for using the AWS API keys.
+ type: string
+ secretKey:
+ description: SecretKey of the AWS API to use for signing.
+ If blank, the environment variable AWS_SECRET_ACCESS_KEY
+ is used.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ tlsConfig:
+ description: TLSConfig to use for remote_write.
+ properties:
+ ca:
+ description: Struct containing the CA cert to use for the
+ targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ caFile:
+ description: Path to the CA cert in the Prometheus container
+ to use for the targets.
+ type: string
+ cert:
+ description: Struct containing the client cert file for
+ the targets.
+ properties:
+ configMap:
+ description: ConfigMap containing data to use for the
+ targets.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ secret:
+ description: Secret containing data to use for the targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ certFile:
+ description: Path to the client cert file in the Prometheus
+ container for the targets.
+ type: string
+ insecureSkipVerify:
+ description: Disable target certificate validation.
+ type: boolean
+ keyFile:
+ description: Path to the client key file in the Prometheus
+ container for the targets.
+ type: string
+ keySecret:
+ description: Secret containing the client key file for the
+ targets.
+ 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
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must
+ be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ serverName:
+ description: Used to verify the hostname for the targets.
+ type: string
+ type: object
+ url:
+ description: URL of the endpoint to send samples to.
+ type: string
+ writeRelabelConfigs:
+ description: WriteRelabelConfigs holds relabel_configs to relabel
+ samples before they are sent to the remote_write endpoint.
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the
+ label set, being applied to samples before ingestion. It
+ defines `<metric_relabel_configs>`-section of Prometheus
+ configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching.
+ Default is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source
+ label values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex
+ capture groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source
+ label values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing
+ labels. Their content is concatenated using the configured
+ separator and matched against the configured regular
+ expression for the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name
+ which may only contain ASCII letters, numbers, as
+ well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written
+ in a replace action. It is mandatory for replace actions.
+ Regex capture groups are available.
+ type: string
+ type: object
+ type: array
+ required:
+ - url
+ type: object
+ type: array
+ serviceMonitorNamespaceSelector:
+ description: ServiceMonitorNamespaceSelector are the set of labels
+ to determine which namespaces to watch for ServiceMonitor discovery.
+ If nil, only checks own namespace.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ serviceMonitorSelector:
+ description: ServiceMonitorSelector determines which ServiceMonitors
+ should be selected for target discovery.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ walTruncateFrequency:
+ description: WALTruncateFrequency specifies how frequently the WAL
+ truncation process should run. Higher values causes the WAL to increase
+ and for old series to stay in the WAL for longer, but reduces the
+ chances of data loss when remote_write is failing for longer than
+ the given frequency.
+ type: string
+ writeStaleOnShutdown:
+ description: WriteStaleOnShutdown writes staleness markers on shutdown
+ for all series.
+ type: boolean
+ type: object
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml
new file mode 100644
index 0000000..533e336
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml
@@ -0,0 +1,554 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.8.0
+ creationTimestamp: null
+ name: podlogs.monitoring.grafana.com
+spec:
+ group: monitoring.grafana.com
+ names:
+ categories:
+ - agent-operator
+ kind: PodLogs
+ listKind: PodLogsList
+ plural: podlogs
+ singular: podlogs
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: PodLogs defines how to collect logs for a pod.
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Spec holds the specification of the desired behavior for
+ the PodLogs.
+ properties:
+ jobLabel:
+ description: The label to use to retrieve the job name from.
+ type: string
+ namespaceSelector:
+ description: Selector to select which namespaces the Pod objects are
+ discovered from.
+ properties:
+ any:
+ description: Boolean describing whether all namespaces are selected
+ in contrast to a list restricting them.
+ type: boolean
+ matchNames:
+ description: List of namespace names to select from.
+ items:
+ type: string
+ type: array
+ type: object
+ pipelineStages:
+ description: Pipeline stages for this pod. Pipeline stages allow for
+ transforming and filtering log lines.
+ items:
+ description: "PipelineStageSpec defines an individual pipeline stage.
+ Each stage type is mutually exclusive and no more than one may
+ be set per stage. \n More information on pipelines can be found
+ in the Promtail documentation: https://grafana.com/docs/loki/latest/clients/promtail/pipelines/"
+ properties:
+ cri:
+ description: 'CRI is a parsing stage that reads log lines using
+ the standard CRI logging format. Supply cri: {} to enable.'
+ type: object
+ docker:
+ description: 'Docker is a parsing stage that reads log lines
+ using the standard Docker logging format. Supply docker: {}
+ to enable.'
+ type: object
+ drop:
+ description: Drop is a filtering stage that lets you drop certain
+ logs.
+ properties:
+ dropCounterReason:
+ description: Every time a log line is dropped the metric
+ logentry_dropped_lines_total will be incremented. A "reason"
+ label is added, and can be customized by providing a custom
+ value here. Defaults to "drop_stage."
+ type: string
+ expression:
+ description: "RE2 regular exprssion. \n If source is provided,
+ the regex will attempt to match the source. \n If no source
+ is provided, then the regex will attempt to attach the
+ log line. \n If the provided regex matches the log line
+ or a provided source, the line will be dropped."
+ type: string
+ longerThan:
+ description: LongerThan will drop a log line if it its content
+ is longer than this value (in bytes). Can be expressed
+ as an integer (8192) or a number with a suffix (8kb).
+ type: string
+ olderThan:
+ description: OlderThan will be parsed as a Go duration.
+ If the log line's timestamp is older than the current
+ time minus the provided duration it will be dropped.
+ type: string
+ source:
+ description: Name from the extract data to parse. If empty,
+ uses the log message.
+ type: string
+ value:
+ description: "Value can only be specified when source is
+ specified. If the value provided is an exact match for
+ the given source then the line will be dropped. \n Mutually
+ exclusive with expression."
+ type: string
+ type: object
+ json:
+ description: "JSON is a parsing stage that reads the log line
+ as JSON and accepts JMESPath expressions to extract data.
+ \n Information on JMESPath: http://jmespath.org/"
+ properties:
+ expressions:
+ additionalProperties:
+ type: string
+ description: "Set of the key/value pairs of JMESPath expressions.
+ The key will be the key in the extracted data while the
+ expression will be the value, evaluated as a JMESPath
+ from the source data. \n Literal JMESPath exprssions can
+ be done by wrapping a key in double quotes, which then
+ must be wrapped again in single quotes in YAML so they
+ get passed to the JMESPath parser."
+ type: object
+ source:
+ description: Name from the extracted data to parse as JSON.
+ If empty, uses entire log message.
+ type: string
+ type: object
+ labelAllow:
+ description: LabelAllow is an action stage that only allows
+ the provided labels to be included in the label set that is
+ sent to Loki with the log entry.
+ items:
+ type: string
+ type: array
+ labelDrop:
+ description: LabelDrop is an action stage that drops labels
+ from the label set that is sent to Loki with the log entry.
+ items:
+ type: string
+ type: array
+ labels:
+ additionalProperties:
+ type: string
+ description: "Labels is an action stage that takes data from
+ the extracted map and modifies the label set that is sent
+ to Loki with the log entry. \n The key is REQUIRED and represents
+ the name for the label that will be created. Value is optional
+ and will be the name from extracted data to use for the value
+ of the label. If the value is not provided, it defaults to
+ match the key."
+ type: object
+ match:
+ description: Match is a filtering stage that conditionally applies
+ a set of stages or drop entries when a log entry matches a
+ configurable LogQL stream selector and filter expressions.
+ properties:
+ action:
+ description: Determines what action is taken when the selector
+ matches the log line. Can be keep or drop. Defaults to
+ keep. When set to drop, entries will be dropped and no
+ later metrics will be recorded. Stages must be empty when
+ dropping metrics.
+ type: string
+ dropCounterReason:
+ description: Every time a log line is dropped the metric
+ logentry_dropped_lines_total will be incremented. A "reason"
+ label is added, and can be customized by providing a custom
+ value here. Defaults to "match_stage."
+ type: string
+ pipelineName:
+ description: Names the pipeline. When defined, creates an
+ additional label in the pipeline_duration_seconds histogram,
+ where the value is concatenated with job_name using an
+ underscore.
+ type: string
+ selector:
+ description: LogQL stream selector and filter expressions.
+ Required.
+ type: string
+ stages:
+ description: "Nested set of pipeline stages to execute when
+ action: keep and the log line matches selector. \n An
+ example value for stages may be: \n stages: | - json:
+ {} - labelAllow: [foo, bar] \n Note that stages is a string
+ because SIG API Machinery does not support recursive types,
+ and so it cannot be validated for correctness. Be careful
+ not to mistype anything."
+ type: string
+ required:
+ - selector
+ type: object
+ metrics:
+ additionalProperties:
+ description: MetricsStageSpec is an action stage that allows
+ for defining and updating metrics based on data from the
+ extracted map. Created metrics are not pushed to Loki or
+ Prometheus and are instead exposed via the /metrics endpoint
+ of the Grafana Agent pod. The Grafana Agent Operator should
+ be configured with a MetricsInstance that discovers the
+ logging DaemonSet to collect metrics created by this stage.
+ properties:
+ action:
+ description: "The action to take against the metric. Required.
+ \n Must be either \"inc\" or \"add\" for type: counter
+ or type: histogram. When type: gauge, must be one of
+ \"set\", \"inc\", \"dec\", \"add\", or \"sub\". \n \"add\",
+ \"set\", or \"sub\" requires the extracted value to
+ be convertible to a positive float."
+ type: string
+ buckets:
+ description: 'Buckets to create. Bucket values must be
+ convertible to float64s. Extremely large or small numbers
+ are subject to some loss of precision. Only valid for
+ type: histogram.'
+ items:
+ type: string
+ type: array
+ countEntryBytes:
+ description: "If true all log line bytes will be counted.
+ Can only be set with matchAll: true and action: add.
+ \n Only valid for type: counter."
+ type: boolean
+ description:
+ description: Sets the description for the created metric.
+ type: string
+ matchAll:
+ description: "If true all log lines will be counted without
+ attempting to match the source to the extracted map.
+ Mutually exclusive with value. \n Only valid for type:
+ counter."
+ type: boolean
+ maxIdleDuration:
+ description: "Label values on metrics are dynamic which
+ can cause exported metrics to go stale. To prevent unbounded
+ cardinality, any metrics not updated within MaxIdleDuration
+ will be removed. \n Must be greater or equal to 1s.
+ Defaults to 5m."
+ type: string
+ prefix:
+ description: Sets the custom prefix name for the metric.
+ Defaults to "promtail_custom_".
+ type: string
+ source:
+ description: Key from the extracted data map to use for
+ the metric. Defaults to the metrics name if not present.
+ type: string
+ type:
+ description: The metric type to create. Must be one of
+ counter, gauge, histogram. Required.
+ type: string
+ value:
+ description: Filters down source data and only changes
+ the metric if the targeted value exactly matches the
+ provided string. If not present, all data will match.
+ type: string
+ required:
+ - action
+ - type
+ type: object
+ description: Metrics is an action stage that allows for defining
+ and updating metrics based on data from the extracted map.
+ Created metrics are not pushed to Loki or Prometheus and are
+ instead exposed via the /metrics endpoint of the Grafana Agent
+ pod. The Grafana Agent Operator should be configured with
+ a MetricsInstance that discovers the logging DaemonSet to
+ collect metrics created by this stage.
+ type: object
+ multiline:
+ description: Multiline stage merges multiple lines into a multiline
+ block before passing it on to the next stage in the pipeline.
+ properties:
+ firstLine:
+ description: RE2 regular expression. Creates a new multiline
+ block when matched. Required.
+ type: string
+ maxLines:
+ description: Maximum number of lines a block can have. A
+ new block is started if the number of lines surpasses
+ this value. Defaults to 128.
+ type: integer
+ maxWaitTime:
+ description: Maximum time to wait before passing on the
+ multiline block to the next stage if no new lines are
+ received. Defaults to 3s.
+ type: string
+ required:
+ - firstLine
+ type: object
+ output:
+ description: Output stage is an action stage that takes data
+ from the extracted map and changes the log line that will
+ be sent to Loki.
+ properties:
+ source:
+ description: Name from extract data to use for the log entry.
+ Required.
+ type: string
+ required:
+ - source
+ type: object
+ pack:
+ description: Pack is a transform stage that lets you embed extracted
+ values and labels into the log line by packing the log line
+ and labels inside of a JSON object.
+ properties:
+ ingestTimestamp:
+ description: If the resulting log line should use any existing
+ timestamp or use time.Now() when the line was created.
+ Set to true when combining several log streams from different
+ containers to avoid out of order errors.
+ type: boolean
+ labels:
+ description: Name from extracted data or line labels. Requiried.
+ Labels provided here are automatically removed from output
+ labels.
+ items:
+ type: string
+ type: array
+ required:
+ - labels
+ type: object
+ regex:
+ description: Regex is a parsing stage that parses a log line
+ using a regular expression. Named capture groups in the regex
+ allows for adding data into the extracted map.
+ properties:
+ expression:
+ description: RE2 regular expression. Each capture group
+ MUST be named. Required.
+ type: string
+ source:
+ description: Name from extracted data to parse. If empty,
+ defaults to using the log message.
+ type: string
+ required:
+ - expression
+ type: object
+ replace:
+ description: Replace is a parsing stage that parses a log line
+ using a regular expression and replaces the log line. Named
+ capture groups in the regex allows for adding data into the
+ extracted map.
+ properties:
+ expression:
+ description: RE2 regular expression. Each capture group
+ MUST be named. Required.
+ type: string
+ replace:
+ description: Value to replace the captured group with.
+ type: string
+ source:
+ description: Name from extracted data to parse. If empty,
+ defaults to using the log message.
+ type: string
+ required:
+ - expression
+ type: object
+ template:
+ description: Template is a transform stage that manipulates
+ the values in the extracted map using Go's template syntax.
+ properties:
+ source:
+ description: Name from extracted data to parse. Required.
+ If empty, defaults to using the log message.
+ type: string
+ template:
+ description: Go template string to use. Required. In additional
+ to normal template functions, ToLower, ToUpper, Replace,
+ Trim, TrimLeft, TrimRight, TrimPrefix, and TrimSpace are
+ also available.
+ type: string
+ required:
+ - source
+ - template
+ type: object
+ tenant:
+ description: Tenant is an action stage that sets the tenant
+ ID for the log entry picking it from a field in the extracted
+ data map. If the field is missing, the default LogsClientSpec.tenantId
+ will be used.
+ properties:
+ source:
+ description: Name from extracted data to use as the tenant
+ ID. Mutually exclusive with value.
+ type: string
+ value:
+ description: Value to use for the template ID. Useful when
+ this stage is used within a conditional pipeline such
+ as match. Mutually exclusive with source.
+ type: string
+ type: object
+ timestamp:
+ description: Timestamp is an action stage that can change the
+ timestamp of a log line before it is sent to Loki. If not
+ present, the timestamp of a log line defaults to the time
+ when the log line was read.
+ properties:
+ actionOnFailure:
+ description: Action to take when the timestamp can't be
+ extracted or parsed. Can be skip or fudge. Defaults to
+ fudge.
+ type: string
+ fallbackFormats:
+ description: Fallback formats to try if format fails.
+ items:
+ type: string
+ type: array
+ format:
+ description: 'Determines format of the time string. Required.
+ Can be one of: ANSIC, UnixDate, RubyDate, RFC822, RFC822Z,
+ RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Unix,
+ UnixMs, UnixUs, UnixNs.'
+ type: string
+ location:
+ description: IANA Timezone Database string.
+ type: string
+ source:
+ description: Name from extracted data to use as the timestamp.
+ Required.
+ type: string
+ required:
+ - format
+ - source
+ type: object
+ type: object
+ type: array
+ podTargetLabels:
+ description: PodTargetLabels transfers labels on the Kubernetes Pod
+ onto the target.
+ items:
+ type: string
+ type: array
+ relabelings:
+ description: "RelabelConfigs to apply to logs before delivering. Grafana
+ Agent Operator automatically adds relabelings for a few standard
+ Kubernetes fields and replaces original scrape job name with __tmp_logs_job_name.
+ \n More info: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#relabel_configs"
+ items:
+ description: 'RelabelConfig allows dynamic rewriting of the label
+ set, being applied to samples before ingestion. It defines `<metric_relabel_configs>`-section
+ of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
+ properties:
+ action:
+ default: replace
+ description: Action to perform based on regex matching. Default
+ is 'replace'
+ enum:
+ - replace
+ - keep
+ - drop
+ - hashmod
+ - labelmap
+ - labeldrop
+ - labelkeep
+ type: string
+ modulus:
+ description: Modulus to take of the hash of the source label
+ values.
+ format: int64
+ type: integer
+ regex:
+ description: Regular expression against which the extracted
+ value is matched. Default is '(.*)'
+ type: string
+ replacement:
+ description: Replacement value against which a regex replace
+ is performed if the regular expression matches. Regex capture
+ groups are available. Default is '$1'
+ type: string
+ separator:
+ description: Separator placed between concatenated source label
+ values. default is ';'.
+ type: string
+ sourceLabels:
+ description: The source labels select values from existing labels.
+ Their content is concatenated using the configured separator
+ and matched against the configured regular expression for
+ the replace, keep, and drop actions.
+ items:
+ description: LabelName is a valid Prometheus label name which
+ may only contain ASCII letters, numbers, as well as underscores.
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
+ type: string
+ type: array
+ targetLabel:
+ description: Label to which the resulting value is written in
+ a replace action. It is mandatory for replace actions. Regex
+ capture groups are available.
+ type: string
+ type: object
+ type: array
+ selector:
+ description: Selector to select Pod objects. Required.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: A label selector requirement is a selector that
+ contains values, a key, and an operator that relates the key
+ and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: operator represents a key's relationship to
+ a set of values. Valid operators are In, NotIn, Exists
+ and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string values. If the
+ operator is In or NotIn, the values array must be non-empty.
+ If the operator is Exists or DoesNotExist, the values
+ array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value} pairs. A single
+ {key,value} in the matchLabels map is equivalent to an element
+ of matchExpressions, whose key field is "key", the operator
+ is "In", and the values array contains only "value". The requirements
+ are ANDed.
+ type: object
+ type: object
+ required:
+ - selector
+ type: object
+ type: object
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl b/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl
new file mode 100644
index 0000000..f464671
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl
@@ -0,0 +1,67 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "ga-operator.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "ga-operator.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "ga-operator.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "ga-operator.labels" -}}
+{{ include "ga-operator.selectorLabels" . }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+app.kubernetes.io/component: operator
+helm.sh/chart: {{ include "ga-operator.chart" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+{{- if .Values.customLabels }}
+{{ toYaml .Values.customLabels }}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "ga-operator.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "ga-operator.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "ga-operator.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "ga-operator.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml
new file mode 100644
index 0000000..aad0c89
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml
@@ -0,0 +1,55 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "ga-operator.fullname" . }}
+ labels:
+{{ include "ga-operator.labels" . | indent 4 }}
+rules:
+- apiGroups: [monitoring.grafana.com]
+ resources:
+ - grafanaagents
+ - metricsinstances
+ - logsinstances
+ - podlogs
+ - integrations
+ verbs: [get, list, watch]
+- apiGroups: [monitoring.grafana.com]
+ resources:
+ - grafanaagents/finalizers
+ - metricsinstances/finalizers
+ - logsinstances/finalizers
+ - podlogs/finalizers
+ - integrations/finalizers
+ verbs: [get, list, watch, update]
+- apiGroups: [monitoring.coreos.com]
+ resources:
+ - podmonitors
+ - probes
+ - servicemonitors
+ verbs: [get, list, watch]
+- apiGroups: [monitoring.coreos.com]
+ resources:
+ - podmonitors/finalizers
+ - probes/finalizers
+ - servicemonitors/finalizers
+ verbs: [get, list, watch, update]
+- apiGroups: [""]
+ resources:
+ - namespaces
+ - nodes
+ verbs: [get, list, watch]
+- apiGroups: [""]
+ resources:
+ - secrets
+ - services
+ - configmaps
+ - endpoints
+ verbs: [get, list, watch, create, update, patch, delete]
+- apiGroups: ["apps"]
+ resources:
+ - statefulsets
+ - daemonsets
+ - deployments
+ verbs: [get, list, watch, create, update, patch, delete]
+{{- end -}}
diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml
new file mode 100644
index 0000000..372d310
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "ga-operator.fullname" . }}
+ labels:
+{{ include "ga-operator.labels" . | indent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "ga-operator.fullname" . }}
+subjects:
+- kind: ServiceAccount
+ name: {{ template "ga-operator.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end -}}
+
diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml
new file mode 100644
index 0000000..d83087c
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml
@@ -0,0 +1,67 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "ga-operator.fullname" . }}
+ labels:
+{{ include "ga-operator.labels" . | indent 4 }}
+ {{- with .Values.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+{{ include "ga-operator.selectorLabels" . | indent 6 }}
+ template:
+ metadata:
+ labels:
+{{ include "ga-operator.selectorLabels" . | indent 8 }}
+{{- with .Values.podLabels }}
+{{- toYaml . | nindent 8 }}
+{{- end }}
+{{- with .Values.podAnnotations }}
+ annotations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+ spec:
+ serviceAccountName: {{ template "ga-operator.serviceAccountName" . }}
+ {{- with .Values.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: {{ include "ga-operator.name" . }}
+ image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ {{- with .Values.resources }}
+ resources:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- if or (and .Values.kubeletService.namespace .Values.kubeletService.serviceName) (.Values.extraArgs) }}
+ args:
+ {{- if and .Values.kubeletService.namespace .Values.kubeletService.serviceName }}
+ - --kubelet-service={{ .Values.kubeletService.namespace }}/{{ .Values.kubeletService.serviceName }}
+ {{- end }}
+ {{- if .Values.extraArgs }}
+ {{- range .Values.extraArgs }}
+ - {{ . }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.image.pullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml
new file mode 100644
index 0000000..f8125e8
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml
@@ -0,0 +1,9 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "ga-operator.serviceAccountName" . }}
+ labels:
+{{ include "ga-operator.labels" . | indent 4 }}
+{{- end -}}
+
diff --git a/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml b/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml
new file mode 100644
index 0000000..9e9d913
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml
@@ -0,0 +1,118 @@
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: GrafanaAgent
+metadata:
+ name: grafana-agent-test
+ labels:
+ app: grafana-agent-test
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+spec:
+ image: "{{ .Values.image.registry }}/grafana/agent:{{ .Values.image.tag }}"
+ logLevel: info
+ serviceAccountName: grafana-agent-test-sa
+ metrics:
+ instanceSelector:
+ matchLabels:
+ agent: grafana-agent-test
+
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: grafana-agent-test-sa
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: grafana-agent-test-cr
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - nodes
+ - nodes/proxy
+ - nodes/metrics
+ - services
+ - endpoints
+ - pods
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - networking.k8s.io
+ resources:
+ - ingresses
+ verbs:
+ - get
+ - list
+ - watch
+- nonResourceURLs:
+ - /metrics
+ - /metrics/cadvisor
+ verbs:
+ - get
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: grafana-agent-test-crb
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: grafana-agent-test-cr
+subjects:
+- kind: ServiceAccount
+ name: grafana-agent-test-sa
+ namespace: {{ .Release.Namespace }}
+
+---
+
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: MetricsInstance
+metadata:
+ name: primary-test
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+ labels:
+ agent: grafana-agent-test
+spec: {}
+
+---
+
+apiVersion: v1
+kind: Pod
+metadata:
+ name: grafana-agent-test-probe
+ annotations:
+ "helm.sh/hook": test
+ "helm.sh/hook-weight": "1"
+ "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed
+spec:
+ containers:
+ - name: busybox
+ image: busybox
+ command: ['wget']
+ args: ['grafana-agent-test-operated:8080/-/healthy']
+ # Wait for GrafanaAgent CR
+ initContainers:
+ - name: sleep
+ image: busybox
+ command: ['sleep', '60']
+ restartPolicy: Never
diff --git a/charts/loki/charts/grafana-agent-operator/values.yaml b/charts/loki/charts/grafana-agent-operator/values.yaml
new file mode 100644
index 0000000..3d69c60
--- /dev/null
+++ b/charts/loki/charts/grafana-agent-operator/values.yaml
@@ -0,0 +1,60 @@
+# -- Overrides the chart's name
+nameOverride: ""
+
+# -- Overrides the chart's computed fullname
+fullnameOverride: ""
+
+# -- Annotations for the Deployment
+annotations: {}
+
+# -- Annotations for the Deployment Pods
+podAnnotations: {}
+
+# -- Annotations for the Deployment Pods
+podLabels: {}
+
+# -- Pod security context (runAsUser, etc.)
+podSecurityContext: {}
+
+# -- Toggle to create ClusterRole and ClusterRoleBinding
+rbac:
+ create: true
+
+serviceAccount:
+ # -- Toggle to create ServiceAccount
+ create: true
+ # -- Service account name
+ name:
+
+image:
+ # -- Image registry
+ registry: docker.io
+ # -- Image repo
+ repository: grafana/agent-operator
+ # -- Image tag
+ tag: v0.25.1
+ # -- Image pull policy
+ pullPolicy: IfNotPresent
+ # -- Image pull secrets
+ pullSecrets: []
+
+# -- If both are set, Agent Operator will create and maintain a service for scraping kubelets
+# https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets
+kubeletService:
+ namespace: default
+ serviceName: kubelet
+
+# -- List of additional cli arguments to configure agent-operator (example: `--log.level`)
+extraArgs: []
+
+# -- Resource limits and requests config
+resources: {}
+
+# -- nodeSelector configuration
+nodeSelector: {}
+
+# -- Tolerations applied to Pods
+tolerations: []
+
+# -- Pod affinity configuration
+affinity: {}
diff --git a/charts/loki/charts/minio/.helmignore b/charts/loki/charts/minio/.helmignore
new file mode 100644
index 0000000..a9fe727
--- /dev/null
+++ b/charts/loki/charts/minio/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+# OWNERS file for Kubernetes
+OWNERS
\ No newline at end of file
diff --git a/charts/loki/charts/minio/Chart.yaml b/charts/loki/charts/minio/Chart.yaml
new file mode 100644
index 0000000..67824a4
--- /dev/null
+++ b/charts/loki/charts/minio/Chart.yaml
@@ -0,0 +1,18 @@
+apiVersion: v1
+appVersion: RELEASE.2022-08-13T21-54-44Z
+description: Multi-Cloud Object Storage
+home: https://min.io
+icon: https://min.io/resources/img/logo/MINIO_wordmark.png
+keywords:
+- minio
+- storage
+- object-storage
+- s3
+- cluster
+maintainers:
+- email: dev@minio.io
+ name: MinIO, Inc
+name: minio
+sources:
+- https://github.com/minio/minio
+version: 4.0.12
diff --git a/charts/loki/charts/minio/README.md b/charts/loki/charts/minio/README.md
new file mode 100644
index 0000000..898dcfa
--- /dev/null
+++ b/charts/loki/charts/minio/README.md
@@ -0,0 +1,236 @@
+# MinIO Helm Chart
+
+[](https://slack.min.io) [](https://github.com/minio/minio/blob/master/LICENSE)
+
+MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads.
+
+For more detailed documentation please visit [here](https://docs.minio.io/)
+
+## Introduction
+
+This chart bootstraps MinIO Cluster on [Kubernetes](http://kubernetes.io) using the [Helm](https://helm.sh) package manager.
+
+## Prerequisites
+
+- Helm cli with Kubernetes cluster configured.
+- PV provisioner support in the underlying infrastructure. (We recommend using <https://github.com/minio/direct-csi>)
+- Use Kubernetes version v1.19 and later for best experience.
+
+## Configure MinIO Helm repo
+
+```bash
+helm repo add minio https://charts.min.io/
+```
+
+### Installing the Chart
+
+Install this chart using:
+
+```bash
+helm install --namespace minio --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio
+```
+
+The command deploys MinIO on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
+
+### Upgrading the Chart
+
+You can use Helm to update MinIO version in a live release. Assuming your release is named as `my-release`, get the values using the command:
+
+```bash
+helm get values my-release > old_values.yaml
+```
+
+Then change the field `image.tag` in `old_values.yaml` file with MinIO image tag you want to use. Now update the chart using
+
+```bash
+helm upgrade -f old_values.yaml my-release minio/minio
+```
+
+Default upgrade strategies are specified in the `values.yaml` file. Update these fields if you'd like to use a different strategy.
+
+### Configuration
+
+Refer the [Values file](./values.yaml) for all the possible config fields.
+
+You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
+
+```bash
+helm install --name my-release --set persistence.size=1Ti minio/minio
+```
+
+The above command deploys MinIO server with a 1Ti backing persistent volume.
+
+Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example,
+
+```bash
+helm install --name my-release -f values.yaml minio/minio
+```
+
+### Persistence
+
+This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by:
+
+```bash
+helm install --set persistence.enabled=false minio/minio
+```
+
+> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."*
+
+### Existing PersistentVolumeClaim
+
+If a Persistent Volume Claim already exists, specify it during installation.
+
+1. Create the PersistentVolume
+2. Create the PersistentVolumeClaim
+3. Install the chart
+
+```bash
+helm install --set persistence.existingClaim=PVC_NAME minio/minio
+```
+
+### NetworkPolicy
+
+To enable network policy for MinIO,
+install [a networking plugin that implements the Kubernetes
+NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin),
+and set `networkPolicy.enabled` to `true`.
+
+For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting
+the DefaultDeny namespace annotation. Note: this will enforce policy for *all* pods in the namespace:
+
+```
+kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}"
+```
+
+With NetworkPolicy enabled, traffic will be limited to just port 9000.
+
+For more precise policy, set `networkPolicy.allowExternal=true`. This will
+only allow pods with the generated client label to connect to MinIO.
+This label will be displayed in the output of a successful install.
+
+### Existing secret
+
+Instead of having this chart create the secret for you, you can supply a preexisting secret, much
+like an existing PersistentVolumeClaim.
+
+First, create the secret:
+
+```bash
+kubectl create secret generic my-minio-secret --from-literal=rootUser=foobarbaz --from-literal=rootPassword=foobarbazqux
+```
+
+Then install the chart, specifying that you want to use an existing secret:
+
+```bash
+helm install --set existingSecret=my-minio-secret minio/minio
+```
+
+The following fields are expected in the secret:
+
+| .data.\<key\> in Secret | Corresponding variable | Description | Required |
+|:------------------------|:-----------------------|:---------------|:---------|
+| `rootUser` | `rootUser` | Root user. | yes |
+| `rootPassword` | `rootPassword` | Root password. | yes |
+
+All corresponding variables will be ignored in values file.
+
+### Configure TLS
+
+To enable TLS for MinIO containers, acquire TLS certificates from a CA or create self-signed certificates. While creating / acquiring certificates ensure the corresponding domain names are set as per the standard [DNS naming conventions](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity) in a Kubernetes StatefulSet (for a distributed MinIO setup). Then create a secret using
+
+```bash
+kubectl create secret generic tls-ssl-minio --from-file=path/to/private.key --from-file=path/to/public.crt
+```
+
+Then install the chart, specifying that you want to use the TLS secret:
+
+```bash
+helm install --set tls.enabled=true,tls.certSecret=tls-ssl-minio minio/minio
+```
+
+### Installing certificates from third party CAs
+
+MinIO can connect to other servers, including MinIO nodes or other server types such as NATs and Redis. If these servers use certificates that were not registered with a known CA, add trust for these certificates to MinIO Server by bundling these certificates into a Kubernetes secret and providing it to Helm via the `trustedCertsSecret` value. If `.Values.tls.enabled` is `true` and you're installing certificates for third party CAs, remember to include MinIO's own certificate with key `public.crt`, if it also needs to be trusted.
+
+For instance, given that TLS is enabled and you need to add trust for MinIO's own CA and for the CA of a Keycloak server, a Kubernetes secret can be created from the certificate files using `kubectl`:
+
+```
+kubectl -n minio create secret generic minio-trusted-certs --from-file=public.crt --from-file=keycloak.crt
+```
+
+If TLS is not enabled, you would need only the third party CA:
+
+```
+kubectl -n minio create secret generic minio-trusted-certs --from-file=keycloak.crt
+```
+
+The name of the generated secret can then be passed to Helm using a values file or the `--set` parameter:
+
+```
+trustedCertsSecret: "minio-trusted-certs"
+
+or
+
+--set trustedCertsSecret=minio-trusted-certs
+```
+
+### Create buckets after install
+
+Install the chart, specifying the buckets you want to create after install:
+
+```bash
+helm install --set buckets[0].name=bucket1,buckets[0].policy=none,buckets[0].purge=false minio/minio
+```
+
+Description of the configuration parameters used above -
+
+- `buckets[].name` - name of the bucket to create, must be a string with length > 0
+- `buckets[].policy` - can be one of none|download|upload|public
+- `buckets[].purge` - purge if bucket exists already
+
+### Create policies after install
+
+Install the chart, specifying the policies you want to create after install:
+
+```bash
+helm install --set policies[0].name=mypolicy,policies[0].statements[0].resources[0]='arn:aws:s3:::bucket1',policies[0].statements[0].actions[0]='s3:ListBucket',policies[0].statements[0].actions[1]='s3:GetObject' minio/minio
+```
+
+Description of the configuration parameters used above -
+
+- `policies[].name` - name of the policy to create, must be a string with length > 0
+- `policies[].statements[]` - list of statements, includes actions and resources
+- `policies[].statements[].resources[]` - list of resources that applies the statement
+- `policies[].statements[].actions[]` - list of actions granted
+
+### Create user after install
+
+Install the chart, specifying the users you want to create after install:
+
+```bash
+helm install --set users[0].accessKey=accessKey,users[0].secretKey=secretKey,users[0].policy=none,users[1].accessKey=accessKey2,users[1].secretRef=existingSecret,users[1].secretKey=password,users[1].policy=none minio/minio
+```
+
+Description of the configuration parameters used above -
+
+- `users[].accessKey` - accessKey of user
+- `users[].secretKey` - secretKey of usersecretRef
+- `users[].existingSecret` - secret name that contains the secretKey of user
+- `users[].existingSecretKey` - data key in existingSecret secret containing the secretKey
+- `users[].policy` - name of the policy to assign to user
+
+## Uninstalling the Chart
+
+Assuming your release is named as `my-release`, delete it using the command:
+
+```bash
+helm delete my-release
+```
+
+or
+
+```bash
+helm uninstall my-release
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
diff --git a/charts/loki/charts/minio/templates/NOTES.txt b/charts/loki/charts/minio/templates/NOTES.txt
new file mode 100644
index 0000000..9337196
--- /dev/null
+++ b/charts/loki/charts/minio/templates/NOTES.txt
@@ -0,0 +1,43 @@
+{{- if eq .Values.service.type "ClusterIP" "NodePort" }}
+MinIO can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster:
+{{ template "minio.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+
+To access MinIO from localhost, run the below commands:
+
+ 1. export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
+
+ 2. kubectl port-forward $POD_NAME 9000 --namespace {{ .Release.Namespace }}
+
+Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/
+
+You can now access MinIO server on http://localhost:9000. Follow the below steps to connect to MinIO server with mc client:
+
+ 1. Download the MinIO mc client - https://docs.minio.io/docs/minio-client-quickstart-guide
+
+ 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@localhost:{{ .Values.service.port }}
+
+ 3. mc ls {{ template "minio.fullname" . }}-local
+
+{{- end }}
+{{- if eq .Values.service.type "LoadBalancer" }}
+MinIO can be accessed via port {{ .Values.service.port }} on an external IP address. Get the service external IP address by:
+kubectl get svc --namespace {{ .Release.Namespace }} -l app={{ template "minio.fullname" . }}
+
+Note that the public IP may take a couple of minutes to be available.
+
+You can now access MinIO server on http://<External-IP>:9000. Follow the below steps to connect to MinIO server with mc client:
+
+ 1. Download the MinIO mc client - https://docs.minio.io/docs/minio-client-quickstart-guide
+
+ 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret {{ template "minio.secretName" . }} --namespace {{ .Release.Namespace }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@<External-IP>:{{ .Values.service.port }}
+
+ 3. mc ls {{ template "minio.fullname" . }}
+
+Alternately, you can use your browser or the MinIO SDK to access the server - https://docs.minio.io/categories/17
+{{- end }}
+
+{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }}
+Note: Since NetworkPolicy is enabled, only pods with label
+{{ template "minio.fullname" . }}-client=true"
+will be able to connect to this minio cluster.
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/_helper_create_bucket.txt b/charts/loki/charts/minio/templates/_helper_create_bucket.txt
new file mode 100644
index 0000000..ced600d
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helper_create_bucket.txt
@@ -0,0 +1,123 @@
+#!/bin/sh
+set -e ; # Have script exit in the event of a failed command.
+
+{{- if .Values.configPathmc }}
+MC_CONFIG_DIR="{{ .Values.configPathmc }}"
+MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}"
+{{- else }}
+MC="/usr/bin/mc --insecure"
+{{- end }}
+
+# connectToMinio
+# Use a check-sleep-check loop to wait for MinIO service to be available
+connectToMinio() {
+ SCHEME=$1
+ ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts
+ set -e ; # fail if we can't read the keys.
+ ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ;
+ set +e ; # The connections to minio are allowed to fail.
+ echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ;
+ MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ;
+ $MC_COMMAND ;
+ STATUS=$? ;
+ until [ $STATUS = 0 ]
+ do
+ ATTEMPTS=`expr $ATTEMPTS + 1` ;
+ echo \"Failed attempts: $ATTEMPTS\" ;
+ if [ $ATTEMPTS -gt $LIMIT ]; then
+ exit 1 ;
+ fi ;
+ sleep 2 ; # 1 second intervals between attempts
+ $MC_COMMAND ;
+ STATUS=$? ;
+ done ;
+ set -e ; # reset `e` as active
+ return 0
+}
+
+# checkBucketExists ($bucket)
+# Check if the bucket exists, by using the exit code of `mc ls`
+checkBucketExists() {
+ BUCKET=$1
+ CMD=$(${MC} ls myminio/$BUCKET > /dev/null 2>&1)
+ return $?
+}
+
+# createBucket ($bucket, $policy, $purge)
+# Ensure bucket exists, purging if asked to
+createBucket() {
+ BUCKET=$1
+ POLICY=$2
+ PURGE=$3
+ VERSIONING=$4
+ OBJECTLOCKING=$5
+
+ # Purge the bucket, if set & exists
+ # Since PURGE is user input, check explicitly for `true`
+ if [ $PURGE = true ]; then
+ if checkBucketExists $BUCKET ; then
+ echo "Purging bucket '$BUCKET'."
+ set +e ; # don't exit if this fails
+ ${MC} rm -r --force myminio/$BUCKET
+ set -e ; # reset `e` as active
+ else
+ echo "Bucket '$BUCKET' does not exist, skipping purge."
+ fi
+ fi
+
+# Create the bucket if it does not exist and set objectlocking if enabled (NOTE: versioning will be not changed if OBJECTLOCKING is set because it enables versioning to the Buckets created)
+if ! checkBucketExists $BUCKET ; then
+ if [ ! -z $OBJECTLOCKING ] ; then
+ if [ $OBJECTLOCKING = true ] ; then
+ echo "Creating bucket with OBJECTLOCKING '$BUCKET'"
+ ${MC} mb --with-lock myminio/$BUCKET
+ elif [ $OBJECTLOCKING = false ] ; then
+ echo "Creating bucket '$BUCKET'"
+ ${MC} mb myminio/$BUCKET
+ fi
+ elif [ -z $OBJECTLOCKING ] ; then
+ echo "Creating bucket '$BUCKET'"
+ ${MC} mb myminio/$BUCKET
+ else
+ echo "Bucket '$BUCKET' already exists."
+ fi
+ fi
+
+
+ # set versioning for bucket if objectlocking is disabled or not set
+ if [ -z $OBJECTLOCKING ] ; then
+ if [ ! -z $VERSIONING ] ; then
+ if [ $VERSIONING = true ] ; then
+ echo "Enabling versioning for '$BUCKET'"
+ ${MC} version enable myminio/$BUCKET
+ elif [ $VERSIONING = false ] ; then
+ echo "Suspending versioning for '$BUCKET'"
+ ${MC} version suspend myminio/$BUCKET
+ fi
+ fi
+ else
+ echo "Bucket '$BUCKET' versioning unchanged."
+ fi
+
+
+ # At this point, the bucket should exist, skip checking for existence
+ # Set policy on the bucket
+ echo "Setting policy of bucket '$BUCKET' to '$POLICY'."
+ ${MC} policy set $POLICY myminio/$BUCKET
+}
+
+# Try connecting to MinIO instance
+{{- if .Values.tls.enabled }}
+scheme=https
+{{- else }}
+scheme=http
+{{- end }}
+connectToMinio $scheme
+
+{{ if .Values.buckets }}
+{{ $global := . }}
+# Create the buckets
+{{- range .Values.buckets }}
+createBucket {{ tpl .name $global }} {{ .policy }} {{ .purge }} {{ .versioning }} {{ .objectlocking }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/loki/charts/minio/templates/_helper_create_policy.txt b/charts/loki/charts/minio/templates/_helper_create_policy.txt
new file mode 100644
index 0000000..d565b16
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helper_create_policy.txt
@@ -0,0 +1,75 @@
+#!/bin/sh
+set -e ; # Have script exit in the event of a failed command.
+
+{{- if .Values.configPathmc }}
+MC_CONFIG_DIR="{{ .Values.configPathmc }}"
+MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}"
+{{- else }}
+MC="/usr/bin/mc --insecure"
+{{- end }}
+
+# connectToMinio
+# Use a check-sleep-check loop to wait for MinIO service to be available
+connectToMinio() {
+ SCHEME=$1
+ ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts
+ set -e ; # fail if we can't read the keys.
+ ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ;
+ set +e ; # The connections to minio are allowed to fail.
+ echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ;
+ MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ;
+ $MC_COMMAND ;
+ STATUS=$? ;
+ until [ $STATUS = 0 ]
+ do
+ ATTEMPTS=`expr $ATTEMPTS + 1` ;
+ echo \"Failed attempts: $ATTEMPTS\" ;
+ if [ $ATTEMPTS -gt $LIMIT ]; then
+ exit 1 ;
+ fi ;
+ sleep 2 ; # 1 second intervals between attempts
+ $MC_COMMAND ;
+ STATUS=$? ;
+ done ;
+ set -e ; # reset `e` as active
+ return 0
+}
+
+# checkPolicyExists ($policy)
+# Check if the policy exists, by using the exit code of `mc admin policy info`
+checkPolicyExists() {
+ POLICY=$1
+ CMD=$(${MC} admin policy info myminio $POLICY > /dev/null 2>&1)
+ return $?
+}
+
+# createPolicy($name, $filename)
+createPolicy () {
+ NAME=$1
+ FILENAME=$2
+
+ # Create the name if it does not exist
+ echo "Checking policy: $NAME (in /config/$FILENAME.json)"
+ if ! checkPolicyExists $NAME ; then
+ echo "Creating policy '$NAME'"
+ else
+ echo "Policy '$NAME' already exists."
+ fi
+ ${MC} admin policy add myminio $NAME /config/$FILENAME.json
+
+}
+
+# Try connecting to MinIO instance
+{{- if .Values.tls.enabled }}
+scheme=https
+{{- else }}
+scheme=http
+{{- end }}
+connectToMinio $scheme
+
+{{ if .Values.policies }}
+# Create the policies
+{{- range $idx, $policy := .Values.policies }}
+createPolicy {{ $policy.name }} policy_{{ $idx }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/loki/charts/minio/templates/_helper_create_user.txt b/charts/loki/charts/minio/templates/_helper_create_user.txt
new file mode 100644
index 0000000..ea2b3b6
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helper_create_user.txt
@@ -0,0 +1,105 @@
+#!/bin/sh
+set -e ; # Have script exit in the event of a failed command.
+
+{{- if .Values.configPathmc }}
+MC_CONFIG_DIR="{{ .Values.configPathmc }}"
+MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}"
+{{- else }}
+MC="/usr/bin/mc --insecure"
+{{- end }}
+
+# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters.
+# Special characters for example : ',",<,>,{,}
+MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_tmp"
+
+# connectToMinio
+# Use a check-sleep-check loop to wait for MinIO service to be available
+connectToMinio() {
+ SCHEME=$1
+ ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts
+ set -e ; # fail if we can't read the keys.
+ ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ;
+ set +e ; # The connections to minio are allowed to fail.
+ echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ;
+ MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ;
+ $MC_COMMAND ;
+ STATUS=$? ;
+ until [ $STATUS = 0 ]
+ do
+ ATTEMPTS=`expr $ATTEMPTS + 1` ;
+ echo \"Failed attempts: $ATTEMPTS\" ;
+ if [ $ATTEMPTS -gt $LIMIT ]; then
+ exit 1 ;
+ fi ;
+ sleep 2 ; # 1 second intervals between attempts
+ $MC_COMMAND ;
+ STATUS=$? ;
+ done ;
+ set -e ; # reset `e` as active
+ return 0
+}
+
+# checkUserExists ()
+# Check if the user exists, by using the exit code of `mc admin user info`
+checkUserExists() {
+ CMD=$(${MC} admin user info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1)
+ return $?
+}
+
+# createUser ($policy)
+createUser() {
+ POLICY=$1
+ #check accessKey_and_secretKey_tmp file
+ if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then
+ echo "credentials file does not exist"
+ return 1
+ fi
+ if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then
+ echo "credentials file is invalid"
+ rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP
+ return 1
+ fi
+ USER=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP)
+ # Create the user if it does not exist
+ if ! checkUserExists ; then
+ echo "Creating user '$USER'"
+ cat $MINIO_ACCESSKEY_SECRETKEY_TMP | ${MC} admin user add myminio
+ else
+ echo "User '$USER' already exists."
+ fi
+ #clean up credentials files.
+ rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP
+
+ # set policy for user
+ if [ ! -z $POLICY -a $POLICY != " " ] ; then
+ echo "Adding policy '$POLICY' for '$USER'"
+ ${MC} admin policy set myminio $POLICY user=$USER
+ else
+ echo "User '$USER' has no policy attached."
+ fi
+}
+
+# Try connecting to MinIO instance
+{{- if .Values.tls.enabled }}
+scheme=https
+{{- else }}
+scheme=http
+{{- end }}
+connectToMinio $scheme
+
+{{ if .Values.users }}
+{{ $global := . }}
+# Create the users
+{{- range .Values.users }}
+echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP
+{{- if .existingSecret }}
+cat /config/secrets/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP
+# Add a new line if it doesn't exist
+sed -i '$a\' $MINIO_ACCESSKEY_SECRETKEY_TMP
+createUser {{ .policy }}
+{{ else }}
+echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP
+createUser {{ .policy }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/_helper_custom_command.txt b/charts/loki/charts/minio/templates/_helper_custom_command.txt
new file mode 100644
index 0000000..b583a77
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helper_custom_command.txt
@@ -0,0 +1,58 @@
+#!/bin/sh
+set -e ; # Have script exit in the event of a failed command.
+
+{{- if .Values.configPathmc }}
+MC_CONFIG_DIR="{{ .Values.configPathmc }}"
+MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}"
+{{- else }}
+MC="/usr/bin/mc --insecure"
+{{- end }}
+
+# connectToMinio
+# Use a check-sleep-check loop to wait for MinIO service to be available
+connectToMinio() {
+ SCHEME=$1
+ ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts
+ set -e ; # fail if we can't read the keys.
+ ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ;
+ set +e ; # The connections to minio are allowed to fail.
+ echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ;
+ MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ;
+ $MC_COMMAND ;
+ STATUS=$? ;
+ until [ $STATUS = 0 ]
+ do
+ ATTEMPTS=`expr $ATTEMPTS + 1` ;
+ echo \"Failed attempts: $ATTEMPTS\" ;
+ if [ $ATTEMPTS -gt $LIMIT ]; then
+ exit 1 ;
+ fi ;
+ sleep 2 ; # 1 second intervals between attempts
+ $MC_COMMAND ;
+ STATUS=$? ;
+ done ;
+ set -e ; # reset `e` as active
+ return 0
+}
+
+# runCommand ($@)
+# Run custom mc command
+runCommand() {
+ ${MC} "$@"
+ return $?
+}
+
+# Try connecting to MinIO instance
+{{- if .Values.tls.enabled }}
+scheme=https
+{{- else }}
+scheme=http
+{{- end }}
+connectToMinio $scheme
+
+{{ if .Values.customCommands }}
+# Run custom commands
+{{- range .Values.customCommands }}
+runCommand {{ .command }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/_helper_policy.tpl b/charts/loki/charts/minio/templates/_helper_policy.tpl
new file mode 100644
index 0000000..83a2e15
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helper_policy.tpl
@@ -0,0 +1,18 @@
+{{- $statements_length := len .statements -}}
+{{- $statements_length := sub $statements_length 1 -}}
+{
+ "Version": "2012-10-17",
+ "Statement": [
+{{- range $i, $statement := .statements }}
+ {
+ "Effect": "Allow",
+ "Action": [
+"{{ $statement.actions | join "\",\n\"" }}"
+ ]{{ if $statement.resources }},
+ "Resource": [
+"{{ $statement.resources | join "\",\n\"" }}"
+ ]{{ end }}
+ }{{ if lt $i $statements_length }},{{end }}
+{{- end }}
+ ]
+}
diff --git a/charts/loki/charts/minio/templates/_helpers.tpl b/charts/loki/charts/minio/templates/_helpers.tpl
new file mode 100644
index 0000000..4e38194
--- /dev/null
+++ b/charts/loki/charts/minio/templates/_helpers.tpl
@@ -0,0 +1,218 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "minio.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "minio.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "minio.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for networkpolicy.
+*/}}
+{{- define "minio.networkPolicy.apiVersion" -}}
+{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.Version -}}
+{{- print "extensions/v1beta1" -}}
+{{- else if semverCompare ">=1.7-0, <1.16-0" .Capabilities.KubeVersion.Version -}}
+{{- print "networking.k8s.io/v1beta1" -}}
+{{- else if semverCompare "^1.16-0" .Capabilities.KubeVersion.Version -}}
+{{- print "networking.k8s.io/v1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for deployment.
+*/}}
+{{- define "minio.deployment.apiVersion" -}}
+{{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.Version -}}
+{{- print "apps/v1beta2" -}}
+{{- else -}}
+{{- print "apps/v1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for statefulset.
+*/}}
+{{- define "minio.statefulset.apiVersion" -}}
+{{- if semverCompare "<1.16-0" .Capabilities.KubeVersion.Version -}}
+{{- print "apps/v1beta2" -}}
+{{- else -}}
+{{- print "apps/v1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for ingress.
+*/}}
+{{- define "minio.ingress.apiVersion" -}}
+{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "extensions/v1beta1" -}}
+{{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "networking.k8s.io/v1beta1" -}}
+{{- else -}}
+{{- print "networking.k8s.io/v1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for console ingress.
+*/}}
+{{- define "minio.consoleIngress.apiVersion" -}}
+{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "extensions/v1beta1" -}}
+{{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "networking.k8s.io/v1beta1" -}}
+{{- else -}}
+{{- print "networking.k8s.io/v1" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Determine secret name.
+*/}}
+{{- define "minio.secretName" -}}
+{{- if .Values.existingSecret -}}
+{{- .Values.existingSecret }}
+{{- else -}}
+{{- include "minio.fullname" . -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Determine name for scc role and rolebinding
+*/}}
+{{- define "minio.sccRoleName" -}}
+{{- printf "%s-%s" "scc" (include "minio.fullname" .) | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Properly format optional additional arguments to MinIO binary
+*/}}
+{{- define "minio.extraArgs" -}}
+{{- range .Values.extraArgs -}}
+{{ " " }}{{ . }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the proper Docker Image Registry Secret Names
+*/}}
+{{- define "minio.imagePullSecrets" -}}
+{{/*
+Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
+but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
+Also, we can not use a single if because lazy evaluation is not an option
+*/}}
+{{- if .Values.global }}
+{{- if .Values.global.imagePullSecrets }}
+imagePullSecrets:
+{{- range .Values.global.imagePullSecrets }}
+ - name: {{ . }}
+{{- end }}
+{{- else if .Values.imagePullSecrets }}
+imagePullSecrets:
+ {{ toYaml .Values.imagePullSecrets }}
+{{- end -}}
+{{- else if .Values.imagePullSecrets }}
+imagePullSecrets:
+ {{ toYaml .Values.imagePullSecrets }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Formats volumeMount for MinIO TLS keys and trusted certs
+*/}}
+{{- define "minio.tlsKeysVolumeMount" -}}
+{{- if .Values.tls.enabled }}
+- name: cert-secret-volume
+ mountPath: {{ .Values.certsPath }}
+{{- end }}
+{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }}
+{{- $casPath := printf "%s/CAs" .Values.certsPath | clean }}
+- name: trusted-cert-secret-volume
+ mountPath: {{ $casPath }}
+{{- end }}
+{{- end -}}
+
+{{/*
+Formats volume for MinIO TLS keys and trusted certs
+*/}}
+{{- define "minio.tlsKeysVolume" -}}
+{{- if .Values.tls.enabled }}
+- name: cert-secret-volume
+ secret:
+ secretName: {{ .Values.tls.certSecret }}
+ items:
+ - key: {{ .Values.tls.publicCrt }}
+ path: public.crt
+ - key: {{ .Values.tls.privateKey }}
+ path: private.key
+{{- end }}
+{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }}
+{{- $certSecret := eq .Values.trustedCertsSecret "" | ternary .Values.tls.certSecret .Values.trustedCertsSecret }}
+{{- $publicCrt := eq .Values.trustedCertsSecret "" | ternary .Values.tls.publicCrt "" }}
+- name: trusted-cert-secret-volume
+ secret:
+ secretName: {{ $certSecret }}
+ {{- if ne $publicCrt "" }}
+ items:
+ - key: {{ $publicCrt }}
+ path: public.crt
+ {{- end }}
+{{- end }}
+{{- end -}}
+
+{{/*
+Returns the available value for certain key in an existing secret (if it exists),
+otherwise it generates a random value.
+*/}}
+{{- define "minio.getValueFromSecret" }}
+ {{- $len := (default 16 .Length) | int -}}
+ {{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}}
+ {{- if $obj }}
+ {{- index $obj .Key | b64dec -}}
+ {{- else -}}
+ {{- randAlphaNum $len -}}
+ {{- end -}}
+{{- end }}
+
+{{- define "minio.root.username" -}}
+ {{- if .Values.rootUser }}
+ {{- .Values.rootUser | toString }}
+ {{- else }}
+ {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 20 "Key" "rootUser") }}
+ {{- end }}
+{{- end -}}
+
+{{- define "minio.root.password" -}}
+ {{- if .Values.rootPassword }}
+ {{- .Values.rootPassword | toString }}
+ {{- else }}
+ {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 40 "Key" "rootPassword") }}
+ {{- end }}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/loki/charts/minio/templates/configmap.yaml b/charts/loki/charts/minio/templates/configmap.yaml
new file mode 100644
index 0000000..95a7c60
--- /dev/null
+++ b/charts/loki/charts/minio/templates/configmap.yaml
@@ -0,0 +1,24 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ initialize: |-
+{{ include (print $.Template.BasePath "/_helper_create_bucket.txt") . | indent 4 }}
+ add-user: |-
+{{ include (print $.Template.BasePath "/_helper_create_user.txt") . | indent 4 }}
+ add-policy: |-
+{{ include (print $.Template.BasePath "/_helper_create_policy.txt") . | indent 4 }}
+{{- range $idx, $policy := .Values.policies }}
+ # {{ $policy.name }}
+ policy_{{ $idx }}.json: |-
+{{ include (print $.Template.BasePath "/_helper_policy.tpl") . | indent 4 }}
+{{ end }}
+ custom-command: |-
+{{ include (print $.Template.BasePath "/_helper_custom_command.txt") . | indent 4 }}
diff --git a/charts/loki/charts/minio/templates/console-ingress.yaml b/charts/loki/charts/minio/templates/console-ingress.yaml
new file mode 100644
index 0000000..2ce9a93
--- /dev/null
+++ b/charts/loki/charts/minio/templates/console-ingress.yaml
@@ -0,0 +1,58 @@
+{{- if .Values.consoleIngress.enabled -}}
+{{- $fullName := printf "%s-console" (include "minio.fullname" .) -}}
+{{- $servicePort := .Values.consoleService.port -}}
+{{- $ingressPath := .Values.consoleIngress.path -}}
+apiVersion: {{ template "minio.consoleIngress.apiVersion" . }}
+kind: Ingress
+metadata:
+ name: {{ $fullName }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.consoleIngress.labels }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+
+{{- with .Values.consoleIngress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.consoleIngress.ingressClassName }}
+ ingressClassName: {{ .Values.consoleIngress.ingressClassName }}
+{{- end }}
+{{- if .Values.consoleIngress.tls }}
+ tls:
+ {{- range .Values.consoleIngress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ {{- range .Values.consoleIngress.hosts }}
+ - http:
+ paths:
+ - path: {{ $ingressPath }}
+ {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $fullName }}
+ port:
+ number: {{ $servicePort }}
+ {{- else }}
+ backend:
+ serviceName: {{ $fullName }}
+ servicePort: {{ $servicePort }}
+ {{- end }}
+ {{- if . }}
+ host: {{ . | quote }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/console-service.yaml b/charts/loki/charts/minio/templates/console-service.yaml
new file mode 100644
index 0000000..46da359
--- /dev/null
+++ b/charts/loki/charts/minio/templates/console-service.yaml
@@ -0,0 +1,48 @@
+{{ $scheme := "http" }}
+{{- if .Values.tls.enabled }}
+{{ $scheme = "https" }}
+{{ end }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "minio.fullname" . }}-console
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.consoleService.annotations }}
+ annotations:
+{{ toYaml .Values.consoleService.annotations | indent 4 }}
+{{- end }}
+spec:
+{{- if (or (eq .Values.consoleService.type "ClusterIP" "") (empty .Values.consoleService.type)) }}
+ type: ClusterIP
+ {{- if not (empty .Values.consoleService.clusterIP) }}
+ clusterIP: {{ .Values.consoleService.clusterIP }}
+ {{end}}
+{{- else if eq .Values.consoleService.type "LoadBalancer" }}
+ type: {{ .Values.consoleService.type }}
+ loadBalancerIP: {{ default "" .Values.consoleService.loadBalancerIP }}
+{{- else }}
+ type: {{ .Values.consoleService.type }}
+{{- end }}
+ ports:
+ - name: {{ $scheme }}
+ port: {{ .Values.consoleService.port }}
+ protocol: TCP
+{{- if (and (eq .Values.consoleService.type "NodePort") ( .Values.consoleService.nodePort)) }}
+ nodePort: {{ .Values.consoleService.nodePort }}
+{{- else }}
+ targetPort: {{ .Values.minioConsolePort }}
+{{- end}}
+{{- if .Values.consoleService.externalIPs }}
+ externalIPs:
+{{- range $i , $ip := .Values.consoleService.externalIPs }}
+ - {{ $ip }}
+{{- end }}
+{{- end }}
+ selector:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
diff --git a/charts/loki/charts/minio/templates/deployment.yaml b/charts/loki/charts/minio/templates/deployment.yaml
new file mode 100644
index 0000000..062d141
--- /dev/null
+++ b/charts/loki/charts/minio/templates/deployment.yaml
@@ -0,0 +1,195 @@
+{{- if eq .Values.mode "standalone" }}
+{{ $scheme := "http" }}
+{{- if .Values.tls.enabled }}
+{{ $scheme = "https" }}
+{{ end }}
+{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }}
+apiVersion: {{ template "minio.deployment.apiVersion" . }}
+kind: Deployment
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels | trimSuffix "\n" | indent 4 }}
+{{- end }}
+{{- if .Values.additionalAnnotations }}
+ annotations:
+{{ toYaml .Values.additionalAnnotations | trimSuffix "\n" | indent 4 }}
+{{- end }}
+spec:
+ strategy:
+ type: {{ .Values.DeploymentUpdate.type }}
+ {{- if eq .Values.DeploymentUpdate.type "RollingUpdate" }}
+ rollingUpdate:
+ maxSurge: {{ .Values.DeploymentUpdate.maxSurge }}
+ maxUnavailable: {{ .Values.DeploymentUpdate.maxUnavailable }}
+ {{- end}}
+ replicas: 1
+ selector:
+ matchLabels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ name: {{ template "minio.fullname" . }}
+ labels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+ annotations:
+{{- if not .Values.ignoreChartChecksums }}
+ checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+{{- end }}
+{{- if .Values.podAnnotations }}
+{{ toYaml .Values.podAnnotations | trimSuffix "\n" | indent 8 }}
+{{- end }}
+ spec:
+ {{- if .Values.priorityClassName }}
+ priorityClassName: "{{ .Values.priorityClassName }}"
+ {{- end }}
+ {{- if .Values.runtimeClassName }}
+ runtimeClassName: "{{ .Values.runtimeClassName }}"
+ {{- end }}
+{{- if and .Values.securityContext.enabled .Values.persistence.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.securityContext.fsGroup }}
+ {{- if and (ge .Capabilities.KubeVersion.Major "1") (ge .Capabilities.KubeVersion.Minor "20") }}
+ fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }}
+ {{- end }}
+{{- end }}
+{{ if .Values.serviceAccount.create }}
+ serviceAccountName: {{ .Values.serviceAccount.name }}
+{{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - "/bin/sh"
+ - "-ce"
+ - "/usr/bin/docker-entrypoint.sh minio server {{ $bucketRoot }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template "minio.extraArgs" . }}"
+ volumeMounts:
+ - name: minio-user
+ mountPath: "/tmp/credentials"
+ readOnly: true
+ {{- if .Values.persistence.enabled }}
+ - name: export
+ mountPath: {{ .Values.mountPath }}
+ {{- if .Values.persistence.subPath }}
+ subPath: "{{ .Values.persistence.subPath }}"
+ {{- end }}
+ {{- end }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ mountPath: "/tmp/minio-config-env"
+ {{- end }}
+ {{- include "minio.tlsKeysVolumeMount" . | indent 12 }}
+ ports:
+ - name: {{ $scheme }}
+ containerPort: {{ .Values.minioAPIPort }}
+ - name: {{ $scheme }}-console
+ containerPort: {{ .Values.minioConsolePort }}
+ env:
+ - name: MINIO_ROOT_USER
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootUser
+ - name: MINIO_ROOT_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootPassword
+ {{- if .Values.extraSecret }}
+ - name: MINIO_CONFIG_ENV_FILE
+ value: "/tmp/minio-config-env/config.env"
+ {{- end}}
+ {{- if .Values.metrics.serviceMonitor.public }}
+ - name: MINIO_PROMETHEUS_AUTH_TYPE
+ value: "public"
+ {{- end}}
+ {{- if .Values.oidc.enabled }}
+ - name: MINIO_IDENTITY_OPENID_CONFIG_URL
+ value: {{ .Values.oidc.configUrl }}
+ - name: MINIO_IDENTITY_OPENID_CLIENT_ID
+ value: {{ .Values.oidc.clientId }}
+ - name: MINIO_IDENTITY_OPENID_CLIENTs_SECRET
+ value: {{ .Values.oidc.clientSecret }}
+ - name: MINIO_IDENTITY_OPENID_CLAIM_NAME
+ value: {{ .Values.oidc.claimName }}
+ - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX
+ value: {{ .Values.oidc.claimPrefix }}
+ - name: MINIO_IDENTITY_OPENID_SCOPES
+ value: {{ .Values.oidc.scopes }}
+ - name: MINIO_IDENTITY_OPENID_REDIRECT_URI
+ value: {{ .Values.oidc.redirectUri }}
+ - name: MINIO_IDENTITY_OPENID_COMMENT
+ value: {{ .Values.oidc.comment }}
+ {{- end}}
+ {{- if .Values.etcd.endpoints }}
+ - name: MINIO_ETCD_ENDPOINTS
+ value: {{ join "," .Values.etcd.endpoints | quote }}
+ {{- if .Values.etcd.clientCert }}
+ - name: MINIO_ETCD_CLIENT_CERT
+ value: "/tmp/credentials/etcd_client_cert.pem"
+ {{- end }}
+ {{- if .Values.etcd.clientCertKey }}
+ - name: MINIO_ETCD_CLIENT_CERT_KEY
+ value: "/tmp/credentials/etcd_client_cert_key.pem"
+ {{- end }}
+ {{- if .Values.etcd.pathPrefix }}
+ - name: MINIO_ETCD_PATH_PREFIX
+ value: {{ .Values.etcd.pathPrefix }}
+ {{- end }}
+ {{- if .Values.etcd.corednsPathPrefix }}
+ - name: MINIO_ETCD_COREDNS_PATH
+ value: {{ .Values.etcd.corednsPathPrefix }}
+ {{- end }}
+ {{- end }}
+ {{- range $key, $val := .Values.environment }}
+ - name: {{ $key }}
+ value: {{ $val | quote }}
+ {{- end}}
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+{{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+ volumes:
+ - name: export
+ {{- if .Values.persistence.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ .Values.persistence.existingClaim | default (include "minio.fullname" .) }}
+ {{- else }}
+ emptyDir: {}
+ {{- end }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ secret:
+ secretName: {{ .Values.extraSecret }}
+ {{- end }}
+ - name: minio-user
+ secret:
+ secretName: {{ template "minio.secretName" . }}
+ {{- include "minio.tlsKeysVolume" . | indent 8 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/gateway-deployment.yaml b/charts/loki/charts/minio/templates/gateway-deployment.yaml
new file mode 100644
index 0000000..b14f86b
--- /dev/null
+++ b/charts/loki/charts/minio/templates/gateway-deployment.yaml
@@ -0,0 +1,173 @@
+{{- if eq .Values.mode "gateway" }}
+{{ $scheme := "http" }}
+{{- if .Values.tls.enabled }}
+{{ $scheme = "https" }}
+{{ end }}
+{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }}
+apiVersion: {{ template "minio.deployment.apiVersion" . }}
+kind: Deployment
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels | trimSuffix "\n" | indent 4 }}
+{{- end }}
+{{- if .Values.additionalAnnotations }}
+ annotations:
+{{ toYaml .Values.additionalAnnotations | trimSuffix "\n" | indent 4 }}
+{{- end }}
+spec:
+ strategy:
+ type: {{ .Values.DeploymentUpdate.type }}
+ {{- if eq .Values.DeploymentUpdate.type "RollingUpdate" }}
+ rollingUpdate:
+ maxSurge: {{ .Values.DeploymentUpdate.maxSurge }}
+ maxUnavailable: {{ .Values.DeploymentUpdate.maxUnavailable }}
+ {{- end}}
+ replicas: {{ .Values.gateway.replicas }}
+ selector:
+ matchLabels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ name: {{ template "minio.fullname" . }}
+ labels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+ annotations:
+{{- if not .Values.ignoreChartChecksums }}
+ checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+{{- end }}
+{{- if .Values.podAnnotations }}
+{{ toYaml .Values.podAnnotations | trimSuffix "\n" | indent 8 }}
+{{- end }}
+ spec:
+ {{- if .Values.priorityClassName }}
+ priorityClassName: "{{ .Values.priorityClassName }}"
+ {{- end }}
+{{- if and .Values.securityContext.enabled .Values.persistence.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.securityContext.fsGroup }}
+{{- end }}
+{{ if .Values.serviceAccount.create }}
+ serviceAccountName: {{ .Values.serviceAccount.name }}
+{{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command:
+ - "/bin/sh"
+ - "-ce"
+ {{- if eq .Values.gateway.type "nas" }}
+ - "/usr/bin/docker-entrypoint.sh minio gateway nas {{ $bucketRoot }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template "minio.extraArgs" . }} "
+ {{- end }}
+ volumeMounts:
+ - name: minio-user
+ mountPath: "/tmp/credentials"
+ readOnly: true
+ {{- if .Values.persistence.enabled }}
+ - name: export
+ mountPath: {{ .Values.mountPath }}
+ {{- if .Values.persistence.subPath }}
+ subPath: "{{ .Values.persistence.subPath }}"
+ {{- end }}
+ {{- end }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ mountPath: "/tmp/minio-config-env"
+ {{- end }}
+ {{- include "minio.tlsKeysVolumeMount" . | indent 12 }}
+ ports:
+ - name: {{ $scheme }}
+ containerPort: {{ .Values.minioAPIPort }}
+ - name: {{ $scheme }}-console
+ containerPort: {{ .Values.minioConsolePort }}
+ env:
+ - name: MINIO_ROOT_USER
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootUser
+ - name: MINIO_ROOT_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootPassword
+ {{- if .Values.extraSecret }}
+ - name: MINIO_CONFIG_ENV_FILE
+ value: "/tmp/minio-config-env/config.env"
+ {{- end}}
+ {{- if .Values.metrics.serviceMonitor.public }}
+ - name: MINIO_PROMETHEUS_AUTH_TYPE
+ value: "public"
+ {{- end}}
+ {{- if .Values.etcd.endpoints }}
+ - name: MINIO_ETCD_ENDPOINTS
+ value: {{ join "," .Values.etcd.endpoints | quote }}
+ {{- if .Values.etcd.clientCert }}
+ - name: MINIO_ETCD_CLIENT_CERT
+ value: "/tmp/credentials/etcd_client.crt"
+ {{- end }}
+ {{- if .Values.etcd.clientCertKey }}
+ - name: MINIO_ETCD_CLIENT_CERT_KEY
+ value: "/tmp/credentials/etcd_client.key"
+ {{- end }}
+ {{- if .Values.etcd.pathPrefix }}
+ - name: MINIO_ETCD_PATH_PREFIX
+ value: {{ .Values.etcd.pathPrefix }}
+ {{- end }}
+ {{- if .Values.etcd.corednsPathPrefix }}
+ - name: MINIO_ETCD_COREDNS_PATH
+ value: {{ .Values.etcd.corednsPathPrefix }}
+ {{- end }}
+ {{- end }}
+ {{- range $key, $val := .Values.environment }}
+ - name: {{ $key }}
+ value: {{ $val | quote }}
+ {{- end}}
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+{{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+ volumes:
+ - name: export
+ {{- if .Values.persistence.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ .Values.persistence.existingClaim | default (include "minio.fullname" .) }}
+ {{- else }}
+ emptyDir: {}
+ {{- end }}
+ - name: minio-user
+ secret:
+ secretName: {{ template "minio.secretName" . }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ secret:
+ secretName: {{ .Values.extraSecret }}
+ {{- end }}
+ {{- include "minio.tlsKeysVolume" . | indent 8 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/ingress.yaml b/charts/loki/charts/minio/templates/ingress.yaml
new file mode 100644
index 0000000..8d9a837
--- /dev/null
+++ b/charts/loki/charts/minio/templates/ingress.yaml
@@ -0,0 +1,58 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "minio.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+{{- $ingressPath := .Values.ingress.path -}}
+apiVersion: {{ template "minio.ingress.apiVersion" . }}
+kind: Ingress
+metadata:
+ name: {{ $fullName }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- with .Values.ingress.labels }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+
+{{- with .Values.ingress.annotations }}
+ annotations:
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+{{- if .Values.ingress.ingressClassName }}
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+{{- end }}
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ {{- range .Values.ingress.hosts }}
+ - http:
+ paths:
+ - path: {{ $ingressPath }}
+ {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $fullName }}
+ port:
+ number: {{ $servicePort }}
+ {{- else }}
+ backend:
+ serviceName: {{ $fullName }}
+ servicePort: {{ $servicePort }}
+ {{- end }}
+ {{- if . }}
+ host: {{ . | quote }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/networkpolicy.yaml b/charts/loki/charts/minio/templates/networkpolicy.yaml
new file mode 100644
index 0000000..ac219b9
--- /dev/null
+++ b/charts/loki/charts/minio/templates/networkpolicy.yaml
@@ -0,0 +1,27 @@
+{{- if .Values.networkPolicy.enabled }}
+kind: NetworkPolicy
+apiVersion: {{ template "minio.networkPolicy.apiVersion" . }}
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ podSelector:
+ matchLabels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+ ingress:
+ - ports:
+ - port: {{ .Values.minioAPIPort }}
+ - port: {{ .Values.minioConsolePort }}
+ {{- if not .Values.networkPolicy.allowExternal }}
+ from:
+ - podSelector:
+ matchLabels:
+ {{ template "minio.name" . }}-client: "true"
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/poddisruptionbudget.yaml b/charts/loki/charts/minio/templates/poddisruptionbudget.yaml
new file mode 100644
index 0000000..8037eb7
--- /dev/null
+++ b/charts/loki/charts/minio/templates/poddisruptionbudget.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.podDisruptionBudget.enabled }}
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+ name: minio
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+spec:
+ maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
+ selector:
+ matchLabels:
+ app: {{ template "minio.name" . }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/loki/charts/minio/templates/post-install-create-bucket-job.yaml b/charts/loki/charts/minio/templates/post-install-create-bucket-job.yaml
new file mode 100644
index 0000000..37d4f6b
--- /dev/null
+++ b/charts/loki/charts/minio/templates/post-install-create-bucket-job.yaml
@@ -0,0 +1,92 @@
+{{- if .Values.buckets }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "minio.fullname" . }}-make-bucket-job
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}-make-bucket-job
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ annotations:
+ "helm.sh/hook": post-install,post-upgrade
+ "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
+{{- with .Values.makeBucketJob.annotations }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+ template:
+ metadata:
+ labels:
+ app: {{ template "minio.name" . }}-job
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+{{- if .Values.makeBucketJob.podAnnotations }}
+ annotations:
+{{ toYaml .Values.makeBucketJob.podAnnotations | indent 8 }}
+{{- end }}
+ spec:
+ restartPolicy: OnFailure
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- if .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml .Values.makeBucketJob.nodeSelector | indent 8 }}
+{{- end }}
+{{- with .Values.makeBucketJob.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.makeBucketJob.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- if .Values.makeBucketJob.securityContext.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.makeBucketJob.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.makeBucketJob.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.makeBucketJob.securityContext.fsGroup }}
+{{- end }}
+ volumes:
+ - name: minio-configuration
+ projected:
+ sources:
+ - configMap:
+ name: {{ template "minio.fullname" . }}
+ - secret:
+ name: {{ template "minio.secretName" . }}
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ secret:
+ secretName: {{ .Values.tls.certSecret }}
+ items:
+ - key: {{ .Values.tls.publicCrt }}
+ path: CAs/public.crt
+ {{ end }}
+ containers:
+ - name: minio-mc
+ image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}"
+ imagePullPolicy: {{ .Values.mcImage.pullPolicy }}
+ {{- if .Values.makeBucketJob.exitCommand }}
+ command: ["/bin/sh", "-c"]
+ args: ["/bin/sh /config/initialize; x=$(echo $?); {{ .Values.makeBucketJob.exitCommand }} && exit $x" ]
+ {{- else }}
+ command: ["/bin/sh", "/config/initialize"]
+ {{- end }}
+ env:
+ - name: MINIO_ENDPOINT
+ value: {{ template "minio.fullname" . }}
+ - name: MINIO_PORT
+ value: {{ .Values.service.port | quote }}
+ volumeMounts:
+ - name: minio-configuration
+ mountPath: /config
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ mountPath: {{ .Values.configPathmc }}certs
+ {{ end }}
+ resources:
+{{ toYaml .Values.makeBucketJob.resources | indent 10 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/post-install-create-policy-job.yaml b/charts/loki/charts/minio/templates/post-install-create-policy-job.yaml
new file mode 100644
index 0000000..cf3c660
--- /dev/null
+++ b/charts/loki/charts/minio/templates/post-install-create-policy-job.yaml
@@ -0,0 +1,92 @@
+{{- if .Values.policies }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "minio.fullname" . }}-make-policies-job
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}-make-policies-job
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ annotations:
+ "helm.sh/hook": post-install,post-upgrade
+ "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
+{{- with .Values.makePolicyJob.annotations }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+ template:
+ metadata:
+ labels:
+ app: {{ template "minio.name" . }}-job
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+{{- if .Values.makePolicyJob.podAnnotations }}
+ annotations:
+{{ toYaml .Values.makePolicyJob.podAnnotations | indent 8 }}
+{{- end }}
+ spec:
+ restartPolicy: OnFailure
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- if .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml .Values.makePolicyJob.nodeSelector | indent 8 }}
+{{- end }}
+{{- with .Values.makePolicyJob.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.makePolicyJob.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- if .Values.makePolicyJob.securityContext.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.makePolicyJob.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.makePolicyJob.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.makePolicyJob.securityContext.fsGroup }}
+{{- end }}
+ volumes:
+ - name: minio-configuration
+ projected:
+ sources:
+ - configMap:
+ name: {{ template "minio.fullname" . }}
+ - secret:
+ name: {{ template "minio.secretName" . }}
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ secret:
+ secretName: {{ .Values.tls.certSecret }}
+ items:
+ - key: {{ .Values.tls.publicCrt }}
+ path: CAs/public.crt
+ {{ end }}
+ containers:
+ - name: minio-mc
+ image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}"
+ imagePullPolicy: {{ .Values.mcImage.pullPolicy }}
+ {{- if .Values.makePolicyJob.exitCommand }}
+ command: ["/bin/sh", "-c"]
+ args: ["/bin/sh /config/add-policy; x=$(echo $?); {{ .Values.makePolicyJob.exitCommand }} && exit $x" ]
+ {{- else }}
+ command: ["/bin/sh", "/config/add-policy"]
+ {{- end }}
+ env:
+ - name: MINIO_ENDPOINT
+ value: {{ template "minio.fullname" . }}
+ - name: MINIO_PORT
+ value: {{ .Values.service.port | quote }}
+ volumeMounts:
+ - name: minio-configuration
+ mountPath: /config
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ mountPath: {{ .Values.configPathmc }}certs
+ {{ end }}
+ resources:
+{{ toYaml .Values.makePolicyJob.resources | indent 10 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/post-install-create-user-job.yaml b/charts/loki/charts/minio/templates/post-install-create-user-job.yaml
new file mode 100644
index 0000000..7d7f6dd
--- /dev/null
+++ b/charts/loki/charts/minio/templates/post-install-create-user-job.yaml
@@ -0,0 +1,102 @@
+{{- $global := . -}}
+{{- if .Values.users }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "minio.fullname" . }}-make-user-job
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}-make-user-job
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ annotations:
+ "helm.sh/hook": post-install,post-upgrade
+ "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
+{{- with .Values.makeUserJob.annotations }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+ template:
+ metadata:
+ labels:
+ app: {{ template "minio.name" . }}-job
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+{{- if .Values.makeUserJob.podAnnotations }}
+ annotations:
+{{ toYaml .Values.makeUserJob.podAnnotations | indent 8 }}
+{{- end }}
+ spec:
+ restartPolicy: OnFailure
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- if .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml .Values.makeUserJob.nodeSelector | indent 8 }}
+{{- end }}
+{{- with .Values.makeUserJob.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.makeUserJob.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- if .Values.makeUserJob.securityContext.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.makeUserJob.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.makeUserJob.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.makeUserJob.securityContext.fsGroup }}
+{{- end }}
+ volumes:
+ - name: minio-configuration
+ projected:
+ sources:
+ - configMap:
+ name: {{ template "minio.fullname" . }}
+ - secret:
+ name: {{ template "minio.secretName" . }}
+ {{- range .Values.users }}
+ {{- if .existingSecret }}
+ - secret:
+ name: {{ tpl .existingSecret $global }}
+ items:
+ - key: {{ .existingSecretKey }}
+ path: secrets/{{ tpl .existingSecretKey $global }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ secret:
+ secretName: {{ .Values.tls.certSecret }}
+ items:
+ - key: {{ .Values.tls.publicCrt }}
+ path: CAs/public.crt
+ {{ end }}
+ containers:
+ - name: minio-mc
+ image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}"
+ imagePullPolicy: {{ .Values.mcImage.pullPolicy }}
+ {{- if .Values.makeUserJob.exitCommand }}
+ command: ["/bin/sh", "-c"]
+ args: ["/bin/sh /config/add-user; x=$(echo $?); {{ .Values.makeUserJob.exitCommand }} && exit $x" ]
+ {{- else }}
+ command: ["/bin/sh", "/config/add-user"]
+ {{- end }}
+ env:
+ - name: MINIO_ENDPOINT
+ value: {{ template "minio.fullname" . }}
+ - name: MINIO_PORT
+ value: {{ .Values.service.port | quote }}
+ volumeMounts:
+ - name: minio-configuration
+ mountPath: /config
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ mountPath: {{ .Values.configPathmc }}certs
+ {{ end }}
+ resources:
+{{ toYaml .Values.makeUserJob.resources | indent 10 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/post-install-custom-command.yaml b/charts/loki/charts/minio/templates/post-install-custom-command.yaml
new file mode 100644
index 0000000..48cbd75
--- /dev/null
+++ b/charts/loki/charts/minio/templates/post-install-custom-command.yaml
@@ -0,0 +1,92 @@
+{{- if .Values.customCommands }}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "minio.fullname" . }}-custom-command-job
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}-custom-command-job
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ annotations:
+ "helm.sh/hook": post-install,post-upgrade
+ "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
+{{- with .Values.customCommandJob.annotations }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+spec:
+ template:
+ metadata:
+ labels:
+ app: {{ template "minio.name" . }}-job
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+{{- if .Values.customCommandJob.podAnnotations }}
+ annotations:
+{{ toYaml .Values.customCommandJob.podAnnotations | indent 8 }}
+{{- end }}
+ spec:
+ restartPolicy: OnFailure
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+{{- if .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml .Values.customCommandJob.nodeSelector | indent 8 }}
+{{- end }}
+{{- with .Values.customCommandJob.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- with .Values.customCommandJob.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+{{- end }}
+{{- if .Values.customCommandJob.securityContext.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.customCommandJob.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.customCommandJob.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.customCommandJob.securityContext.fsGroup }}
+{{- end }}
+ volumes:
+ - name: minio-configuration
+ projected:
+ sources:
+ - configMap:
+ name: {{ template "minio.fullname" . }}
+ - secret:
+ name: {{ template "minio.secretName" . }}
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ secret:
+ secretName: {{ .Values.tls.certSecret }}
+ items:
+ - key: {{ .Values.tls.publicCrt }}
+ path: CAs/public.crt
+ {{ end }}
+ containers:
+ - name: minio-mc
+ image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}"
+ imagePullPolicy: {{ .Values.mcImage.pullPolicy }}
+ {{- if .Values.customCommandJob.exitCommand }}
+ command: ["/bin/sh", "-c"]
+ args: ["/bin/sh /config/custom-command; x=$(echo $?); {{ .Values.customCommandJob.exitCommand }} && exit $x" ]
+ {{- else }}
+ command: ["/bin/sh", "/config/custom-command"]
+ {{- end }}
+ env:
+ - name: MINIO_ENDPOINT
+ value: {{ template "minio.fullname" . }}
+ - name: MINIO_PORT
+ value: {{ .Values.service.port | quote }}
+ volumeMounts:
+ - name: minio-configuration
+ mountPath: /config
+ {{- if .Values.tls.enabled }}
+ - name: cert-secret-volume-mc
+ mountPath: {{ .Values.configPathmc }}certs
+ {{ end }}
+ resources:
+{{ toYaml .Values.customCommandJob.resources | indent 10 }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/pvc.yaml b/charts/loki/charts/minio/templates/pvc.yaml
new file mode 100644
index 0000000..369aade
--- /dev/null
+++ b/charts/loki/charts/minio/templates/pvc.yaml
@@ -0,0 +1,35 @@
+{{- if eq .Values.mode "standalone" }}
+{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.persistence.annotations }}
+ annotations:
+{{ toYaml .Values.persistence.annotations | trimSuffix "\n" | indent 4 }}
+{{- end }}
+spec:
+ accessModes:
+ - {{ .Values.persistence.accessMode | quote }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.size | quote }}
+
+{{- if .Values.persistence.storageClass }}
+{{- if (eq "-" .Values.persistence.storageClass) }}
+ storageClassName: ""
+{{- else }}
+ storageClassName: "{{ .Values.persistence.storageClass }}"
+{{- end }}
+{{- end }}
+{{- if .Values.persistence.VolumeName }}
+ volumeName: "{{ .Values.persistence.VolumeName }}"
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/secrets.yaml b/charts/loki/charts/minio/templates/secrets.yaml
new file mode 100644
index 0000000..da2ecab
--- /dev/null
+++ b/charts/loki/charts/minio/templates/secrets.yaml
@@ -0,0 +1,22 @@
+{{- if not .Values.existingSecret }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ template "minio.secretName" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+type: Opaque
+data:
+ rootUser: {{ include "minio.root.username" . | b64enc | quote }}
+ rootPassword: {{ include "minio.root.password" . | b64enc | quote }}
+ {{- if .Values.etcd.clientCert }}
+ etcd_client.crt: {{ .Values.etcd.clientCert | toString | b64enc | quote }}
+ {{- end }}
+ {{- if .Values.etcd.clientCertKey }}
+ etcd_client.key: {{ .Values.etcd.clientCertKey | toString | b64enc | quote }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/securitycontextconstraints.yaml b/charts/loki/charts/minio/templates/securitycontextconstraints.yaml
new file mode 100644
index 0000000..4bac7e3
--- /dev/null
+++ b/charts/loki/charts/minio/templates/securitycontextconstraints.yaml
@@ -0,0 +1,45 @@
+{{- if and .Values.securityContext.enabled .Values.persistence.enabled (.Capabilities.APIVersions.Has "security.openshift.io/v1") }}
+apiVersion: security.openshift.io/v1
+kind: SecurityContextConstraints
+metadata:
+ name: {{ template "minio.fullname" . }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+allowHostDirVolumePlugin: false
+allowHostIPC: false
+allowHostNetwork: false
+allowHostPID: false
+allowHostPorts: false
+allowPrivilegeEscalation: true
+allowPrivilegedContainer: false
+allowedCapabilities: []
+readOnlyRootFilesystem: false
+defaultAddCapabilities: []
+requiredDropCapabilities:
+- KILL
+- MKNOD
+- SETUID
+- SETGID
+fsGroup:
+ type: MustRunAs
+ ranges:
+ - max: {{ .Values.securityContext.fsGroup }}
+ min: {{ .Values.securityContext.fsGroup }}
+runAsUser:
+ type: MustRunAs
+ uid: {{ .Values.securityContext.runAsUser }}
+seLinuxContext:
+ type: MustRunAs
+supplementalGroups:
+ type: RunAsAny
+volumes:
+- configMap
+- downwardAPI
+- emptyDir
+- persistentVolumeClaim
+- projected
+- secret
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/service.yaml b/charts/loki/charts/minio/templates/service.yaml
new file mode 100644
index 0000000..741528d
--- /dev/null
+++ b/charts/loki/charts/minio/templates/service.yaml
@@ -0,0 +1,49 @@
+{{ $scheme := "http" }}
+{{- if .Values.tls.enabled }}
+{{ $scheme = "https" }}
+{{ end }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ monitoring: "true"
+{{- if .Values.service.annotations }}
+ annotations:
+{{ toYaml .Values.service.annotations | indent 4 }}
+{{- end }}
+spec:
+{{- if (or (eq .Values.service.type "ClusterIP" "") (empty .Values.service.type)) }}
+ type: ClusterIP
+ {{- if not (empty .Values.service.clusterIP) }}
+ clusterIP: {{ .Values.service.clusterIP }}
+ {{end}}
+{{- else if eq .Values.service.type "LoadBalancer" }}
+ type: {{ .Values.service.type }}
+ loadBalancerIP: {{ default "" .Values.service.loadBalancerIP }}
+{{- else }}
+ type: {{ .Values.service.type }}
+{{- end }}
+ ports:
+ - name: {{ $scheme }}
+ port: {{ .Values.service.port }}
+ protocol: TCP
+{{- if (and (eq .Values.service.type "NodePort") ( .Values.service.nodePort)) }}
+ nodePort: {{ .Values.service.nodePort }}
+{{- else }}
+ targetPort: {{ .Values.minioAPIPort }}
+{{- end}}
+{{- if .Values.service.externalIPs }}
+ externalIPs:
+{{- range $i , $ip := .Values.service.externalIPs }}
+ - {{ $ip }}
+{{- end }}
+{{- end }}
+ selector:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
diff --git a/charts/loki/charts/minio/templates/serviceaccount.yaml b/charts/loki/charts/minio/templates/serviceaccount.yaml
new file mode 100644
index 0000000..6a4bd94
--- /dev/null
+++ b/charts/loki/charts/minio/templates/serviceaccount.yaml
@@ -0,0 +1,7 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ .Values.serviceAccount.name | quote }}
+ namespace: {{ .Release.Namespace | quote }}
+{{- end -}}
diff --git a/charts/loki/charts/minio/templates/servicemonitor.yaml b/charts/loki/charts/minio/templates/servicemonitor.yaml
new file mode 100644
index 0000000..d3fb629
--- /dev/null
+++ b/charts/loki/charts/minio/templates/servicemonitor.yaml
@@ -0,0 +1,61 @@
+{{- if .Values.metrics.serviceMonitor.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "minio.fullname" . }}
+ {{- if .Values.metrics.serviceMonitor.namespace }}
+ namespace: {{ .Values.metrics.serviceMonitor.namespace }}
+ {{ else }}
+ namespace: {{ .Release.Namespace | quote }}
+ {{- end }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ {{- if .Values.metrics.serviceMonitor.additionalLabels }}
+{{ toYaml .Values.metrics.serviceMonitor.additionalLabels | indent 4 }}
+ {{- end }}
+{{- if .Values.metrics.serviceMonitor.annotations }}
+ annotations:
+{{ toYaml .Values.metrics.serviceMonitor.annotations | trimSuffix "\n" | indent 4 }}
+{{- end }}
+spec:
+ endpoints:
+ {{- if .Values.tls.enabled }}
+ - port: https
+ scheme: https
+ tlsConfig:
+ ca:
+ secret:
+ name: {{ .Values.tls.certSecret }}
+ key: {{ .Values.tls.publicCrt }}
+ serverName: {{ template "minio.fullname" . }}
+ {{ else }}
+ - port: http
+ scheme: http
+ {{- end }}
+ path: /minio/v2/metrics/cluster
+ {{- if .Values.metrics.serviceMonitor.interval }}
+ interval: {{ .Values.metrics.serviceMonitor.interval }}
+ {{- end }}
+ {{- if .Values.metrics.serviceMonitor.scrapeTimeout }}
+ scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }}
+ {{- end }}
+ {{- if .Values.metrics.serviceMonitor.relabelConfigs }}
+{{ toYaml .Values.metrics.serviceMonitor.relabelConfigs | indent 6 }}
+ {{- end }}
+ {{- if not .Values.metrics.serviceMonitor.public }}
+ bearerTokenSecret:
+ name: {{ template "minio.fullname" . }}-prometheus
+ key: token
+ {{- end }}
+ namespaceSelector:
+ matchNames:
+ - {{ .Release.Namespace | quote }}
+ selector:
+ matchLabels:
+ app: {{ include "minio.name" . }}
+ release: {{ .Release.Name }}
+ monitoring: "true"
+{{- end }}
diff --git a/charts/loki/charts/minio/templates/statefulset.yaml b/charts/loki/charts/minio/templates/statefulset.yaml
new file mode 100644
index 0000000..6d695dd
--- /dev/null
+++ b/charts/loki/charts/minio/templates/statefulset.yaml
@@ -0,0 +1,246 @@
+{{- if eq .Values.mode "distributed" }}
+{{ $poolCount := .Values.pools | int }}
+{{ $nodeCount := .Values.replicas | int }}
+{{ $replicas := mul $poolCount $nodeCount }}
+{{ $drivesPerNode := .Values.drivesPerNode | int }}
+{{ $scheme := "http" }}
+{{- if .Values.tls.enabled }}
+{{ $scheme = "https" }}
+{{ end }}
+{{ $mountPath := .Values.mountPath }}
+{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }}
+{{ $subPath := .Values.persistence.subPath }}
+{{ $penabled := .Values.persistence.enabled }}
+{{ $accessMode := .Values.persistence.accessMode }}
+{{ $storageClass := .Values.persistence.storageClass }}
+{{ $psize := .Values.persistence.size }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "minio.fullname" . }}-svc
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: "{{ .Release.Name }}"
+ heritage: "{{ .Release.Service }}"
+spec:
+ publishNotReadyAddresses: true
+ clusterIP: None
+ ports:
+ - name: {{ $scheme }}
+ port: {{ .Values.service.port }}
+ protocol: TCP
+ targetPort: {{ .Values.minioAPIPort }}
+ selector:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+---
+apiVersion: {{ template "minio.statefulset.apiVersion" . }}
+kind: StatefulSet
+metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ app: {{ template "minio.name" . }}
+ chart: {{ template "minio.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels | trimSuffix "\n" | indent 4 }}
+{{- end }}
+{{- if .Values.additionalAnnotations }}
+ annotations:
+{{ toYaml .Values.additionalAnnotations | trimSuffix "\n" | indent 4 }}
+{{- end }}
+spec:
+ updateStrategy:
+ type: {{ .Values.StatefulSetUpdate.updateStrategy }}
+ podManagementPolicy: "Parallel"
+ serviceName: {{ template "minio.fullname" . }}-svc
+ replicas: {{ $replicas }}
+ selector:
+ matchLabels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ name: {{ template "minio.fullname" . }}
+ labels:
+ app: {{ template "minio.name" . }}
+ release: {{ .Release.Name }}
+{{- if .Values.podLabels }}
+{{ toYaml .Values.podLabels | indent 8 }}
+{{- end }}
+ annotations:
+{{- if not .Values.ignoreChartChecksums }}
+ checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+{{- end }}
+{{- if .Values.podAnnotations }}
+{{ toYaml .Values.podAnnotations | trimSuffix "\n" | indent 8 }}
+{{- end }}
+ spec:
+ {{- if .Values.priorityClassName }}
+ priorityClassName: "{{ .Values.priorityClassName }}"
+ {{- end }}
+ {{- if .Values.runtimeClassName }}
+ runtimeClassName: "{{ .Values.runtimeClassName }}"
+ {{- end }}
+{{- if and .Values.securityContext.enabled .Values.persistence.enabled }}
+ securityContext:
+ runAsUser: {{ .Values.securityContext.runAsUser }}
+ runAsGroup: {{ .Values.securityContext.runAsGroup }}
+ fsGroup: {{ .Values.securityContext.fsGroup }}
+ {{- if and (ge .Capabilities.KubeVersion.Major "1") (ge .Capabilities.KubeVersion.Minor "20") }}
+ fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }}
+ {{- end }}
+{{- end }}
+{{ if .Values.serviceAccount.create }}
+ serviceAccountName: {{ .Values.serviceAccount.name }}
+{{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+
+ command: [ "/bin/sh",
+ "-ce",
+ "/usr/bin/docker-entrypoint.sh minio server {{- range $i := until $poolCount }}{{ $factor := mul $i $nodeCount }}{{ $endIndex := add $factor $nodeCount }}{{ $beginIndex := mul $i $nodeCount }} {{ $scheme }}://{{ template `minio.fullname` $ }}-{{ `{` }}{{ $beginIndex }}...{{ sub $endIndex 1 }}{{ `}`}}.{{ template `minio.fullname` $ }}-svc.{{ $.Release.Namespace }}.svc.{{ $.Values.clusterDomain }}{{if (gt $drivesPerNode 1)}}{{ $bucketRoot }}-{{ `{` }}0...{{ sub $drivesPerNode 1 }}{{ `}` }}{{else}}{{ $bucketRoot }}{{end}}{{- end}} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template `minio.extraArgs` . }}" ]
+ volumeMounts:
+ {{- if $penabled }}
+ {{- if (gt $drivesPerNode 1) }}
+ {{- range $i := until $drivesPerNode }}
+ - name: export-{{ $i }}
+ mountPath: {{ $mountPath }}-{{ $i }}
+ {{- if and $penabled $subPath }}
+ subPath: {{ $subPath }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ - name: export
+ mountPath: {{ $mountPath }}
+ {{- if and $penabled $subPath }}
+ subPath: {{ $subPath }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ mountPath: "/tmp/minio-config-env"
+ {{- end }}
+ {{- include "minio.tlsKeysVolumeMount" . | indent 12 }}
+ ports:
+ - name: {{ $scheme }}
+ containerPort: {{ .Values.minioAPIPort }}
+ - name: {{ $scheme }}-console
+ containerPort: {{ .Values.minioConsolePort }}
+ env:
+ - name: MINIO_ROOT_USER
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootUser
+ - name: MINIO_ROOT_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ template "minio.secretName" . }}
+ key: rootPassword
+ {{- if .Values.extraSecret }}
+ - name: MINIO_CONFIG_ENV_FILE
+ value: "/tmp/minio-config-env/config.env"
+ {{- end}}
+ {{- if .Values.metrics.serviceMonitor.public }}
+ - name: MINIO_PROMETHEUS_AUTH_TYPE
+ value: "public"
+ {{- end}}
+ {{- if .Values.oidc.enabled }}
+ - name: MINIO_IDENTITY_OPENID_CONFIG_URL
+ value: {{ .Values.oidc.configUrl }}
+ - name: MINIO_IDENTITY_OPENID_CLIENT_ID
+ value: {{ .Values.oidc.clientId }}
+ - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET
+ value: {{ .Values.oidc.clientSecret }}
+ - name: MINIO_IDENTITY_OPENID_CLAIM_NAME
+ value: {{ .Values.oidc.claimName }}
+ - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX
+ value: {{ .Values.oidc.claimPrefix }}
+ - name: MINIO_IDENTITY_OPENID_SCOPES
+ value: {{ .Values.oidc.scopes }}
+ - name: MINIO_IDENTITY_OPENID_REDIRECT_URI
+ value: {{ .Values.oidc.redirectUri }}
+ - name: MINIO_IDENTITY_OPENID_COMMENT
+ value: {{ .Values.oidc.comment }}
+ {{- end}}
+ {{- range $key, $val := .Values.environment }}
+ - name: {{ $key }}
+ value: {{ $val | quote }}
+ {{- end}}
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+{{- include "minio.imagePullSecrets" . | indent 6 }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- if and (gt $replicas 1) (ge .Capabilities.KubeVersion.Major "1") (ge .Capabilities.KubeVersion.Minor "19") }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- end }}
+ volumes:
+ - name: minio-user
+ secret:
+ secretName: {{ template "minio.secretName" . }}
+ {{- if .Values.extraSecret }}
+ - name: extra-secret
+ secret:
+ secretName: {{ .Values.extraSecret }}
+ {{- end }}
+ {{- include "minio.tlsKeysVolume" . | indent 8 }}
+{{- if .Values.persistence.enabled }}
+ volumeClaimTemplates:
+ {{- if gt $drivesPerNode 1 }}
+ {{- range $diskId := until $drivesPerNode}}
+ - metadata:
+ name: export-{{ $diskId }}
+ {{- if $.Values.persistence.annotations }}
+ annotations:
+{{ toYaml $.Values.persistence.annotations | trimSuffix "\n" | indent 10 }}
+ {{- end }}
+ spec:
+ accessModes: [ {{ $accessMode | quote }} ]
+ {{- if $storageClass }}
+ storageClassName: {{ $storageClass }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ $psize }}
+ {{- end }}
+ {{- else }}
+ - metadata:
+ name: export
+ {{- if $.Values.persistence.annotations }}
+ annotations:
+{{ toYaml $.Values.persistence.annotations | trimSuffix "\n" | indent 10 }}
+ {{- end }}
+ spec:
+ accessModes: [ {{ $accessMode | quote }} ]
+ {{- if $storageClass }}
+ storageClassName: {{ $storageClass }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ $psize }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/charts/minio/values.yaml b/charts/loki/charts/minio/values.yaml
new file mode 100644
index 0000000..457d647
--- /dev/null
+++ b/charts/loki/charts/minio/values.yaml
@@ -0,0 +1,482 @@
+## Provide a name in place of minio for `app:` labels
+##
+nameOverride: ""
+
+## Provide a name to substitute for the full names of resources
+##
+fullnameOverride: ""
+
+## set kubernetes cluster domain where minio is running
+##
+clusterDomain: cluster.local
+
+## Set default image, imageTag, and imagePullPolicy. mode is used to indicate the
+##
+image:
+ repository: quay.io/minio/minio
+ tag: RELEASE.2022-08-13T21-54-44Z
+ pullPolicy: IfNotPresent
+
+imagePullSecrets: []
+# - name: "image-pull-secret"
+
+## Set default image, imageTag, and imagePullPolicy for the `mc` (the minio
+## client used to create a default bucket).
+##
+mcImage:
+ repository: quay.io/minio/mc
+ tag: RELEASE.2022-08-11T00-30-48Z
+ pullPolicy: IfNotPresent
+
+## minio mode, i.e. standalone or distributed or gateway.
+mode: distributed ## other supported values are "standalone", "gateway"
+
+## Additional labels to include with deployment or statefulset
+additionalLabels: []
+
+## Additional annotations to include with deployment or statefulset
+additionalAnnotations: []
+
+## Typically the deployment/statefulset includes checksums of secrets/config,
+## So that when these change on a subsequent helm install, the deployment/statefulset
+## is restarted. This can result in unnecessary restarts under GitOps tooling such as
+## flux, so set to "true" to disable this behaviour.
+ignoreChartChecksums: false
+
+## Additional arguments to pass to minio binary
+extraArgs: []
+
+## Internal port number for MinIO S3 API container
+## Change service.port to change external port number
+minioAPIPort: "9000"
+
+## Internal port number for MinIO Browser Console container
+## Change consoleService.port to change external port number
+minioConsolePort: "9001"
+
+## Update strategy for Deployments
+DeploymentUpdate:
+ type: RollingUpdate
+ maxUnavailable: 0
+ maxSurge: 100%
+
+## Update strategy for StatefulSets
+StatefulSetUpdate:
+ updateStrategy: RollingUpdate
+
+## Pod priority settings
+## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
+##
+priorityClassName: ""
+
+## Pod runtime class name
+## ref https://kubernetes.io/docs/concepts/containers/runtime-class/
+##
+runtimeClassName: ""
+
+## Set default rootUser, rootPassword
+## AccessKey and secretKey is generated when not set
+## Distributed MinIO ref: https://docs.minio.io/docs/distributed-minio-quickstart-guide
+##
+rootUser: ""
+rootPassword: ""
+
+## Use existing Secret that store following variables:
+##
+## | Chart var | .data.<key> in Secret |
+## |:----------------------|:-------------------------|
+## | rootUser | rootUser |
+## | rootPassword | rootPassword |
+##
+## All mentioned variables will be ignored in values file.
+## .data.rootUser and .data.rootPassword are mandatory,
+## others depend on enabled status of corresponding sections.
+existingSecret: ""
+
+## Directory on the MinIO pof
+certsPath: "/etc/minio/certs/"
+configPathmc: "/etc/minio/mc/"
+
+## Path where PV would be mounted on the MinIO Pod
+mountPath: "/export"
+## Override the root directory which the minio server should serve from.
+## If left empty, it defaults to the value of {{ .Values.mountPath }}
+## If defined, it must be a sub-directory of the path specified in {{ .Values.mountPath }}
+##
+bucketRoot: ""
+
+# Number of drives attached to a node
+drivesPerNode: 1
+# Number of MinIO containers running
+replicas: 16
+# Number of expanded MinIO clusters
+pools: 1
+
+# Deploy if 'mode == gateway' - 4 replicas.
+gateway:
+ type: "nas" # currently only "nas" are supported.
+ replicas: 4
+
+## TLS Settings for MinIO
+tls:
+ enabled: false
+ ## Create a secret with private.key and public.crt files and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret
+ certSecret: ""
+ publicCrt: public.crt
+ privateKey: private.key
+
+## Trusted Certificates Settings for MinIO. Ref: https://docs.minio.io/docs/how-to-secure-access-to-minio-server-with-tls#install-certificates-from-third-party-cas
+## Bundle multiple trusted certificates into one secret and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret
+## When using self-signed certificates, remember to include MinIO's own certificate in the bundle with key public.crt.
+## If certSecret is left empty and tls is enabled, this chart installs the public certificate from .Values.tls.certSecret.
+trustedCertsSecret: ""
+
+## Enable persistence using Persistent Volume Claims
+## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
+##
+persistence:
+ enabled: true
+ annotations: {}
+
+ ## A manually managed Persistent Volume and Claim
+ ## Requires persistence.enabled: true
+ ## If defined, PVC must be created manually before volume will be bound
+ existingClaim: ""
+
+ ## minio data Persistent Volume Storage Class
+ ## If defined, storageClassName: <storageClass>
+ ## If set to "-", storageClassName: "", which disables dynamic provisioning
+ ## If undefined (the default) or set to null, no storageClassName spec is
+ ## set, choosing the default provisioner. (gp2 on AWS, standard on
+ ## GKE, AWS & OpenStack)
+ ##
+ ## Storage class of PV to bind. By default it looks for standard storage class.
+ ## If the PV uses a different storage class, specify that here.
+ storageClass: ""
+ VolumeName: ""
+ accessMode: ReadWriteOnce
+ size: 500Gi
+
+ ## If subPath is set mount a sub folder of a volume instead of the root of the volume.
+ ## This is especially handy for volume plugins that don't natively support sub mounting (like glusterfs).
+ ##
+ subPath: ""
+
+## Expose the MinIO service to be accessed from outside the cluster (LoadBalancer service).
+## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it.
+## ref: http://kubernetes.io/docs/user-guide/services/
+##
+service:
+ type: ClusterIP
+ clusterIP: ~
+ port: "9000"
+ nodePort: 32000
+
+## Configure Ingress based on the documentation here: https://kubernetes.io/docs/concepts/services-networking/ingress/
+##
+
+ingress:
+ enabled: false
+ # ingressClassName: ""
+ labels: {}
+ # node-role.kubernetes.io/ingress: platform
+
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ # kubernetes.io/ingress.allow-http: "false"
+ # kubernetes.io/ingress.global-static-ip-name: ""
+ # nginx.ingress.kubernetes.io/secure-backends: "true"
+ # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
+ # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
+ path: /
+ hosts:
+ - minio-example.local
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+consoleService:
+ type: ClusterIP
+ clusterIP: ~
+ port: "9001"
+ nodePort: 32001
+
+consoleIngress:
+ enabled: false
+ # ingressClassName: ""
+ labels: {}
+ # node-role.kubernetes.io/ingress: platform
+
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ # kubernetes.io/ingress.allow-http: "false"
+ # kubernetes.io/ingress.global-static-ip-name: ""
+ # nginx.ingress.kubernetes.io/secure-backends: "true"
+ # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
+ # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
+ path: /
+ hosts:
+ - console.minio-example.local
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+## Node labels for pod assignment
+## Ref: https://kubernetes.io/docs/user-guide/node-selection/
+##
+nodeSelector: {}
+tolerations: []
+affinity: {}
+topologySpreadConstraints: []
+
+## Add stateful containers to have security context, if enabled MinIO will run as this
+## user and group NOTE: securityContext is only enabled if persistence.enabled=true
+securityContext:
+ enabled: true
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ fsGroupChangePolicy: "OnRootMismatch"
+
+# Additational pod annotations
+podAnnotations: {}
+
+# Additional pod labels
+podLabels: {}
+
+## Configure resource requests and limits
+## ref: http://kubernetes.io/docs/user-guide/compute-resources/
+##
+resources:
+ requests:
+ memory: 16Gi
+
+## List of policies to be created after minio install
+##
+## In addition to default policies [readonly|readwrite|writeonly|consoleAdmin|diagnostics]
+## you can define additional policies with custom supported actions and resources
+policies: []
+## writeexamplepolicy policy grants creation or deletion of buckets with name
+## starting with example. In addition, grants objects write permissions on buckets starting with
+## example.
+# - name: writeexamplepolicy
+# statements:
+# - resources:
+# - 'arn:aws:s3:::example*/*'
+# actions:
+# - "s3:AbortMultipartUpload"
+# - "s3:GetObject"
+# - "s3:DeleteObject"
+# - "s3:PutObject"
+# - "s3:ListMultipartUploadParts"
+# - resources:
+# - 'arn:aws:s3:::example*'
+# actions:
+# - "s3:CreateBucket"
+# - "s3:DeleteBucket"
+# - "s3:GetBucketLocation"
+# - "s3:ListBucket"
+# - "s3:ListBucketMultipartUploads"
+## readonlyexamplepolicy policy grants access to buckets with name starting with example.
+## In addition, grants objects read permissions on buckets starting with example.
+# - name: readonlyexamplepolicy
+# statements:
+# - resources:
+# - 'arn:aws:s3:::example*/*'
+# actions:
+# - "s3:GetObject"
+# - resources:
+# - 'arn:aws:s3:::example*'
+# actions:
+# - "s3:GetBucketLocation"
+# - "s3:ListBucket"
+# - "s3:ListBucketMultipartUploads"
+## Additional Annotations for the Kubernetes Job makePolicyJob
+makePolicyJob:
+ podAnnotations:
+ annotations:
+ securityContext:
+ enabled: false
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ resources:
+ requests:
+ memory: 128Mi
+ nodeSelector: {}
+ tolerations: []
+ affinity: {}
+ # Command to run after the main command on exit
+ exitCommand: ""
+
+## List of users to be created after minio install
+##
+users:
+ ## Username, password and policy to be assigned to the user
+ ## Default policies are [readonly|readwrite|writeonly|consoleAdmin|diagnostics]
+ ## Add new policies as explained here https://docs.min.io/docs/minio-multi-user-quickstart-guide.html
+ ## NOTE: this will fail if LDAP is enabled in your MinIO deployment
+ ## make sure to disable this if you are using LDAP.
+ - accessKey: console
+ secretKey: console123
+ policy: consoleAdmin
+ # Or you can refer to specific secret
+ #- accessKey: externalSecret
+ # existingSecret: my-secret
+ # existingSecretKey: password
+ # policy: readonly
+
+
+## Additional Annotations for the Kubernetes Job makeUserJob
+makeUserJob:
+ podAnnotations:
+ annotations:
+ securityContext:
+ enabled: false
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ resources:
+ requests:
+ memory: 128Mi
+ nodeSelector: {}
+ tolerations: []
+ affinity: {}
+ # Command to run after the main command on exit
+ exitCommand: ""
+
+## List of buckets to be created after minio install
+##
+buckets:
+ # # Name of the bucket
+ # - name: bucket1
+ # # Policy to be set on the
+ # # bucket [none|download|upload|public]
+ # policy: none
+ # # Purge if bucket exists already
+ # purge: false
+ # # set versioning for
+ # # bucket [true|false]
+ # versioning: false
+ # # set objectlocking for
+ # # bucket [true|false] NOTE: versioning is enabled by default if you use locking
+ # objectlocking: false
+ # - name: bucket2
+ # policy: none
+ # purge: false
+ # versioning: true
+ # # set objectlocking for
+ # # bucket [true|false] NOTE: versioning is enabled by default if you use locking
+ # objectlocking: false
+
+## Additional Annotations for the Kubernetes Job makeBucketJob
+makeBucketJob:
+ podAnnotations:
+ annotations:
+ securityContext:
+ enabled: false
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ resources:
+ requests:
+ memory: 128Mi
+ nodeSelector: {}
+ tolerations: []
+ affinity: {}
+ # Command to run after the main command on exit
+ exitCommand: ""
+
+## List of command to run after minio install
+## NOTE: the mc command TARGET is always "myminio"
+customCommands:
+ # - command: "admin policy set myminio consoleAdmin group='cn=ops,cn=groups,dc=example,dc=com'"
+
+## Additional Annotations for the Kubernetes Job customCommandJob
+customCommandJob:
+ podAnnotations:
+ annotations:
+ securityContext:
+ enabled: false
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ resources:
+ requests:
+ memory: 128Mi
+ nodeSelector: {}
+ tolerations: []
+ affinity: {}
+ # Command to run after the main command on exit
+ exitCommand: ""
+
+## Use this field to add environment variables relevant to MinIO server. These fields will be passed on to MinIO container(s)
+## when Chart is deployed
+environment:
+ ## Please refer for comprehensive list https://docs.min.io/minio/baremetal/reference/minio-server/minio-server.html
+ ## MINIO_SUBNET_LICENSE: "License key obtained from https://subnet.min.io"
+ ## MINIO_BROWSER: "off"
+
+## The name of a secret in the same kubernetes namespace which contain secret values
+## This can be useful for LDAP password, etc
+## The key in the secret must be 'config.env'
+##
+# extraSecret: minio-extraenv
+
+## OpenID Identity Management
+## The following section documents environment variables for enabling external identity management using an OpenID Connect (OIDC)-compatible provider.
+## See https://docs.min.io/minio/baremetal/security/openid-external-identity-management/external-authentication-with-openid-identity-provider.html#minio-external-identity-management-openid for a tutorial on using these variables.
+oidc:
+ enabled: false
+ configUrl: "https://identity-provider-url/.well-known/openid-configuration"
+ clientId: "minio"
+ clientSecret: ""
+ claimName: "policy"
+ scopes: "openid,profile,email"
+ redirectUri: "https://console-endpoint-url/oauth_callback"
+ # Can leave empty
+ claimPrefix: ""
+ comment: ""
+
+networkPolicy:
+ enabled: false
+ allowExternal: true
+
+## PodDisruptionBudget settings
+## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/
+##
+podDisruptionBudget:
+ enabled: false
+ maxUnavailable: 1
+
+## Specify the service account to use for the MinIO pods. If 'create' is set to 'false'
+## and 'name' is left unspecified, the account 'default' will be used.
+serviceAccount:
+ create: true
+ ## The name of the service account to use. If 'create' is 'true', a service account with that name
+ ## will be created.
+ name: "minio-sa"
+
+metrics:
+ serviceMonitor:
+ enabled: false
+ public: true
+ additionalLabels: {}
+ annotations: {}
+ relabelConfigs: {}
+ # namespace: monitoring
+ # interval: 30s
+ # scrapeTimeout: 10s
+
+## ETCD settings: https://github.com/minio/minio/blob/master/docs/sts/etcd.md
+## Define endpoints to enable this section.
+etcd:
+ endpoints: []
+ pathPrefix: ""
+ corednsPathPrefix: ""
+ clientCert: ""
+ clientCertKey: ""
diff --git a/charts/loki/docs/examples/README.md b/charts/loki/docs/examples/README.md
new file mode 100644
index 0000000..84cbae3
--- /dev/null
+++ b/charts/loki/docs/examples/README.md
@@ -0,0 +1,4 @@
+## Introduction
+The Helm Charts found under the examples directory are getting started examples which you can use to deploy Loki using the Simple Scalable architecture quickly. Currently, the examples include:
+- [Deploying Grafana Enterprise Logs (Loki in Enterprise mode)](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/enterprise)
+- [Deploying Loki OSS](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/oss)
diff --git a/charts/loki/docs/examples/enterprise/README.md b/charts/loki/docs/examples/enterprise/README.md
new file mode 100644
index 0000000..42004f1
--- /dev/null
+++ b/charts/loki/docs/examples/enterprise/README.md
@@ -0,0 +1,29 @@
+## Introduction
+This example gives you an example or getting started overrides value file for deploying Loki (Enterprise Licensed) using the Simple Scalable architecture in GKE and using GCS
+
+## Installation of Helm Chart
+These instructions assume you have already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket.
+
+### Populate Secret Values
+Populate the examples/enterprise-secrets.yaml so that:
+- The gcp_service_account.json secret has the contents of your GCP Service Account JSON key
+- The gel-license.jwt secret has the contents of your Grafana Enterprise Logs license key given to your by Grafana Labs
+
+Deploy the secrets file to your k8s cluster.
+
+`kubectl apply -f enterprise-secrets.yaml`
+
+### Configure the Helm Chart
+Open examples/overides-enterprise-gcs.yaml and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/helm-charts/blob/main/charts/loki-simple-scalable/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file.
+
+### Install the Helm chart
+
+`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}`
+
+### Get the Token for Grafana to connect
+`export POD_NAME=$(kubectl get pods --namespace {KUBERNETES_NAMESPACE} -l "job-name=enterprise-logs-tokengen" -o jsonpath="{.items[0].metadata.name}")`
+
+`kubectl --namespace {KUBERNETES_NAMESPACE} logs $POD_NAME loki | grep Token`
+
+Take note of this token, you will need it when connecting Grafana Enterprise Logs to Grafana
+
diff --git a/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml b/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml
new file mode 100644
index 0000000..77266fa
--- /dev/null
+++ b/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: gel-secrets
+type: Opaque
+stringData:
+ gcp_service_account.json: |
+ {
+ GCP_SERVICE_ACCOUNT_JSON_HERE
+ }
+
+ gel-license.jwt: LICENSE_HERE
\ No newline at end of file
diff --git a/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml b/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml
new file mode 100644
index 0000000..348b8b7
--- /dev/null
+++ b/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml
@@ -0,0 +1,83 @@
+enterprise:
+ enabled: true
+ useExternalLicense: true
+ externalLicenseName: gel-secrets
+ tokengen:
+ env:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/gel_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: gel-secrets
+ mountPath: "/etc/gel_secrets"
+ extraVolumes:
+ - name: gel-secrets
+ secret:
+ secretName: gel-secrets
+ items:
+ - key: gel-license.jwt
+ path: license.jwt
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
+loki:
+ auth_enabled: true
+
+ storage:
+ type: gcs
+ bucketNames:
+ chunks: {YOUR_GCS_BUCKET}
+ ruler: {YOUR_GCS_BUCKET}
+ admin: {YOUR_GCS_BUCKET}
+
+minio:
+ enabled: false
+
+write:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/gel_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: gel-secrets
+ mountPath: "/etc/gel_secrets"
+ extraVolumes:
+ - name: gel-secrets
+ secret:
+ secretName: gel-secrets
+ items:
+ - key: gel-license.jwt
+ path: license.jwt
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
+
+read:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/gel_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: gel-secrets
+ mountPath: "/etc/gel_secrets"
+ extraVolumes:
+ - name: gel-secrets
+ secret:
+ secretName: gel-secrets
+ items:
+ - key: gel-license.jwt
+ path: license.jwt
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
+
+gateway:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/gel_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: gel-secrets
+ mountPath: "/etc/gel_secrets"
+ extraVolumes:
+ - name: gel-secrets
+ secret:
+ secretName: gel-secrets
+ items:
+ - key: gel-license.jwt
+ path: license.jwt
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
diff --git a/charts/loki/docs/examples/oss/README.md b/charts/loki/docs/examples/oss/README.md
new file mode 100644
index 0000000..0326de3
--- /dev/null
+++ b/charts/loki/docs/examples/oss/README.md
@@ -0,0 +1,20 @@
+## Introduction
+This example gives you an example or getting started overrides value file for deploying Loki (OSS) using the Simple Scalable architecture in GKE and using GCS
+
+## Installation of Helm Chart
+These instructions assume you have already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket.
+
+### Populate Secret Values
+Populate the examples/enterprise/enterprise-secrets.yaml so that:
+- The gcp_service_account.json secret has the contents of your GCP Service Account JSON key
+
+Deploy the secrets file to your k8s cluster.
+
+`kubectl apply -f loki-secrets.yaml`
+
+### Configure the Helm Chart
+Open examples/enterprise/overides-oss-gcs.yaml and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/helm-charts/blob/main/charts/loki-simple-scalable/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file.
+
+### Install the Helm chart
+
+`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}`
diff --git a/charts/loki/docs/examples/oss/oss-secrets.yaml b/charts/loki/docs/examples/oss/oss-secrets.yaml
new file mode 100644
index 0000000..4fbf5e7
--- /dev/null
+++ b/charts/loki/docs/examples/oss/oss-secrets.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: loki-secrets
+type: Opaque
+stringData:
+ gcp_service_account.json: |
+ {
+ GCP_SERVICE_ACCOUNT_JSON_HERE
+ }
\ No newline at end of file
diff --git a/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml b/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml
new file mode 100644
index 0000000..3e94f84
--- /dev/null
+++ b/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml
@@ -0,0 +1,77 @@
+enterprise:
+ enabled: false
+ adminApi:
+ enabled: false
+ useExternalLicense: false
+
+ config: |
+ admin_client:
+ storage:
+ gcs:
+ bucket_name: {YOUR_GCS_BUCKET}
+ auth:
+ type: trust
+ auth_enabled: false
+ cluster_name: loki-logs
+
+loki:
+ auth_enabled: false
+
+ commonConfig:
+ path_prefix: /var/loki
+ replication_factor: 3
+
+ storage:
+ type: gcs
+ bucketNames:
+ chunks: {YOUR_GCS_BUCKET}
+ ruler: {YOUR_GCS_BUCKET}
+ admin: {YOUR_GCS_BUCKET}
+
+minio:
+ enabled: false
+
+write:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/loki_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: loki-secrets
+ mountPath: "/etc/loki_secrets"
+ extraVolumes:
+ - name: loki-secrets
+ secret:
+ secretName: loki-secrets
+ items:
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
+
+read:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/loki_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: loki-secrets
+ mountPath: "/etc/loki_secrets"
+ extraVolumes:
+ - name: loki-secrets
+ secret:
+ secretName: loki-secrets
+ items:
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
+
+gateway:
+ extraEnv:
+ - name: GOOGLE_APPLICATION_CREDENTIALS
+ value: "/etc/loki_secrets/gcp_service_account.json"
+ extraVolumeMounts:
+ - name: loki-secrets
+ mountPath: "/etc/loki_secrets"
+ extraVolumes:
+ - name: loki-secrets
+ secret:
+ secretName: loki-secrets
+ items:
+ - key: gcp_service_account.json
+ path: gcp_service_account.json
diff --git a/charts/loki/reference.md.gotmpl b/charts/loki/reference.md.gotmpl
new file mode 100644
index 0000000..9636b1e
--- /dev/null
+++ b/charts/loki/reference.md.gotmpl
@@ -0,0 +1,47 @@
+---
+title: Helm Chart Values
+menuTitle: Helm Chart Values
+description: Reference for Helm Chart values.
+weight: 100
+keywords: []
+---
+
+<!-- Autogenerated. Modify ../production/helm/loki/reference.md.gotmpl -->
+
+# Helm Chart Values
+<!-- vale Grafana.Quotes = NO -->
+<!-- The reference title is required. Use a noun-based title. -->
+<!-- vale Grafana.Quotes = YES -->
+
+This is the generated reference for the Loki Helm Chart values.
+
+> **Note:** This reference is for the Loki Helm chart version 3.0 or greater.
+> If you are using the `grafana/loki-stack` Helm chart from the community repo,
+> please refer to the `values.yaml` of the respective Github repository
+> [grafana/helm-charts](https://github.com/grafana/helm-charts/tree/main/charts/loki-stack).
+
+<!-- Override default values table from helm-docs. See https://github.com/norwoodj/helm-docs/tree/master#advanced-table-rendering -->
+{{ define "chart.valuesTableHtml" }}
+{{ `{{< responsive-table >}}` }}
+<table>
+ <thead>
+ <th>Key</th>
+ <th>Type</th>
+ <th>Description</th>
+ <th>Default</th>
+ </thead>
+ <tbody>
+ {{- range .Values }}
+ <tr>
+ <td>{{ .Key }}</td>
+ <td>{{ .Type }}</td>
+ <td>{{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }}</td>
+ <td>{{ template "chart.valueDefaultColumnRender" . }}</td>
+ </tr>
+ {{- end }}
+ </tbody>
+</table>
+{{ `{{< /responsive-table >}}` }}
+{{ end }}
+
+{{ template "chart.valuesTableHtml" . }}
diff --git a/charts/loki/src/alerts.yaml b/charts/loki/src/alerts.yaml
new file mode 100644
index 0000000..b1e9687
--- /dev/null
+++ b/charts/loki/src/alerts.yaml
@@ -0,0 +1,52 @@
+groups:
+- name: loki_alerts
+ rules:
+ - alert: LokiRequestErrors
+ annotations:
+ message: |
+ {{ $labels.job }} {{ $labels.route }} is experiencing {{ printf "%.2f" $value }}% errors.
+ expr: |
+ 100 * sum(rate(loki_request_duration_seconds_count{status_code=~"5.."}[2m])) by (namespace, job, route)
+ /
+ sum(rate(loki_request_duration_seconds_count[2m])) by (namespace, job, route)
+ > 10
+ for: 15m
+ labels:
+ severity: critical
+ - alert: LokiRequestPanics
+ annotations:
+ message: |
+ {{ $labels.job }} is experiencing {{ printf "%.2f" $value }}% increase of panics.
+ expr: |
+ sum(increase(loki_panic_total[10m])) by (namespace, job) > 0
+ labels:
+ severity: critical
+ - alert: LokiRequestLatency
+ annotations:
+ message: |
+ {{ $labels.job }} {{ $labels.route }} is experiencing {{ printf "%.2f" $value }}s 99th percentile latency.
+ expr: |
+ namespace_job_route:loki_request_duration_seconds:99quantile{route!~"(?i).*tail.*"} > 1
+ for: 15m
+ labels:
+ severity: critical
+ - alert: LokiTooManyCompactorsRunning
+ annotations:
+ message: |
+ {{ $labels.cluster }} {{ $labels.namespace }} has had {{ printf "%.0f" $value }} compactors running for more than 5m. Only one compactor should run at a time.
+ expr: |
+ sum(loki_boltdb_shipper_compactor_running) by (namespace, cluster) > 1
+ for: 5m
+ labels:
+ severity: warning
+- name: 'loki_canaries_alerts'
+ rules:
+ - alert: 'LokiCanaryLatency'
+ annotations:
+ message: |
+ {{ $labels.job }} is experiencing {{ printf "%.2f" $value }}s 99th percentile latency.
+ expr: |
+ histogram_quantile(0.99, sum(rate(loki_canary_response_latency_seconds_bucket[5m])) by (le, namespace, job)) > 5
+ for: '15m'
+ labels:
+ severity: 'warning'
diff --git a/charts/loki/src/dashboards/loki-chunks.json b/charts/loki/src/dashboards/loki-chunks.json
new file mode 100644
index 0000000..8f30328
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-chunks.json
@@ -0,0 +1,1336 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "series",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Series",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}) / sum(loki_ingester_memory_streams{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "chunks",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunks per series",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Active Series / Chunks",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_ingester_chunk_utilization_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_utilization_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Utilization",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "percentunit",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_ingester_chunk_age_seconds_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1e3 / sum(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Age",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Flush Stats",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 5,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_ingester_chunk_entries_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_entries_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Log Entries Per Chunk",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_chunk_store_index_entries_per_chunk_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_chunk_store_index_entries_per_chunk_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Index Entries",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Index Entries Per Chunk",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Flush Stats",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 7,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "cortex_ingester_flush_queue_length{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Queue Length",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {
+ "1xx": "#EAB839",
+ "2xx": "#7EB26D",
+ "3xx": "#6ED0E0",
+ "4xx": "#EF843C",
+ "5xx": "#E24D42",
+ "error": "#E24D42",
+ "success": "#7EB26D"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 8,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Flush Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Flush Stats",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 9,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunks Flushed/Second",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 10,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (reason) (rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{reason}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunk Flush Reason",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": 1,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": 1,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Flush Stats",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "cards": {
+ "cardPadding": null,
+ "cardRound": null
+ },
+ "color": {
+ "cardColor": "#b4ff00",
+ "colorScale": "sqrt",
+ "colorScheme": "interpolateSpectral",
+ "exponent": 0.5,
+ "mode": "spectrum"
+ },
+ "dataFormat": "tsbuckets",
+ "datasource": "$datasource",
+ "heatmap": { },
+ "hideZeroBuckets": false,
+ "highlightCards": true,
+ "id": 11,
+ "legend": {
+ "show": true
+ },
+ "span": 12,
+ "targets": [
+ {
+ "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))",
+ "format": "heatmap",
+ "intervalFactor": 2,
+ "legendFormat": "{{le}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Chunk Utilization",
+ "tooltip": {
+ "show": true,
+ "showHistogram": true
+ },
+ "type": "heatmap",
+ "xAxis": {
+ "show": true
+ },
+ "xBucketNumber": null,
+ "xBucketSize": null,
+ "yAxis": {
+ "decimals": 0,
+ "format": "percentunit",
+ "show": true,
+ "splitFactor": null
+ },
+ "yBucketBound": "auto"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Utilization",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "cards": {
+ "cardPadding": null,
+ "cardRound": null
+ },
+ "color": {
+ "cardColor": "#b4ff00",
+ "colorScale": "sqrt",
+ "colorScheme": "interpolateSpectral",
+ "exponent": 0.5,
+ "mode": "spectrum"
+ },
+ "dataFormat": "tsbuckets",
+ "datasource": "$datasource",
+ "heatmap": { },
+ "hideZeroBuckets": false,
+ "highlightCards": true,
+ "id": 12,
+ "legend": {
+ "show": true
+ },
+ "span": 12,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)",
+ "format": "heatmap",
+ "intervalFactor": 2,
+ "legendFormat": "{{le}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Chunk Size Bytes",
+ "tooltip": {
+ "show": true,
+ "showHistogram": true
+ },
+ "type": "heatmap",
+ "xAxis": {
+ "show": true
+ },
+ "xBucketNumber": null,
+ "xBucketSize": null,
+ "yAxis": {
+ "decimals": 0,
+ "format": "bytes",
+ "show": true,
+ "splitFactor": null
+ },
+ "yBucketBound": "auto"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Utilization",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 13,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "p99",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.90, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "p90",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "p50",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunk Size Quantiles",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Utilization",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 14,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.5, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "p50",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "p99",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_ingester_chunk_bounds_hours_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_ingester_chunk_bounds_hours_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "avg",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunk Duration hours (end-start)",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Duration",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Chunks",
+ "uid": "chunks",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-deletion.json b/charts/loki/src/dashboards/loki-deletion.json
new file mode 100644
index 0000000..84bfee6
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-deletion.json
@@ -0,0 +1,632 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "100px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "format": "none",
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(loki_compactor_pending_delete_requests_count{cluster=~\"$cluster\", namespace=~\"$namespace\"})",
+ "format": "time_series",
+ "instant": true,
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "70,80",
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Number of Pending Requests",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "singlestat",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "format": "dtdurations",
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max(loki_compactor_oldest_pending_delete_request_age_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"})",
+ "format": "time_series",
+ "instant": true,
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "70,80",
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Oldest Pending Request Age",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "singlestat",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Headlines",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(increase(loki_compactor_delete_requests_received_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "received",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Delete Requests Received / Day",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(increase(loki_compactor_delete_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "processed",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Delete Requests Processed / Day",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Churn",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 5,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(increase(loki_compactor_load_pending_requests_attempts_total{status=\"fail\", cluster=~\"$cluster\", namespace=~\"$namespace\"}[1h]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "failures",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Failures in Loading Delete Requests / Hour",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Failures",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_compactor_deleted_lines{cluster=~\"$cluster\",job=~\"$namespace/(loki|enterprise-logs)-read\"}[$__rate_interval])) by (user)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{user}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Lines Deleted / Sec",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Deleted lines",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Deletion",
+ "uid": "deletion",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-logs.json b/charts/loki/src/dashboards/loki-logs.json
new file mode 100644
index 0000000..c09d154
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-logs.json
@@ -0,0 +1,1073 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "id": 8,
+ "iteration": 1583185057230,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 0,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 35,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(go_goroutines{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"})",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "goroutines",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 3,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 41,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(go_gc_duration_seconds{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}) by (quantile)",
+ "legendFormat": "{{quantile}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "gc duration",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 6,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 36,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(container_cpu_usage_seconds_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "cpu",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 9,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 40,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"})",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "working set",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 12,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 38,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "tx",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 15,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 39,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "rx",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "decbytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 18,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 37,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "increase(kube_pod_container_status_last_terminated_reason{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[30m]) > 0",
+ "legendFormat": "{{reason}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "restarts",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 3,
+ "x": 21,
+ "y": 0
+ },
+ "hiddenSeries": false,
+ "id": 42,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(promtail_custom_bad_words_total{cluster=\"$cluster\", exported_namespace=\"$namespace\", exported_pod=~\"$deployment.*\", exported_pod=~\"$pod\", container=~\"$container\"}[5m])) by (level)",
+ "legendFormat": "{{level}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "bad words",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$logs",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 24,
+ "x": 0,
+ "y": 4
+ },
+ "hiddenSeries": false,
+ "id": 31,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "warn",
+ "color": "#FF780A"
+ },
+ {
+ "alias": "error",
+ "color": "#E02F44"
+ },
+ {
+ "alias": "info",
+ "color": "#56A64B"
+ },
+ {
+ "alias": "debug",
+ "color": "#3274D9"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\" } |logfmt| level=\"$level\" |= \"$filter\" [5m])) by (level)",
+ "intervalFactor": 3,
+ "legendFormat": "{{level}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Log Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": false,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "datasource": "$logs",
+ "gridPos": {
+ "h": 19,
+ "w": 24,
+ "x": 0,
+ "y": 6
+ },
+ "id": 29,
+ "maxDataPoints": "",
+ "options": {
+ "showLabels": false,
+ "showTime": true,
+ "sortOrder": "Descending",
+ "wrapLogMessage": true
+ },
+ "targets": [
+ {
+ "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"} | logfmt | level=\"$level\" |= \"$filter\"",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Logs",
+ "type": "logs"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "hide": 0,
+ "label": null,
+ "name": "logs",
+ "options": [ ],
+ "query": "loki",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": { },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": null,
+ "multi": false,
+ "name": "deployment",
+ "options": [ ],
+ "query": "label_values(kube_deployment_created{cluster=\"$cluster\", namespace=\"$namespace\"}, deployment)",
+ "refresh": 0,
+ "regex": "",
+ "sort": 1,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": { },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": null,
+ "multi": false,
+ "name": "pod",
+ "options": [ ],
+ "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\"}, pod)",
+ "refresh": 0,
+ "regex": "",
+ "sort": 1,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": { },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": null,
+ "multi": false,
+ "name": "container",
+ "options": [ ],
+ "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\", pod=~\"$deployment.*\"}, container)",
+ "refresh": 0,
+ "regex": "",
+ "sort": 1,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "selected": true,
+ "text": "",
+ "value": ""
+ },
+ "hide": 0,
+ "includeAll": false,
+ "label": "",
+ "multi": true,
+ "name": "level",
+ "options": [
+ {
+ "selected": false,
+ "text": "debug",
+ "value": "debug"
+ },
+ {
+ "selected": false,
+ "text": "info",
+ "value": "info"
+ },
+ {
+ "selected": false,
+ "text": "warn",
+ "value": "warn"
+ },
+ {
+ "selected": false,
+ "text": "error",
+ "value": "error"
+ }
+ ],
+ "query": "debug,info,warn,error",
+ "refresh": 0,
+ "type": "custom"
+ },
+ {
+ "current": {
+ "selected": false,
+ "text": "",
+ "value": ""
+ },
+ "label": "LogQL Filter",
+ "name": "filter",
+ "query": "",
+ "type": "textbox"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Logs",
+ "uid": "logs",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-mixin-recording-rules.json b/charts/loki/src/dashboards/loki-mixin-recording-rules.json
new file mode 100644
index 0000000..fe49ec7
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-mixin-recording-rules.json
@@ -0,0 +1,657 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "-- Grafana --",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "target": {
+ "limit": 100,
+ "matchAny": false,
+ "tags": [ ],
+ "type": "dashboard"
+ },
+ "type": "dashboard"
+ },
+ {
+ "datasource": "${datasource}",
+ "enable": false,
+ "expr": "sum by (tenant) (changes(loki_ruler_wal_prometheus_tsdb_wal_truncations_total{tenant=~\"${tenant}\"}[$__rate_interval]))",
+ "iconColor": "red",
+ "name": "WAL Truncations",
+ "target": {
+ "queryType": "Azure Monitor",
+ "refId": "Anno"
+ },
+ "titleFormat": "{{tenant}}"
+ }
+ ]
+ },
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "iteration": 1635347545534,
+ "links": [ ],
+ "liveNow": false,
+ "panels": [
+ {
+ "datasource": "${datasource}",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [ ],
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 1
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 2,
+ "x": 0,
+ "y": 0
+ },
+ "id": 2,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "auto"
+ },
+ "pluginVersion": "8.3.0-38205pre",
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": false,
+ "expr": "sum(loki_ruler_wal_appender_ready) by (pod, tenant) == 0",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "Appenders Not Ready",
+ "type": "stat"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 11,
+ "x": 2,
+ "y": 0
+ },
+ "id": 4,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "sum(rate(loki_ruler_wal_samples_appended_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Samples Appended to WAL per Second",
+ "type": "timeseries"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "Series are unique combinations of labels",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 11,
+ "x": 13,
+ "y": 0
+ },
+ "id": 5,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "sum(rate(loki_ruler_wal_storage_created_series_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Series Created per Second",
+ "type": "timeseries"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "Difference between highest timestamp appended to WAL and highest timestamp successfully written to remote storage",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 0,
+ "y": 10
+ },
+ "id": 6,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "loki_ruler_wal_prometheus_remote_storage_highest_timestamp_in_seconds{tenant=~\"${tenant}\"}\n- on (tenant)\n (\n loki_ruler_wal_prometheus_remote_storage_queue_highest_sent_timestamp_seconds{tenant=~\"${tenant}\"}\n or vector(0)\n )",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Write Behind",
+ "type": "timeseries"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 12,
+ "y": 10
+ },
+ "id": 7,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "sum(rate(loki_ruler_wal_prometheus_remote_storage_samples_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Samples Sent per Second",
+ "type": "timeseries"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "\n",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "bytes"
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 0,
+ "y": 20
+ },
+ "id": 8,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "sum by (tenant) (loki_ruler_wal_disk_size{tenant=~\"${tenant}\"})",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "WAL Disk Size",
+ "type": "timeseries"
+ },
+ {
+ "datasource": "${datasource}",
+ "description": "Some number of pending samples is expected, but if remote-write is failing this value will remain high",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": [ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 12,
+ "y": 20
+ },
+ "id": 9,
+ "options": {
+ "legend": {
+ "calcs": [ ],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": "${datasource}",
+ "exemplar": true,
+ "expr": "max(loki_ruler_wal_prometheus_remote_storage_samples_pending{tenant=~\"${tenant}\"}) by (tenant,pod) > 0",
+ "interval": "",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Pending Samples",
+ "type": "timeseries"
+ }
+ ],
+ "schemaVersion": 31,
+ "style": "dark",
+ "tags": [ ],
+ "templating": {
+ "list": [
+ {
+ "description": null,
+ "error": null,
+ "hide": 0,
+ "includeAll": false,
+ "label": "Datasource",
+ "multi": false,
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "queryValue": "",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "datasource": "${datasource}",
+ "definition": "label_values(loki_ruler_wal_samples_appended_total, tenant)",
+ "description": null,
+ "error": null,
+ "hide": 0,
+ "includeAll": true,
+ "label": "Tenant",
+ "multi": true,
+ "name": "tenant",
+ "options": [ ],
+ "query": {
+ "query": "label_values(loki_ruler_wal_samples_appended_total, tenant)",
+ "refId": "StandardVariableQuery"
+ },
+ "refresh": 2,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 0,
+ "type": "query"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-6h",
+ "to": "now"
+ },
+ "timepicker": { },
+ "timezone": "",
+ "title": "Recording Rules",
+ "uid": "2xKA_ZK7k",
+ "version": 9,
+ "weekStart": ""
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-operational.json b/charts/loki/src/dashboards/loki-operational.json
new file mode 100644
index 0000000..b69db23
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-operational.json
@@ -0,0 +1,6173 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "id": 68,
+ "iteration": 1588704280892,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "panels": [
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "id": 17,
+ "panels": [ ],
+ "targets": [ ],
+ "title": "Main",
+ "type": "row"
+ },
+ {
+ "aliasColors": {
+ "5xx": "red"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 4,
+ "x": 0,
+ "y": 1
+ },
+ "hiddenSeries": false,
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\")\n)",
+ "legendFormat": "{{status}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Queries/Second",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 10,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "5xx": "red"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 4,
+ "x": 4,
+ "y": 1
+ },
+ "hiddenSeries": false,
+ "id": 7,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))",
+ "legendFormat": "{{status}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Pushes/Second",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 10,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 4,
+ "x": 12,
+ "y": 1
+ },
+ "hiddenSeries": false,
+ "id": 2,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10, sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant))",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Lines Per Tenant (top 10)",
+ "tooltip": {
+ "shared": false,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 4,
+ "x": 16,
+ "y": 1
+ },
+ "hiddenSeries": false,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10, sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant)) / 1024 / 1024",
+ "legendFormat": "{{tenant}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "MBs Per Tenant (Top 10)",
+ "tooltip": {
+ "shared": false,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 4,
+ "x": 20,
+ "y": 1
+ },
+ "hiddenSeries": false,
+ "id": 24,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "increase(kube_pod_container_status_restarts_total{cluster=\"$cluster\", namespace=\"$namespace\"}[10m]) > 0",
+ "hide": false,
+ "interval": "",
+ "legendFormat": "{{container}}-{{pod}}",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Container Restarts",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 0,
+ "y": 6
+ },
+ "hiddenSeries": false,
+ "id": 9,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".99",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.75, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".9",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".5",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Push Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 12,
+ "y": 6
+ },
+ "hiddenSeries": false,
+ "id": 12,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".99",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.9, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".9",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".5",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Distributor Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 18,
+ "y": 6
+ },
+ "hiddenSeries": false,
+ "id": 71,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)",
+ "interval": "",
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Distributor Success Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percentunit",
+ "label": "",
+ "logBase": 1,
+ "max": "1",
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 12,
+ "y": 11
+ },
+ "hiddenSeries": false,
+ "id": 13,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3",
+ "legendFormat": ".99",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.9, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3",
+ "hide": false,
+ "legendFormat": ".9",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3",
+ "hide": false,
+ "legendFormat": ".5",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Ingester Latency Write",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 18,
+ "y": 11
+ },
+ "hiddenSeries": false,
+ "id": 72,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)",
+ "interval": "",
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Ingester Success Rate Write",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percentunit",
+ "label": "",
+ "logBase": 1,
+ "max": "1",
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 12,
+ "x": 0,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 10,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "hideEmpty": true,
+ "hideZero": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))",
+ "legendFormat": "{{route}}-.99",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))",
+ "legendFormat": "{{route}}-.9",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))",
+ "legendFormat": "{{route}}-.5",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Query Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 12,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 14,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".99-{{route}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".9-{{route}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".5-{{route}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Querier Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 18,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 73,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[5m])) by (route)",
+ "interval": "",
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Querier Success Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percentunit",
+ "label": "",
+ "logBase": 1,
+ "max": "1",
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 12,
+ "y": 21
+ },
+ "hiddenSeries": false,
+ "id": 15,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".99-{{route}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".9-{{route}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3",
+ "legendFormat": ".5-{{route}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Ingester Latency Read",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "custom": { }
+ },
+ "overrides": [ ]
+ },
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 5,
+ "w": 6,
+ "x": 18,
+ "y": 21
+ },
+ "hiddenSeries": false,
+ "id": 74,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)",
+ "interval": "",
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Ingester Success Rate Read",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percentunit",
+ "label": "",
+ "logBase": 1,
+ "max": "1",
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 26
+ },
+ "id": 110,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 27
+ },
+ "hiddenSeries": false,
+ "id": 112,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10,sum by (tenant, reason) (rate(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])))",
+ "interval": "",
+ "legendFormat": "{{ tenant }} - {{ reason }}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Discarded Lines",
+ "tooltip": {
+ "shared": false,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "columns": [ ],
+ "datasource": "$datasource",
+ "fontSize": "100%",
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 27
+ },
+ "id": 113,
+ "pageSize": null,
+ "panels": [ ],
+ "showHeader": true,
+ "sort": {
+ "col": 3,
+ "desc": true
+ },
+ "styles": [
+ {
+ "alias": "Time",
+ "align": "auto",
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "pattern": "Time",
+ "type": "hidden"
+ },
+ {
+ "alias": "",
+ "align": "auto",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "mappingType": 1,
+ "pattern": "tenant",
+ "thresholds": [ ],
+ "type": "string",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "align": "auto",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "dateFormat": "YYYY-MM-DD HH:mm:ss",
+ "decimals": 2,
+ "mappingType": 1,
+ "pattern": "reason",
+ "thresholds": [ ],
+ "type": "number",
+ "unit": "short"
+ },
+ {
+ "alias": "",
+ "align": "right",
+ "colorMode": null,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "decimals": 2,
+ "pattern": "/.*/",
+ "thresholds": [ ],
+ "type": "number",
+ "unit": "short"
+ }
+ ],
+ "targets": [
+ {
+ "expr": "topk(10, sum by (tenant, reason) (sum_over_time(increase(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])[$__range:1m])))",
+ "format": "table",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "{{ tenant }} - {{ reason }}",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Discarded Lines Per Interval",
+ "transform": "table",
+ "type": "table-old"
+ }
+ ],
+ "targets": [ ],
+ "title": "Limits",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 27
+ },
+ "id": 23,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 28
+ },
+ "hiddenSeries": false,
+ "id": 26,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": true,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}",
+ "intervalFactor": 3,
+ "legendFormat": "{{pod}}-{{container}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "CPU Usage",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 28
+ },
+ "hiddenSeries": false,
+ "id": 27,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "hideEmpty": false,
+ "hideZero": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": true,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}",
+ "instant": false,
+ "intervalFactor": 3,
+ "legendFormat": "{{pod}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Memory Usage",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": true,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$logs",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 4,
+ "w": 12,
+ "x": 12,
+ "y": 28
+ },
+ "hiddenSeries": false,
+ "id": 31,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "{}",
+ "color": "#C4162A"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"[1m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Error Log Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": false,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "datasource": "$logs",
+ "gridPos": {
+ "h": 18,
+ "w": 12,
+ "x": 12,
+ "y": 32
+ },
+ "id": 29,
+ "options": {
+ "showLabels": false,
+ "showTime": false,
+ "sortOrder": "Descending",
+ "wrapLogMessage": true
+ },
+ "panels": [ ],
+ "targets": [
+ {
+ "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Logs",
+ "type": "logs"
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 35
+ },
+ "hiddenSeries": false,
+ "id": 33,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Success Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 35
+ },
+ "hiddenSeries": false,
+ "id": 32,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_distributor_ingester_append_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (ingester)",
+ "intervalFactor": 1,
+ "legendFormat": "{{ingester}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Append Failures By Ingester",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 42
+ },
+ "hiddenSeries": false,
+ "id": 34,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)",
+ "intervalFactor": 1,
+ "legendFormat": "{{pod}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Bytes Received/Second",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 42
+ },
+ "hiddenSeries": false,
+ "id": 35,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)",
+ "intervalFactor": 1,
+ "legendFormat": "{{pod}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Lines Received/Second",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Write Path",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 29
+ },
+ "id": 104,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 30
+ },
+ "hiddenSeries": false,
+ "id": 106,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10,sum by (tenant) (loki_ingester_memory_streams{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}))",
+ "interval": "",
+ "legendFormat": "{{ tenant }}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Active Streams",
+ "tooltip": {
+ "shared": false,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 30
+ },
+ "hiddenSeries": false,
+ "id": 108,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10, sum by (tenant) (rate(loki_ingester_streams_created_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]) > 0))",
+ "interval": "",
+ "legendFormat": "{{ tenant }}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Streams Created/Sec",
+ "tooltip": {
+ "shared": false,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Streams",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 30
+ },
+ "id": 94,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 31
+ },
+ "hiddenSeries": false,
+ "id": 102,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "De-Dupe Ratio",
+ "yaxis": 2
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))",
+ "interval": "",
+ "legendFormat": "Chunks",
+ "refId": "A"
+ },
+ {
+ "expr": "sum(increase(loki_chunk_store_deduped_chunks_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))/sum(increase(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) < 1",
+ "interval": "",
+ "legendFormat": "De-Dupe Ratio",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Chunks Flushed/Sec",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "cards": {
+ "cardPadding": null,
+ "cardRound": null
+ },
+ "color": {
+ "cardColor": "#b4ff00",
+ "colorScale": "sqrt",
+ "colorScheme": "interpolateSpectral",
+ "exponent": 0.5,
+ "mode": "spectrum"
+ },
+ "dataFormat": "tsbuckets",
+ "datasource": "$datasource",
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 31
+ },
+ "heatmap": { },
+ "hideZeroBuckets": false,
+ "highlightCards": true,
+ "id": 100,
+ "legend": {
+ "show": true
+ },
+ "panels": [ ],
+ "reverseYBuckets": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) by (le)",
+ "format": "heatmap",
+ "instant": false,
+ "interval": "",
+ "legendFormat": "{{ le }}",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunk Size Bytes",
+ "tooltip": {
+ "show": true,
+ "showHistogram": false
+ },
+ "type": "heatmap",
+ "xAxis": {
+ "show": true
+ },
+ "xBucketNumber": null,
+ "xBucketSize": null,
+ "yAxis": {
+ "decimals": 0,
+ "format": "bytes",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true,
+ "splitFactor": null
+ },
+ "yBucketBound": "auto",
+ "yBucketNumber": null,
+ "yBucketSize": null
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 7,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 0,
+ "y": 39
+ },
+ "hiddenSeries": false,
+ "id": 96,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(reason) (rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval]))",
+ "interval": "",
+ "legendFormat": "{{ reason }}"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Chunk Flush Reason %",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "percentunit",
+ "label": null,
+ "logBase": 1,
+ "max": "1",
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "cards": {
+ "cardPadding": null,
+ "cardRound": null
+ },
+ "color": {
+ "cardColor": "#b4ff00",
+ "colorScale": "sqrt",
+ "colorScheme": "interpolateSpectral",
+ "exponent": 0.5,
+ "max": null,
+ "min": null,
+ "mode": "spectrum"
+ },
+ "dataFormat": "tsbuckets",
+ "datasource": "$datasource",
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 12,
+ "y": 39
+ },
+ "heatmap": { },
+ "hideZeroBuckets": true,
+ "highlightCards": true,
+ "id": 98,
+ "legend": {
+ "show": true
+ },
+ "panels": [ ],
+ "reverseYBuckets": false,
+ "targets": [
+ {
+ "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))",
+ "format": "heatmap",
+ "instant": false,
+ "interval": "",
+ "legendFormat": "{{ le }}",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Chunk Utilization",
+ "tooltip": {
+ "show": true,
+ "showHistogram": false
+ },
+ "type": "heatmap",
+ "xAxis": {
+ "show": true
+ },
+ "xBucketNumber": null,
+ "xBucketSize": null,
+ "yAxis": {
+ "decimals": 0,
+ "format": "percentunit",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true,
+ "splitFactor": null
+ },
+ "yBucketBound": "auto",
+ "yBucketNumber": null,
+ "yBucketSize": null
+ }
+ ],
+ "targets": [ ],
+ "title": "Chunks",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 31
+ },
+ "id": 64,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 32
+ },
+ "hiddenSeries": false,
+ "id": 68,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": true,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}",
+ "intervalFactor": 3,
+ "legendFormat": "{{pod}}-{{container}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "CPU Usage",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 39
+ },
+ "hiddenSeries": false,
+ "id": 69,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "hideEmpty": false,
+ "hideZero": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": true,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}",
+ "instant": false,
+ "intervalFactor": 3,
+ "legendFormat": "{{pod}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Memory Usage",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": true,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$logs",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 3,
+ "w": 18,
+ "x": 12,
+ "y": 32
+ },
+ "hiddenSeries": false,
+ "id": 65,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "{}",
+ "color": "#F2495C"
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"[1m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Error Log Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": false,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "datasource": "$logs",
+ "gridPos": {
+ "h": 18,
+ "w": 18,
+ "x": 12,
+ "y": 35
+ },
+ "id": 66,
+ "options": {
+ "showLabels": false,
+ "showTime": false,
+ "sortOrder": "Descending",
+ "wrapLogMessage": true
+ },
+ "panels": [ ],
+ "targets": [
+ {
+ "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"",
+ "refId": "A"
+ }
+ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Logs",
+ "type": "logs"
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 0,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 46
+ },
+ "hiddenSeries": false,
+ "id": 70,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[1m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[1m])) by (route)",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "{{route}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Success Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Read Path",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 32
+ },
+ "id": 52,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 30
+ },
+ "hiddenSeries": false,
+ "id": 53,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))",
+ "intervalFactor": 1,
+ "legendFormat": "{{container}}: .99-{{method}}-{{name}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))",
+ "hide": false,
+ "legendFormat": "{{container}}: .9-{{method}}-{{name}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))",
+ "hide": false,
+ "legendFormat": "{{container}}: .5-{{method}}-{{name}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 38
+ },
+ "hiddenSeries": false,
+ "id": 54,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_memcache_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, method, name, container)",
+ "intervalFactor": 1,
+ "legendFormat": "{{container}}: {{status_code}}-{{method}}-{{name}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Memcached",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 33
+ },
+ "id": 57,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 31
+ },
+ "hiddenSeries": false,
+ "id": 55,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 39
+ },
+ "hiddenSeries": false,
+ "id": 58,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, status_code, method)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Consul",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 34
+ },
+ "id": 43,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 41,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".9",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "MutateRows Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 46,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "99%",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))",
+ "interval": "",
+ "legendFormat": "90%",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))",
+ "interval": "",
+ "legendFormat": "50%",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "ReadRows Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 12,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 44,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "99%",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))",
+ "interval": "",
+ "legendFormat": "90%",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))",
+ "interval": "",
+ "legendFormat": "50%",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "GetTable Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 18,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 45,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".9",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "ListTables Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 0,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 47,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (status_code)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "MutateRows Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 6,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 50,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (status_code)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "ReadRows Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 12,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 48,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (status_code)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "GetTable Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 7,
+ "w": 6,
+ "x": 18,
+ "y": 16
+ },
+ "hiddenSeries": false,
+ "id": 49,
+ "interval": "",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (status_code)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "ListTables Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Big Table",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 35
+ },
+ "id": 60,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 33
+ },
+ "hiddenSeries": false,
+ "id": 61,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 41
+ },
+ "hiddenSeries": false,
+ "id": 62,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_gcs_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "GCS",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 36
+ },
+ "id": 76,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": null,
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 0,
+ "y": 9
+ },
+ "id": 82,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(cortex_dynamo_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Failure Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": null,
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 6,
+ "y": 9
+ },
+ "id": 83,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(cortex_dynamo_consumed_capacity_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Consumed Capacity Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": null,
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 12,
+ "y": 9
+ },
+ "id": 84,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(cortex_dynamo_throttled_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Throttled Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": null,
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 18,
+ "y": 9
+ },
+ "id": 85,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(cortex_dynamo_dropped_requests_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Dropped Rate",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": null,
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 0,
+ "y": 15
+ },
+ "id": 86,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 2,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))",
+ "legendFormat": ".99",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))",
+ "legendFormat": ".9",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))",
+ "legendFormat": ".5",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Query Pages",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 9,
+ "x": 6,
+ "y": 15
+ },
+ "id": 87,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 6,
+ "w": 9,
+ "x": 15,
+ "y": 15
+ },
+ "id": 88,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(cortex_dynamo_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Dynamo",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 37
+ },
+ "id": 78,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 10
+ },
+ "id": 79,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 18
+ },
+ "id": 80,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_s3_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "S3",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 37
+ },
+ "id": 78,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 10
+ },
+ "id": 79,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 18
+ },
+ "id": 80,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_azure_blob_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "Azure Blob",
+ "type": "row"
+ },
+ {
+ "collapsed": true,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 37
+ },
+ "id": 114,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 10
+ },
+ "id": 115,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "intervalFactor": 1,
+ "legendFormat": ".99-{{operation}}",
+ "refId": "A"
+ },
+ {
+ "expr": "histogram_quantile(.9, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".9-{{operation}}",
+ "refId": "B"
+ },
+ {
+ "expr": "histogram_quantile(.5, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))",
+ "hide": false,
+ "legendFormat": ".5-{{operation}}",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Latency By Operation",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 18
+ },
+ "id": 116,
+ "interval": "",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": [ ]
+ },
+ "panels": [ ],
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)",
+ "intervalFactor": 1,
+ "legendFormat": "{{status_code}}-{{operation}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeRegions": [ ],
+ "timeShift": null,
+ "title": "Status By Method",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "targets": [ ],
+ "title": "BoltDB Shipper",
+ "type": "row"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "hide": 0,
+ "label": null,
+ "name": "logs",
+ "options": [ ],
+ "query": "loki",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Operational",
+ "uid": "operational",
+ "version": 0
+ }
diff --git a/charts/loki/src/dashboards/loki-reads-resources.json b/charts/loki/src/dashboards/loki-reads-resources.json
new file mode 100644
index 0000000..6fa166f
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-reads-resources.json
@@ -0,0 +1,964 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "collapsed": false,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (workingset)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (go heap inuse)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "gridPos": { },
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}} - {{device}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Writes",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "gridPos": { },
+ "id": 5,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}} - {{device}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Reads",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-read.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{persistentvolumeclaim}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Space Utilization",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "percentunit",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 7,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "loki_boltdb_shipper_query_readiness_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "duration",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Query Readiness Duration",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Read path",
+ "titleSize": "h6",
+ "type": "row"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 8,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 9,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (workingset)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 10,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (go heap inuse)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Ingester",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Reads Resources",
+ "uid": "reads-resources",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-reads.json b/charts/loki/src/dashboards/loki-reads.json
new file mode 100644
index 0000000..6cae30f
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-reads.json
@@ -0,0 +1,504 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {
+ "1xx": "#EAB839",
+ "2xx": "#7EB26D",
+ "3xx": "#6ED0E0",
+ "4xx": "#EF843C",
+ "5xx": "#E24D42",
+ "error": "#E24D42",
+ "success": "#7EB26D"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "QPS",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ route }} 99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ route }} 50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "1e3 * sum(job_route:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) / sum(job_route:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) ",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ route }} Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Read Path",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {
+ "1xx": "#EAB839",
+ "2xx": "#7EB26D",
+ "3xx": "#6ED0E0",
+ "4xx": "#EF843C",
+ "5xx": "#E24D42",
+ "error": "#E24D42",
+ "success": "#7EB26D"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "QPS",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "BoltDB Shipper",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Reads",
+ "uid": "reads",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-retention.json b/charts/loki/src/dashboards/loki-retention.json
new file mode 100644
index 0000000..7fc99ec
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-retention.json
@@ -0,0 +1,1537 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (workingset)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (go heap inuse)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Resource Usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "blue",
+ "mode": "fixed"
+ },
+ "custom": { },
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "dateTimeFromNow"
+ }
+ },
+ "fill": 1,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "text": { },
+ "textMode": "auto"
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "loki_boltdb_shipper_compact_tables_operation_last_successful_run_timestamp_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"} * 1e3",
+ "format": "time_series",
+ "instant": true,
+ "refId": "A"
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Last Compact and Mark Operation Success",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "stat",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 5,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "loki_boltdb_shipper_compact_tables_operation_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "duration",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Compact and Mark Operations Duration",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status)(rate(loki_boltdb_shipper_compact_tables_operation_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{success}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Compact and Mark Operations Per Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Compact and Mark",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 7,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "count by(action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{action}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Processed Tables Per Action",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 8,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "count by(table,action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\" , action=~\"modified|deleted\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{table}}-{{action}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Modified Tables",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 9,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (table)(rate(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) >0",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{table}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Marks Creation Rate Per Table",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Per Table Marker",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "format": "short",
+ "id": 10,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (increase(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))",
+ "format": "time_series",
+ "instant": true,
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "70,80",
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Marked Chunks (24h)",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "singlestat",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 11,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Mark Table Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "format": "short",
+ "id": 12,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (increase(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))",
+ "format": "time_series",
+ "instant": true,
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "70,80",
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Delete Chunks (24h)",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "singlestat",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 13,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Delete Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Sweeper",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 14,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "time() - (loki_boltdb_shipper_retention_sweeper_marker_file_processing_current_time{cluster=~\"$cluster\", namespace=~\"$namespace\"} > 0)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "lag",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Sweeper Lag",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 15,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(loki_boltdb_shipper_retention_sweeper_marker_files_current{cluster=~\"$cluster\", namespace=~\"$namespace\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "count",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Marks Files to Process",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 16,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status)(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Delete Rate Per Status",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "datasource": "$logs",
+ "id": 17,
+ "span": 12,
+ "targets": [
+ {
+ "expr": "{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}",
+ "refId": "A"
+ }
+ ],
+ "title": "Compactor Logs",
+ "type": "logs"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Logs",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "hide": 0,
+ "label": null,
+ "name": "logs",
+ "options": [ ],
+ "query": "loki",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Retention",
+ "uid": "retention",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-writes-resources.json b/charts/loki/src/dashboards/loki-writes-resources.json
new file mode 100644
index 0000000..1b68bd3
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-writes-resources.json
@@ -0,0 +1,700 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "collapsed": false,
+ "panels": [
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (loki_ingester_memory_streams{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "In-memory streams",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "limit",
+ "color": "#E02F44",
+ "fill": 0
+ }
+ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ },
+ {
+ "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "limit",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (workingset)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Memory (go heap inuse)",
+ "tooltip": {
+ "sort": 2
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "gridPos": { },
+ "id": 5,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}} - {{device}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Writes",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "gridPos": { },
+ "id": 6,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{pod}} - {{device}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Reads",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "gridPos": { },
+ "id": 7,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-write.*\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{persistentvolumeclaim}}",
+ "legendLink": null,
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Disk Space Utilization",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "percentunit",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Write path",
+ "titleSize": "h6",
+ "type": "row"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Writes Resources",
+ "uid": "writes-resources",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/dashboards/loki-writes.json b/charts/loki/src/dashboards/loki-writes.json
new file mode 100644
index 0000000..ebaf33e
--- /dev/null
+++ b/charts/loki/src/dashboards/loki-writes.json
@@ -0,0 +1,504 @@
+{
+ "annotations": {
+ "list": [ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "links": [
+ {
+ "asDropdown": true,
+ "icon": "external link",
+ "includeVars": true,
+ "keepTime": true,
+ "tags": [
+ "loki"
+ ],
+ "targetBlank": false,
+ "title": "Loki Dashboards",
+ "type": "dashboards"
+ }
+ ],
+ "refresh": "10s",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {
+ "1xx": "#EAB839",
+ "2xx": "#7EB26D",
+ "3xx": "#6ED0E0",
+ "4xx": "#EF843C",
+ "5xx": "#E24D42",
+ "error": "#E24D42",
+ "success": "#7EB26D"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 1,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push|/httpgrpc.HTTP/Handle\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "QPS",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 2,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "1e3 * sum(job:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"}) / sum(job:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Write Path",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {
+ "1xx": "#EAB839",
+ "2xx": "#7EB26D",
+ "3xx": "#6ED0E0",
+ "4xx": "#EF843C",
+ "5xx": "#E24D42",
+ "error": "#E24D42",
+ "success": "#7EB26D"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 10,
+ "id": 3,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 0,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{status}}",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "QPS",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": { },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "$datasource",
+ "fill": 1,
+ "id": 4,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [ ],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [ ],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "99th Percentile",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "50th Percentile",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Average",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [ ],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": [ ]
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "BoltDB Shipper",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "text": "default",
+ "value": "default"
+ },
+ "hide": 0,
+ "label": "Data Source",
+ "name": "datasource",
+ "options": [ ],
+ "query": "prometheus",
+ "refresh": 1,
+ "regex": "",
+ "type": "datasource"
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "cluster",
+ "multi": false,
+ "name": "cluster",
+ "options": [ ],
+ "query": "label_values(loki_build_info, cluster)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "allValue": null,
+ "current": {
+ "text": "prod",
+ "value": "prod"
+ },
+ "datasource": "$datasource",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": false,
+ "name": "namespace",
+ "options": [ ],
+ "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 2,
+ "tagValuesQuery": "",
+ "tags": [ ],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "utc",
+ "title": "Loki / Writes",
+ "uid": "writes",
+ "version": 0
+ }
\ No newline at end of file
diff --git a/charts/loki/src/helm-test/Dockerfile b/charts/loki/src/helm-test/Dockerfile
new file mode 100644
index 0000000..5ffb228
--- /dev/null
+++ b/charts/loki/src/helm-test/Dockerfile
@@ -0,0 +1,13 @@
+FROM golang:1.18.5 as build
+
+# build via Makefile target helm-test-image in root
+# Makefile. Building from this directory will not be
+# able to access source needed in rest of repo.
+COPY . /src/loki
+WORKDIR /src/loki
+RUN make clean && make BUILD_IN_CONTAINER=false helm-test
+
+FROM alpine:3.16.2
+RUN apk add --update --no-cache ca-certificates=20220614-r0
+COPY --from=build /src/loki/production/helm/loki/src/helm-test/helm-test /usr/bin/helm-test
+ENTRYPOINT [ "/usr/bin/helm-test" ]
diff --git a/charts/loki/src/helm-test/README.md b/charts/loki/src/helm-test/README.md
new file mode 100644
index 0000000..68c9bfd
--- /dev/null
+++ b/charts/loki/src/helm-test/README.md
@@ -0,0 +1,7 @@
+# Loki Helm Test
+
+This folder contains a collection of go tests that test if a Loki canary is running correctly. It's primary use it to test that the helm chart is working correctly by using metrics from the Loki canary. In the helm chart, the template for this test is only available if you are running both the Loki canary and have self monitoring enabled (as the Loki canary's logs need to be in Loki for it to work). However, the tests in this folder can be run against any running Loki canary using `go test`.
+
+## Instructions
+
+Run `go test .` from this directory, or use the Docker image published at `grafana/loki-helm-test`.
diff --git a/charts/loki/src/helm-test/canary_test.go b/charts/loki/src/helm-test/canary_test.go
new file mode 100644
index 0000000..24e9d6d
--- /dev/null
+++ b/charts/loki/src/helm-test/canary_test.go
@@ -0,0 +1,105 @@
+//go:build helm_test
+// +build helm_test
+
+package test
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/prometheus/client_golang/api"
+ v1 "github.com/prometheus/client_golang/api/prometheus/v1"
+ "github.com/prometheus/common/model"
+ "github.com/stretchr/testify/require"
+)
+
+func TestCanary(t *testing.T) {
+ totalEntriesQuery := "sum(loki_canary_entries_total)"
+ totalEntriesMissingQuery := "sum(loki_canary_missing_entries_total)"
+
+ timeout := getEnv("CANARY_TEST_TIMEOUT", "1m")
+ timeoutDuration, err := time.ParseDuration(timeout)
+ require.NoError(t, err, "Failed to parse timeout. Please set CANARY_TEST_TIMEOUT to a valid duration.")
+
+ ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration)
+
+ t.Cleanup(func() {
+ cancel()
+ })
+
+ t.Run("Canary should have entries", func(t *testing.T) {
+ client := newClient(t)
+
+ eventually(t, func() error {
+ result, _, err := client.Query(ctx, totalEntriesQuery, time.Now(), v1.WithTimeout(timeoutDuration))
+ if err != nil {
+ return err
+ }
+ return testResult(t, result, totalEntriesQuery, func(v model.SampleValue) bool {
+ return v > 0
+ }, fmt.Sprintf("Expected %s to be greater than 0", totalEntriesQuery))
+ }, timeoutDuration, "Expected Loki Canary to have entries")
+ })
+
+ t.Run("Canary should not have missed any entries", func(t *testing.T) {
+ client := newClient(t)
+
+ eventually(t, func() error {
+ result, _, err := client.Query(ctx, totalEntriesMissingQuery, time.Now(), v1.WithTimeout(timeoutDuration))
+ if err != nil {
+ return err
+ }
+ return testResult(t, result, totalEntriesMissingQuery, func(v model.SampleValue) bool {
+ return v == 0
+ }, fmt.Sprintf("Expected %s to equal 0", totalEntriesMissingQuery))
+ }, timeoutDuration, "Expected Loki Canary to not have any missing entries")
+ })
+}
+
+func getEnv(key, fallback string) string {
+ if value, ok := os.LookupEnv(key); ok {
+ return value
+ }
+ return fallback
+}
+
+func testResult(t *testing.T, result model.Value, query string, test func(model.SampleValue) bool, msg string) error {
+ if v, ok := result.(model.Vector); ok {
+ for _, s := range v {
+ t.Logf("%s => %v\n", query, s.Value)
+ if !test(s.Value) {
+ return errors.New(msg)
+ }
+ }
+
+ return nil
+ }
+
+ return fmt.Errorf("unexpected Prometheus result type: %v ", result.Type())
+}
+
+func newClient(t *testing.T) v1.API {
+ address := os.Getenv("CANARY_PROMETHEUS_ADDRESS")
+ require.NotEmpty(t, address, "CANARY_PROMETHEUS_ADDRESS must be set to a valid prometheus address")
+
+ client, err := api.NewClient(api.Config{
+ Address: address,
+ })
+ require.NoError(t, err, "Failed to create Loki Canary client")
+
+ return v1.NewAPI(client)
+}
+
+func eventually(t *testing.T, test func() error, timeoutDuration time.Duration, msg string) {
+ require.Eventually(t, func() bool {
+ queryError := test()
+ if queryError != nil {
+ t.Logf("Query failed\n%+v\n", queryError)
+ }
+ return queryError == nil
+ }, timeoutDuration, 1*time.Second, msg)
+}
diff --git a/charts/loki/src/helm-test/default.nix b/charts/loki/src/helm-test/default.nix
new file mode 100644
index 0000000..5ebfa3e
--- /dev/null
+++ b/charts/loki/src/helm-test/default.nix
@@ -0,0 +1,27 @@
+{ pkgs, lib, buildGoModule, dockerTools, rev }:
+rec {
+ loki-helm-test = buildGoModule rec {
+ pname = "loki-helm-test";
+ version = "0.1.0";
+
+ src = ./../../../../..;
+ vendorSha256 = null;
+
+ buildPhase = ''
+ runHook preBuild
+ go test --tags=helm_test -c -o $out/bin/helm-test ./production/helm/loki/src/helm-test
+ runHook postBuild
+ '';
+
+ doCheck = false;
+ };
+
+ # by default, uses the nix hash as the tag, which can be retrieved with:
+ # basename "$(readlink result)" | cut -d - -f 1
+ loki-helm-test-docker = dockerTools.buildImage {
+ name = "grafana/loki-helm-test";
+ config = {
+ Entrypoint = [ "${loki-helm-test}/bin/helm-test" ];
+ };
+ };
+}
diff --git a/charts/loki/src/rules.yaml.tpl b/charts/loki/src/rules.yaml.tpl
new file mode 100644
index 0000000..72bf907
--- /dev/null
+++ b/charts/loki/src/rules.yaml.tpl
@@ -0,0 +1,86 @@
+---
+groups:
+ - name: "loki_rules"
+ rules:
+ - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, job))
+ record: job:loki_request_duration_seconds:99quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, job))
+ record: job:loki_request_duration_seconds:50quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job) / sum(rate(loki_request_duration_seconds_count[1m]))
+ by (job)
+ record: job:loki_request_duration_seconds:avg
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job)
+ record: job:loki_request_duration_seconds_bucket:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job)
+ record: job:loki_request_duration_seconds_sum:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job)
+ record: job:loki_request_duration_seconds_count:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, job, route))
+ record: job_route:loki_request_duration_seconds:99quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, job, route))
+ record: job_route:loki_request_duration_seconds:50quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route) / sum(rate(loki_request_duration_seconds_count[1m]))
+ by (job, route)
+ record: job_route:loki_request_duration_seconds:avg
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route)
+ record: job_route:loki_request_duration_seconds_bucket:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route)
+ record: job_route:loki_request_duration_seconds_sum:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job, route)
+ record: job_route:loki_request_duration_seconds_count:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, namespace, job, route))
+ record: namespace_job_route:loki_request_duration_seconds:99quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m]))
+ by (le, namespace, job, route))
+ record: namespace_job_route:loki_request_duration_seconds:50quantile
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route)
+ / sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route)
+ record: namespace_job_route:loki_request_duration_seconds:avg
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, namespace, job,
+ route)
+ record: namespace_job_route:loki_request_duration_seconds_bucket:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route)
+ record: namespace_job_route:loki_request_duration_seconds_sum:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
+ - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route)
+ record: namespace_job_route:loki_request_duration_seconds_count:sum_rate
+ labels:
+ cluster: "{{ include "loki.fullname" $ }}"
diff --git a/charts/loki/templates/NOTES.txt b/charts/loki/templates/NOTES.txt
new file mode 100644
index 0000000..ad192e7
--- /dev/null
+++ b/charts/loki/templates/NOTES.txt
@@ -0,0 +1,25 @@
+***********************************************************************
+ Welcome to Grafana Loki
+ Chart version: {{ .Chart.Version }}
+ Loki version: {{ .Chart.AppVersion }}
+***********************************************************************
+
+Installed components:
+{{- if .Values.monitoring.selfMonitoring.enabled }}
+* grafana-agent-operator
+{{- end }}
+{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }}
+* loki
+{{- else -}}
+{{- if .Values.gateway.enabled }}
+* gateway
+{{- end }}
+{{- if .Values.minio.enabled }}
+* minio
+{{- end }}
+* read
+* write
+{{- if not .Values.read.legacyReadTarget }}
+* backend
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/_helpers.tpl b/charts/loki/templates/_helpers.tpl
new file mode 100644
index 0000000..2f837ad
--- /dev/null
+++ b/charts/loki/templates/_helpers.tpl
@@ -0,0 +1,703 @@
+{{/*
+Enforce valid label value.
+See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set
+*/}}
+{{- define "loki.validLabelValue" -}}
+{{- (regexReplaceAllLiteral "[^a-zA-Z0-9._-]" . "-") | trunc 63 | trimSuffix "-" | trimSuffix "_" | trimSuffix "." }}
+{{- end }}
+
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "loki.name" -}}
+{{- $default := ternary "enterprise-logs" "loki" .Values.enterprise.enabled }}
+{{- coalesce .Values.nameOverride $default | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+singleBinary fullname
+*/}}
+{{- define "loki.singleBinaryFullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Resource name template
+Params:
+ ctx = . context
+ component = component name (optional)
+ rolloutZoneName = rollout zone name (optional)
+*/}}
+{{- define "loki.resourceName" -}}
+{{- $resourceName := include "loki.fullname" .ctx -}}
+{{- if .component -}}{{- $resourceName = printf "%s-%s" $resourceName .component -}}{{- end -}}
+{{- if and (not .component) .rolloutZoneName -}}{{- printf "Component name cannot be empty if rolloutZoneName (%s) is set" .rolloutZoneName | fail -}}{{- end -}}
+{{- if .rolloutZoneName -}}{{- $resourceName = printf "%s-%s" $resourceName .rolloutZoneName -}}{{- end -}}
+{{- if gt (len $resourceName) 253 -}}{{- printf "Resource name (%s) exceeds kubernetes limit of 253 character. To fix: shorten release name if this will be a fresh install or shorten zone names (e.g. \"a\" instead of \"zone-a\") if using zone-awareness." $resourceName | fail -}}{{- end -}}
+{{- $resourceName -}}
+{{- end -}}
+
+{{/*
+Return if deployment mode is simple scalable
+*/}}
+{{- define "loki.deployment.isScalable" -}}
+ {{- and (eq (include "loki.isUsingObjectStorage" . ) "true") (eq (int .Values.singleBinary.replicas) 0) }}
+{{- end -}}
+
+{{/*
+Return if deployment mode is single binary
+*/}}
+{{- define "loki.deployment.isSingleBinary" -}}
+ {{- $nonZeroReplicas := gt (int .Values.singleBinary.replicas) 0 }}
+ {{- or (eq (include "loki.isUsingObjectStorage" . ) "false") ($nonZeroReplicas) }}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "loki.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := include "loki.name" . }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/* Create a default storage config that uses filesystem storage
+This is required for CI, but Loki will not be queryable with this default
+applied, thus it is encouraged that users override this.
+*/}}
+{{- define "loki.storageConfig" -}}
+{{- if .Values.loki.storageConfig -}}
+{{- .Values.loki.storageConfig | toYaml | nindent 4 -}}
+{{- else }}
+{{- .Values.loki.defaultStorageConfig | toYaml | nindent 4 }}
+{{- end}}
+{{- end}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "loki.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "loki.labels" -}}
+helm.sh/chart: {{ include "loki.chart" . }}
+{{ include "loki.selectorLabels" . }}
+{{- if or (.Chart.AppVersion) (.Values.loki.image.tag) }}
+app.kubernetes.io/version: {{ include "loki.validLabelValue" (.Values.loki.image.tag | default .Chart.AppVersion) | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "loki.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "loki.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "loki.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+ {{ default (include "loki.name" .) .Values.serviceAccount.name }}
+{{- else -}}
+ {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Base template for building docker image reference
+*/}}
+{{- define "loki.baseImage" }}
+{{- $registry := .global.registry | default .service.registry | default "" -}}
+{{- $repository := .service.repository | default "" -}}
+{{- $tag := .service.tag | default .defaultVersion | toString -}}
+{{- if and $registry $repository -}}
+ {{- printf "%s/%s:%s" $registry $repository $tag -}}
+{{- else -}}
+ {{- printf "%s%s:%s" $registry $repository $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Docker image name for Loki
+*/}}
+{{- define "loki.lokiImage" -}}
+{{- $dict := dict "service" .Values.loki.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+{{/*
+Docker image name for enterprise logs
+*/}}
+{{- define "loki.enterpriseImage" -}}
+{{- $dict := dict "service" .Values.enterprise.image "global" .Values.global.image "defaultVersion" .Values.enterprise.version -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+{{/*
+Docker image name
+*/}}
+{{- define "loki.image" -}}
+{{- if .Values.enterprise.enabled -}}{{- include "loki.enterpriseImage" . -}}{{- else -}}{{- include "loki.lokiImage" . -}}{{- end -}}
+{{- end -}}
+
+{{/*
+Docker image name for kubectl container
+*/}}
+{{- define "loki.kubectlImage" -}}
+{{- $dict := dict "service" .Values.kubectlImage "global" .Values.global.image "defaultVersion" "latest" -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+{{/*
+Generated storage config for loki common config
+*/}}
+{{- define "loki.commonStorageConfig" -}}
+{{- if .Values.minio.enabled -}}
+s3:
+ endpoint: {{ include "loki.minio" $ }}
+ bucketnames: {{ $.Values.loki.storage.bucketNames.chunks }}
+ secret_access_key: {{ $.Values.minio.rootPassword }}
+ access_key_id: {{ $.Values.minio.rootUser }}
+ s3forcepathstyle: true
+ insecure: true
+{{- else if eq .Values.loki.storage.type "s3" -}}
+{{- with .Values.loki.storage.s3 }}
+s3:
+ {{- with .s3 }}
+ s3: {{ . }}
+ {{- end }}
+ {{- with .endpoint }}
+ endpoint: {{ . }}
+ {{- end }}
+ {{- with .region }}
+ region: {{ . }}
+ {{- end}}
+ bucketnames: {{ $.Values.loki.storage.bucketNames.chunks }}
+ {{- with .secretAccessKey }}
+ secret_access_key: {{ . }}
+ {{- end }}
+ {{- with .accessKeyId }}
+ access_key_id: {{ . }}
+ {{- end }}
+ s3forcepathstyle: {{ .s3ForcePathStyle }}
+ insecure: {{ .insecure }}
+ {{- with .http_config}}
+ http_config:
+ {{- with .idle_conn_timeout }}
+ idle_conn_timeout: {{ . }}
+ {{- end}}
+ {{- with .response_header_timeout }}
+ response_header_timeout: {{ . }}
+ {{- end}}
+ {{- with .insecure_skip_verify }}
+ insecure_skip_verify: {{ . }}
+ {{- end}}
+ {{- with .ca_file}}
+ ca_file: {{ . }}
+ {{- end}}
+ {{- end }}
+{{- end -}}
+{{- else if eq .Values.loki.storage.type "gcs" -}}
+{{- with .Values.loki.storage.gcs }}
+gcs:
+ bucket_name: {{ $.Values.loki.storage.bucketNames.chunks }}
+ chunk_buffer_size: {{ .chunkBufferSize }}
+ request_timeout: {{ .requestTimeout }}
+ enable_http2: {{ .enableHttp2 }}
+{{- end -}}
+{{- else if eq .Values.loki.storage.type "azure" -}}
+{{- with .Values.loki.storage.azure }}
+azure:
+ account_name: {{ .accountName }}
+ {{- with .accountKey }}
+ account_key: {{ . }}
+ {{- end }}
+ container_name: {{ $.Values.loki.storage.bucketNames.chunks }}
+ use_managed_identity: {{ .useManagedIdentity }}
+ {{- with .userAssignedId }}
+ user_assigned_id: {{ . }}
+ {{- end }}
+ {{- with .requestTimeout }}
+ request_timeout: {{ . }}
+ {{- end }}
+{{- end -}}
+{{- else -}}
+{{- with .Values.loki.storage.filesystem }}
+filesystem:
+ chunks_directory: {{ .chunks_directory }}
+ rules_directory: {{ .rules_directory }}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Storage config for ruler
+*/}}
+{{- define "loki.rulerStorageConfig" -}}
+{{- if .Values.minio.enabled -}}
+type: "s3"
+s3:
+ bucketnames: {{ $.Values.loki.storage.bucketNames.ruler }}
+{{- else if eq .Values.loki.storage.type "s3" -}}
+{{- with .Values.loki.storage.s3 }}
+type: "s3"
+s3:
+ {{- with .s3 }}
+ s3: {{ . }}
+ {{- end }}
+ {{- with .endpoint }}
+ endpoint: {{ . }}
+ {{- end }}
+ {{- with .region }}
+ region: {{ . }}
+ {{- end}}
+ bucketnames: {{ $.Values.loki.storage.bucketNames.ruler }}
+ {{- with .secretAccessKey }}
+ secret_access_key: {{ . }}
+ {{- end }}
+ {{- with .accessKeyId }}
+ access_key_id: {{ . }}
+ {{- end }}
+ s3forcepathstyle: {{ .s3ForcePathStyle }}
+ insecure: {{ .insecure }}
+{{- end -}}
+{{- else if eq .Values.loki.storage.type "gcs" -}}
+{{- with .Values.loki.storage.gcs }}
+type: "gcs"
+gcs:
+ bucket_name: {{ $.Values.loki.storage.bucketNames.ruler }}
+ chunk_buffer_size: {{ .chunkBufferSize }}
+ request_timeout: {{ .requestTimeout }}
+ enable_http2: {{ .enableHttp2 }}
+{{- end -}}
+{{- else if eq .Values.loki.storage.type "azure" -}}
+{{- with .Values.loki.storage.azure }}
+type: "azure"
+azure:
+ account_name: {{ .accountName }}
+ {{- with .accountKey }}
+ account_key: {{ . }}
+ {{- end }}
+ container_name: {{ $.Values.loki.storage.bucketNames.ruler }}
+ use_managed_identity: {{ .useManagedIdentity }}
+ {{- with .userAssignedId }}
+ user_assigned_id: {{ . }}
+ {{- end }}
+ {{- with .requestTimeout }}
+ request_timeout: {{ . }}
+ {{- end }}
+{{- end -}}
+{{- else }}
+type: "local"
+{{- end -}}
+{{- end -}}
+
+{{/* Loki ruler config */}}
+{{- define "loki.rulerConfig" }}
+ruler:
+ storage:
+ {{- include "loki.rulerStorageConfig" . | nindent 4}}
+{{- if (not (empty .Values.loki.rulerConfig)) }}
+{{- toYaml .Values.loki.rulerConfig | nindent 2}}
+{{- end }}
+{{- end }}
+
+{{/*
+Memcached Docker image
+*/}}
+{{- define "loki.memcachedImage" -}}
+{{- $dict := dict "service" .Values.memcached.image "global" .Values.global.image -}}
+{{- include "loki.image" $dict -}}
+{{- end }}
+
+{{/*
+Memcached Exporter Docker image
+*/}}
+{{- define "loki.memcachedExporterImage" -}}
+{{- $dict := dict "service" .Values.memcachedExporter.image "global" .Values.global.image -}}
+{{- include "loki.image" $dict -}}
+{{- end }}
+
+{{/*
+Return the appropriate apiVersion for ingress.
+*/}}
+{{- define "loki.ingress.apiVersion" -}}
+ {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) -}}
+ {{- print "networking.k8s.io/v1" -}}
+ {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
+ {{- print "networking.k8s.io/v1beta1" -}}
+ {{- else -}}
+ {{- print "extensions/v1beta1" -}}
+ {{- end -}}
+{{- end -}}
+
+{{/*
+Return if ingress is stable.
+*/}}
+{{- define "loki.ingress.isStable" -}}
+ {{- eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1" -}}
+{{- end -}}
+
+{{/*
+Return if ingress supports ingressClassName.
+*/}}
+{{- define "loki.ingress.supportsIngressClassName" -}}
+ {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}}
+{{- end -}}
+
+{{/*
+Return if ingress supports pathType.
+*/}}
+{{- define "loki.ingress.supportsPathType" -}}
+ {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}}
+{{- end -}}
+
+{{/*
+Generate list of ingress service paths based on deployment type
+*/}}
+{{- define "loki.ingress.servicePaths" -}}
+{{- if (eq (include "loki.deployment.isScalable" .) "true") -}}
+{{- include "loki.ingress.scalableServicePaths" . }}
+{{- else -}}
+{{- include "loki.ingress.singleBinaryServicePaths" . }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Ingress service paths for scalable deployment
+*/}}
+{{- define "loki.ingress.scalableServicePaths" -}}
+{{- include "loki.ingress.servicePath" (dict "ctx" . "svcName" "read" "paths" .Values.ingress.paths.read )}}
+{{- include "loki.ingress.servicePath" (dict "ctx" . "svcName" "write" "paths" .Values.ingress.paths.write )}}
+{{- end -}}
+
+{{/*
+Ingress service paths for single binary deployment
+*/}}
+{{- define "loki.ingress.singleBinaryServicePaths" -}}
+{{- include "loki.ingress.servicePath" (dict "ctx" . "svcName" "singleBinary" "paths" .Values.ingress.paths.singleBinary )}}
+{{- end -}}
+
+{{/*
+Ingress service path helper function
+Params:
+ ctx = . context
+ svcName = service name without the "loki.fullname" part (ie. read, write)
+ paths = list of url paths to allow ingress for
+*/}}
+{{- define "loki.ingress.servicePath" -}}
+{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .ctx) "true" -}}
+{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .ctx) "true" -}}
+{{- range .paths }}
+- path: {{ . }}
+ {{- if $ingressSupportsPathType }}
+ pathType: Prefix
+ {{- end }}
+ backend:
+ {{- if $ingressApiIsStable }}
+ {{- $serviceName := include "loki.ingress.serviceName" (dict "ctx" $.ctx "svcName" $.svcName) }}
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: 3100
+ {{- else }}
+ serviceName: {{ $serviceName }}
+ servicePort: 3100
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Ingress service name helper function
+Params:
+ ctx = . context
+ svcName = service name without the "loki.fullname" part (ie. read, write)
+*/}}
+{{- define "loki.ingress.serviceName" -}}
+{{- if (eq .svcName "singleBinary") }}
+{{- printf "%s" (include "loki.fullname" .ctx) }}
+{{- else }}
+{{- printf "%s-%s" (include "loki.fullname" .ctx) .svcName }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create the service endpoint including port for MinIO.
+*/}}
+{{- define "loki.minio" -}}
+{{- if .Values.minio.enabled -}}
+{{- printf "%s-%s.%s.svc:%s" .Release.Name "minio" .Release.Namespace (.Values.minio.service.port | toString) -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the appropriate apiVersion for PodDisruptionBudget. */}}
+{{- define "loki.podDisruptionBudget.apiVersion" -}}
+ {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.21-0" .Capabilities.KubeVersion.Version) -}}
+ {{- print "policy/v1" -}}
+ {{- else -}}
+ {{- print "policy/v1beta1" -}}
+ {{- end -}}
+{{- end -}}
+
+{{/* Determine if deployment is using object storage */}}
+{{- define "loki.isUsingObjectStorage" -}}
+{{- or (eq .Values.loki.storage.type "gcs") (eq .Values.loki.storage.type "s3") (eq .Values.loki.storage.type "azure") -}}
+{{- end -}}
+
+{{/* Configure the correct name for the memberlist service */}}
+{{- define "loki.memberlist" -}}
+{{ include "loki.name" . }}-memberlist
+{{- end -}}
+
+{{/* Determine the public host for the Loki cluster */}}
+{{- define "loki.host" -}}
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- $url := printf "%s.%s.svc.%s." (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain }}
+{{- if and $isSingleBinary (not .Values.gateway.enabled) }}
+ {{- $url = printf "%s.%s.svc.%s.:3100" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain }}
+{{- end }}
+{{- printf "%s" $url -}}
+{{- end -}}
+
+{{/* Determine the public endpoint for the Loki cluster */}}
+{{- define "loki.address" -}}
+{{- printf "http://%s" (include "loki.host" . ) -}}
+{{- end -}}
+
+{{/* Name of the cluster */}}
+{{- define "loki.clusterName" -}}
+{{- $name := .Values.enterprise.cluster_name | default .Release.Name }}
+{{- printf "%s" $name -}}
+{{- end -}}
+
+{{/* Name of kubernetes secret to persist GEL admin token to */}}
+{{- define "enterprise-logs.adminTokenSecret" }}
+{{- .Values.enterprise.adminToken.secret | default (printf "%s-admin-token" (include "loki.name" . )) -}}
+{{- end -}}
+
+{{/* Prefix for provisioned secrets created for each provisioned tenant */}}
+{{- define "enterprise-logs.provisionedSecretPrefix" }}
+{{- .Values.enterprise.provisioner.provisionedSecretPrefix | default (printf "%s-provisioned" (include "loki.name" . )) -}}
+{{- end -}}
+
+{{/* Name of kubernetes secret to persist canary credentials in */}}
+{{- define "enterprise-logs.selfMonitoringTenantSecret" }}
+{{- .Values.enterprise.canarySecret | default (printf "%s-%s" (include "enterprise-logs.provisionedSecretPrefix" . ) .Values.monitoring.selfMonitoring.tenant.name) -}}
+{{- end -}}
+
+{{/* Snippet for the nginx file used by gateway */}}
+{{- define "loki.nginxFile" }}
+worker_processes 5; ## Default: 1
+error_log /dev/stderr;
+pid /tmp/nginx.pid;
+worker_rlimit_nofile 8192;
+
+events {
+ worker_connections 4096; ## Default: 1024
+}
+
+http {
+ client_body_temp_path /tmp/client_temp;
+ proxy_temp_path /tmp/proxy_temp_path;
+ fastcgi_temp_path /tmp/fastcgi_temp;
+ uwsgi_temp_path /tmp/uwsgi_temp;
+ scgi_temp_path /tmp/scgi_temp;
+
+ client_max_body_size 4M;
+
+ proxy_read_timeout 600; ## 6 minutes
+ proxy_send_timeout 600;
+ proxy_connect_timeout 600;
+
+ proxy_http_version 1.1;
+
+ default_type application/octet-stream;
+ log_format {{ .Values.gateway.nginxConfig.logFormat }}
+
+ {{- if .Values.gateway.verboseLogging }}
+ access_log /dev/stderr main;
+ {{- else }}
+
+ map $status $loggable {
+ ~^[23] 0;
+ default 1;
+ }
+ access_log /dev/stderr main if=$loggable;
+ {{- end }}
+
+ sendfile on;
+ tcp_nopush on;
+ resolver {{ .Values.global.dnsService }}.{{ .Values.global.dnsNamespace }}.svc.{{ .Values.global.clusterDomain }}.;
+
+ {{- with .Values.gateway.nginxConfig.httpSnippet }}
+ {{ . | nindent 2 }}
+ {{- end }}
+
+ server {
+ listen 8080;
+
+ {{- if .Values.gateway.basicAuth.enabled }}
+ auth_basic "Loki";
+ auth_basic_user_file /etc/nginx/secrets/.htpasswd;
+ {{- end }}
+
+ location = / {
+ return 200 'OK';
+ auth_basic off;
+ }
+
+ {{- $backendHost := include "loki.backendFullname" .}}
+ {{- $readHost := include "loki.readFullname" .}}
+ {{- $writeHost := include "loki.writeFullname" .}}
+
+ {{- if .Values.read.legacyReadTarget }}
+ {{- $backendHost = include "loki.readFullname" . }}
+ {{- end }}
+
+ {{- if gt (int .Values.singleBinary.replicas) 0 }}
+ {{- $backendHost = include "loki.singleBinaryFullname" . }}
+ {{- $readHost = include "loki.singleBinaryFullname" .}}
+ {{- $writeHost = include "loki.singleBinaryFullname" .}}
+ {{- end }}
+
+ {{- $writeUrl := printf "http://%s.%s.svc.%s:3100" $writeHost .Release.Namespace .Values.global.clusterDomain }}
+ {{- $readUrl := printf "http://%s.%s.svc.%s:3100" $readHost .Release.Namespace .Values.global.clusterDomain }}
+ {{- $backendUrl := printf "http://%s.%s.svc.%s:3100" $backendHost .Release.Namespace .Values.global.clusterDomain }}
+
+ {{- if .Values.gateway.nginxConfig.customWriteUrl }}
+ {{- $writeUrl = .Values.gateway.nginxConfig.customWriteUrl }}
+ {{- end }}
+ {{- if .Values.gateway.nginxConfig.customReadUrl }}
+ {{- $readUrl = .Values.gateway.nginxConfig.customReadUrl }}
+ {{- end }}
+ {{- if .Values.gateway.nginxConfig.customBackendUrl }}
+ {{- $backendUrl = .Values.gateway.nginxConfig.customBackendUrl }}
+ {{- end }}
+
+ location = /api/prom/push {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ location = /api/prom/tail {
+ proxy_pass {{ $readUrl }}$request_uri;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ }
+
+ location ~ /api/prom/.* {
+ proxy_pass {{ $readUrl }}$request_uri;
+ }
+
+ location ~ /prometheus/api/v1/alerts.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+ location ~ /prometheus/api/v1/rules.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+ location ~ /ruler/.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+
+ location = /loki/api/v1/push {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ location = /loki/api/v1/tail {
+ proxy_pass {{ $readUrl }}$request_uri;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ }
+
+ location ~ /compactor/.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+
+ location ~ /distributor/.* {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ location ~ /ring {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ location ~ /ingester/.* {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ location ~ /store-gateway/.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+
+ location ~ /query-scheduler/.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+ location ~ /scheduler/.* {
+ proxy_pass {{ $backendUrl }}$request_uri;
+ }
+
+ location ~ /loki/api/.* {
+ proxy_pass {{ $readUrl }}$request_uri;
+ }
+
+ location ~ /admin/api/.* {
+ proxy_pass {{ $writeUrl }}$request_uri;
+ }
+
+ {{- with .Values.gateway.nginxConfig.serverSnippet }}
+ {{ . | nindent 4 }}
+ {{- end }}
+ }
+}
+{{- end }}
+
+{{/* Configure enableServiceLinks in pod */}}
+{{- define "loki.enableServiceLinks" -}}
+{{- if semverCompare ">=1.13-0" .Capabilities.KubeVersion.Version -}}
+{{- if or (.Values.loki.enableServiceLinks) (ne .Values.loki.enableServiceLinks false) -}}
+enableServiceLinks: true
+{{- else -}}
+enableServiceLinks: false
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Determine compactor address based on target configuration */}}
+{{- define "loki.compactorAddress" -}}
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- $compactorAddress := include "loki.backendFullname" . -}}
+{{- if and $isSimpleScalable .Values.read.legacyReadTarget -}}
+{{/* 2 target configuration */}}
+{{- $compactorAddress = include "loki.readFullname" . -}}
+{{- else if (not $isSimpleScalable) -}}
+{{/* single binary */}}
+{{- $compactorAddress = include "loki.singleBinaryFullname" . -}}
+{{- end -}}
+{{- printf "%s" $compactorAddress }}
+{{- end }}
+
diff --git a/charts/loki/templates/backend/_helpers-backend.tpl b/charts/loki/templates/backend/_helpers-backend.tpl
new file mode 100644
index 0000000..08f5f8f
--- /dev/null
+++ b/charts/loki/templates/backend/_helpers-backend.tpl
@@ -0,0 +1,32 @@
+{{/*
+backend fullname
+*/}}
+{{- define "loki.backendFullname" -}}
+{{ include "loki.name" . }}-backend
+{{- end }}
+
+{{/*
+backend common labels
+*/}}
+{{- define "loki.backendLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: backend
+{{- end }}
+
+{{/*
+backend selector labels
+*/}}
+{{- define "loki.backendSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: backend
+{{- end }}
+
+{{/*
+backend priority class name
+*/}}
+{{- define "loki.backendPriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.backend.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/backend/poddisruptionbudget-backend.yaml b/charts/loki/templates/backend/poddisruptionbudget-backend.yaml
new file mode 100644
index 0000000..92c0d57
--- /dev/null
+++ b/charts/loki/templates/backend/poddisruptionbudget-backend.yaml
@@ -0,0 +1,14 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (gt (int .Values.backend.replicas) 1) (not .Values.read.legacyReadTarget ) }}
+apiVersion: {{ include "loki.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ include "loki.backendFullname" . }}
+ labels:
+ {{- include "loki.backendLabels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki.backendSelectorLabels" . | nindent 6 }}
+ maxUnavailable: 1
+{{- end }}
diff --git a/charts/loki/templates/backend/service-backend-headless.yaml b/charts/loki/templates/backend/service-backend-headless.yaml
new file mode 100644
index 0000000..0445107
--- /dev/null
+++ b/charts/loki/templates/backend/service-backend-headless.yaml
@@ -0,0 +1,25 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.backendFullname" . }}-headless
+ labels:
+ {{- include "loki.backendSelectorLabels" . | nindent 4 }}
+ prometheus.io/service-monitor: "false"
+spec:
+ type: ClusterIP
+ clusterIP: None
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.backendSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/backend/service-backend.yaml b/charts/loki/templates/backend/service-backend.yaml
new file mode 100644
index 0000000..b42f715
--- /dev/null
+++ b/charts/loki/templates/backend/service-backend.yaml
@@ -0,0 +1,26 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.backendFullname" . }}
+ labels:
+ {{- include "loki.backendLabels" . | nindent 4 }}
+ {{- with .Values.backend.serviceLabels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.backendSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/backend/statefulset-backend.yaml b/charts/loki/templates/backend/statefulset-backend.yaml
new file mode 100644
index 0000000..7090b75
--- /dev/null
+++ b/charts/loki/templates/backend/statefulset-backend.yaml
@@ -0,0 +1,175 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "loki.backendFullname" . }}
+ labels:
+ {{- include "loki.backendLabels" . | nindent 4 }}
+ app.kubernetes.io/part-of: memberlist
+spec:
+ replicas: {{ .Values.backend.replicas }}
+ podManagementPolicy: Parallel
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ serviceName: {{ include "loki.backendFullname" . }}-headless
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.backend.persistence.enableStatefulSetAutoDeletePVC) }}
+ {{/*
+ Data on the backend nodes is easy to replace, so we want to always delete PVCs to make
+ operation easier, and will rely on re-fetching data when needed.
+ */}}
+ persistentVolumeClaimRetentionPolicy:
+ whenDeleted: Delete
+ whenScaled: Delete
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.backendSelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.backend.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "loki.backendSelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.backend.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.backend.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 8 }}
+ {{- end }}
+ app.kubernetes.io/part-of: memberlist
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.backendPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.backend.terminationGracePeriodSeconds }}
+ {{- if .Values.backend.initContainers }}
+ initContainers:
+ {{- with .Values.backend.initContainers }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- end }}
+ containers:
+ - name: loki
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.backend.targetModule }}
+ - -legacy-read-mode=false
+ {{- with .Values.backend.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ - name: http-memberlist
+ containerPort: 7946
+ protocol: TCP
+ {{- with .Values.backend.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.backend.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ - name: tmp
+ mountPath: /tmp
+ - name: data
+ mountPath: /var/loki
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ mountPath: /etc/loki/license
+ {{- end}}
+ {{- with .Values.backend.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.backend.resources | nindent 12 }}
+ {{- with .Values.backend.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.backend.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.backend.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ {{- end }}
+ {{- with .Values.backend.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumeClaimTemplates:
+ - metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ {{- with .Values.backend.persistence.storageClass }}
+ storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.backend.persistence.size | quote }}
+ {{- with .Values.backend.persistence.selector }}
+ selector:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/configmap.yaml b/charts/loki/templates/configmap.yaml
new file mode 100644
index 0000000..8cfb80b
--- /dev/null
+++ b/charts/loki/templates/configmap.yaml
@@ -0,0 +1,11 @@
+{{- if not .Values.loki.existingSecretForConfig -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "loki.name" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+data:
+ config.yaml: |
+ {{- tpl (mergeOverwrite (tpl .Values.loki.config . | fromYaml) .Values.loki.structuredConfig | toYaml) . | nindent 4 }}
+{{- end -}}
diff --git a/charts/loki/templates/extra-manifests.yaml b/charts/loki/templates/extra-manifests.yaml
new file mode 100644
index 0000000..a9bb3b6
--- /dev/null
+++ b/charts/loki/templates/extra-manifests.yaml
@@ -0,0 +1,4 @@
+{{ range .Values.extraObjects }}
+---
+{{ tpl (toYaml .) $ }}
+{{ end }}
diff --git a/charts/loki/templates/gateway/_helpers-gateway.tpl b/charts/loki/templates/gateway/_helpers-gateway.tpl
new file mode 100644
index 0000000..272814b
--- /dev/null
+++ b/charts/loki/templates/gateway/_helpers-gateway.tpl
@@ -0,0 +1,47 @@
+{{/*
+gateway fullname
+*/}}
+{{- define "loki.gatewayFullname" -}}
+{{ include "loki.name" . }}-gateway
+{{- end }}
+
+{{/*
+gateway common labels
+*/}}
+{{- define "loki.gatewayLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: gateway
+{{- end }}
+
+{{/*
+gateway selector labels
+*/}}
+{{- define "loki.gatewaySelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: gateway
+{{- end }}
+
+{{/*
+gateway auth secret name
+*/}}
+{{- define "loki.gatewayAuthSecret" -}}
+{{ .Values.gateway.basicAuth.existingSecret | default (include "loki.gatewayFullname" . ) }}
+{{- end }}
+
+{{/*
+gateway Docker image
+*/}}
+{{- define "loki.gatewayImage" -}}
+{{- $dict := dict "service" .Values.gateway.image "global" .Values.global.image -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end }}
+
+{{/*
+gateway priority class name
+*/}}
+{{- define "loki.gatewayPriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.gateway.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/configmap-gateway.yaml b/charts/loki/templates/gateway/configmap-gateway.yaml
new file mode 100644
index 0000000..dcb379b
--- /dev/null
+++ b/charts/loki/templates/gateway/configmap-gateway.yaml
@@ -0,0 +1,11 @@
+{{- if and .Values.gateway.enabled }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+data:
+ nginx.conf: |
+ {{- tpl .Values.gateway.nginxConfig.file . | indent 2 }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/deployment-gateway.yaml b/charts/loki/templates/gateway/deployment-gateway.yaml
new file mode 100644
index 0000000..ff8e645
--- /dev/null
+++ b/charts/loki/templates/gateway/deployment-gateway.yaml
@@ -0,0 +1,117 @@
+{{- if .Values.gateway.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+spec:
+{{- if not .Values.gateway.autoscaling.enabled }}
+ replicas: {{ .Values.gateway.replicas }}
+{{- end }}
+{{- with .Values.gateway.deploymentStrategy }}
+ strategy:
+{{ toYaml . | trim | indent 4 }}
+{{- end }}
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ selector:
+ matchLabels:
+ {{- include "loki.gatewaySelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/gateway/configmap-gateway.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.gateway.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.gateway.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.gatewaySelectorLabels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ {{ include "loki.enableServiceLinks" . }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end -}}
+ {{- include "loki.gatewayPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.gateway.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.gateway.terminationGracePeriodSeconds }}
+ containers:
+ - name: nginx
+ image: {{ include "loki.gatewayImage" . }}
+ imagePullPolicy: {{ .Values.gateway.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 8080
+ protocol: TCP
+ {{- with .Values.gateway.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.gateway.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ readinessProbe:
+ {{- toYaml .Values.gateway.readinessProbe | nindent 12 }}
+ securityContext:
+ {{- toYaml .Values.gateway.containerSecurityContext | nindent 12 }}
+ {{- with .Values.gateway.lifecycle }}
+ lifecycle:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/nginx
+ {{- if .Values.gateway.basicAuth.enabled }}
+ - name: auth
+ mountPath: /etc/nginx/secrets
+ {{- end }}
+ - name: tmp
+ mountPath: /tmp
+ - name: docker-entrypoint-d-override
+ mountPath: /docker-entrypoint.d
+ {{- if .Values.gateway.extraVolumeMounts }}
+ {{- toYaml .Values.gateway.extraVolumeMounts | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.gateway.resources | nindent 12 }}
+ {{- with .Values.gateway.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.gateway.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.gateway.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: config
+ configMap:
+ name: {{ include "loki.gatewayFullname" . }}
+ {{- if .Values.gateway.basicAuth.enabled }}
+ - name: auth
+ secret:
+ secretName: {{ include "loki.gatewayAuthSecret" . }}
+ {{- end }}
+ - name: tmp
+ emptyDir: {}
+ - name: docker-entrypoint-d-override
+ emptyDir: {}
+ {{- if .Values.gateway.extraVolumes }}
+ {{- toYaml .Values.gateway.extraVolumes | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/hpa.yaml b/charts/loki/templates/gateway/hpa.yaml
new file mode 100644
index 0000000..e23c221
--- /dev/null
+++ b/charts/loki/templates/gateway/hpa.yaml
@@ -0,0 +1,45 @@
+{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}}
+{{- if .Values.gateway.autoscaling.enabled }}
+{{- if $autoscalingv2 }}
+apiVersion: autoscaling/v2
+{{- else }}
+apiVersion: autoscaling/v2beta1
+{{- end }}
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "loki.gatewayFullname" . }}
+ minReplicas: {{ .Values.gateway.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.gateway.autoscaling.maxReplicas }}
+ metrics:
+ {{- with .Values.gateway.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ {{- if $autoscalingv2 }}
+ target:
+ type: Utilization
+ averageUtilization: {{ . }}
+ {{- else }}
+ targetAverageUtilization: {{ . }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.gateway.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ {{- if $autoscalingv2 }}
+ target:
+ type: Utilization
+ averageUtilization: {{ . }}
+ {{- else }}
+ targetAverageUtilization: {{ . }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/ingress-gateway.yaml b/charts/loki/templates/gateway/ingress-gateway.yaml
new file mode 100644
index 0000000..5c1106c
--- /dev/null
+++ b/charts/loki/templates/gateway/ingress-gateway.yaml
@@ -0,0 +1,55 @@
+{{- if and .Values.gateway.enabled -}}
+{{- if .Values.gateway.ingress.enabled -}}
+{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .) "true" -}}
+{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}}
+{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .) "true" -}}
+apiVersion: {{ include "loki.ingress.apiVersion" . }}
+kind: Ingress
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+ {{- with .Values.gateway.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if and $ingressSupportsIngressClassName .Values.gateway.ingress.ingressClassName }}
+ ingressClassName: {{ .Values.gateway.ingress.ingressClassName }}
+ {{- end -}}
+ {{- if .Values.gateway.ingress.tls }}
+ tls:
+ {{- range .Values.gateway.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ {{- with .secretName }}
+ secretName: {{ . }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.gateway.ingress.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- if $ingressSupportsPathType }}
+ pathType: {{ .pathType }}
+ {{- end }}
+ backend:
+ {{- if $ingressApiIsStable }}
+ service:
+ name: {{ include "loki.gatewayFullname" $ }}
+ port:
+ number: {{ $.Values.gateway.service.port }}
+ {{- else }}
+ serviceName: {{ include "loki.gatewayFullname" $ }}
+ servicePort: {{ $.Values.gateway.service.port }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml b/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml
new file mode 100644
index 0000000..734906d
--- /dev/null
+++ b/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml
@@ -0,0 +1,15 @@
+{{- if and .Values.gateway.enabled }}
+{{- if gt (int .Values.gateway.replicas) 1 }}
+apiVersion: {{ include "loki.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki.gatewaySelectorLabels" . | nindent 6 }}
+ maxUnavailable: 1
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/secret-gateway.yaml b/charts/loki/templates/gateway/secret-gateway.yaml
new file mode 100644
index 0000000..f7cc8a6
--- /dev/null
+++ b/charts/loki/templates/gateway/secret-gateway.yaml
@@ -0,0 +1,13 @@
+{{- with .Values.gateway }}
+{{- if and .enabled .basicAuth.enabled (not .basicAuth.existingSecret) }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "loki.gatewayFullname" $ }}
+ labels:
+ {{- include "loki.gatewayLabels" $ | nindent 4 }}
+stringData:
+ .htpasswd: |
+ {{- tpl .basicAuth.htpasswd $ | nindent 4 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/gateway/service-gateway.yaml b/charts/loki/templates/gateway/service-gateway.yaml
new file mode 100644
index 0000000..8e7b6c0
--- /dev/null
+++ b/charts/loki/templates/gateway/service-gateway.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.gateway.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.gatewayFullname" . }}
+ labels:
+ {{- include "loki.gatewayLabels" . | nindent 4 }}
+ {{- with .Values.gateway.service.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .Values.gateway.service.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: {{ .Values.gateway.service.type }}
+ {{- with .Values.gateway.service.clusterIP }}
+ clusterIP: {{ . }}
+ {{- end }}
+ {{- if and (eq "LoadBalancer" .Values.gateway.service.type) .Values.gateway.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.gateway.service.loadBalancerIP }}
+ {{- end }}
+ ports:
+ - name: http
+ port: {{ .Values.gateway.service.port }}
+ targetPort: http
+ {{- if and (eq "NodePort" .Values.gateway.service.type) .Values.gateway.service.nodePort }}
+ nodePort: {{ .Values.gateway.service.nodePort }}
+ {{- end }}
+ protocol: TCP
+ selector:
+ {{- include "loki.gatewaySelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/ingress.yaml b/charts/loki/templates/ingress.yaml
new file mode 100644
index 0000000..49e3911
--- /dev/null
+++ b/charts/loki/templates/ingress.yaml
@@ -0,0 +1,36 @@
+{{- if .Values.ingress.enabled }}
+{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}}
+apiVersion: {{ include "loki.ingress.apiVersion" . }}
+kind: Ingress
+metadata:
+ name: {{ include "loki.fullname" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }}
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ {{- with .secretName }}
+ secretName: {{ . }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range $.Values.ingress.hosts }}
+ - host: {{ . | quote }}
+ http:
+ paths:
+ {{- include "loki.ingress.servicePaths" $ | indent 10}}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/loki-canary/_helpers.tpl b/charts/loki/templates/loki-canary/_helpers.tpl
new file mode 100644
index 0000000..28ce60d
--- /dev/null
+++ b/charts/loki/templates/loki-canary/_helpers.tpl
@@ -0,0 +1,40 @@
+{{/*
+canary fullname
+*/}}
+{{- define "loki-canary.fullname" -}}
+{{ include "loki.name" . }}-canary
+{{- end }}
+
+{{/*
+canary common labels
+*/}}
+{{- define "loki-canary.labels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: canary
+{{- end }}
+
+{{/*
+canary selector labels
+*/}}
+{{- define "loki-canary.selectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: canary
+{{- end }}
+
+{{/*
+Docker image name for loki-canary
+*/}}
+{{- define "loki-canary.image" -}}
+{{- $dict := dict "service" .Values.monitoring.lokiCanary.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+{{/*
+canry priority class name
+*/}}
+{{- define "loki-canary.priorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.read.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/loki-canary/daemonset.yaml b/charts/loki/templates/loki-canary/daemonset.yaml
new file mode 100644
index 0000000..7b5d9c0
--- /dev/null
+++ b/charts/loki/templates/loki-canary/daemonset.yaml
@@ -0,0 +1,99 @@
+{{- with .Values.monitoring.lokiCanary -}}
+{{- if .enabled -}}
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: {{ include "loki-canary.fullname" $ }}
+ labels:
+ {{- include "loki-canary.labels" $ | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki-canary.selectorLabels" $ | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ {{- with .annotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "loki-canary.selectorLabels" $ | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "loki-canary.fullname" $ }}
+ {{- with $.Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki-canary.priorityClassName" $ | nindent 6 }}
+ securityContext:
+ {{- toYaml $.Values.loki.podSecurityContext | nindent 8 }}
+ containers:
+ - name: loki-canary
+ image: {{ include "loki-canary.image" $ }}
+ imagePullPolicy: {{ $.Values.loki.image.pullPolicy }}
+ args:
+ - -addr={{- include "loki.host" $ }}
+ - -labelname=pod
+ - -labelvalue=$(POD_NAME)
+ {{- if $.Values.enterprise.enabled }}
+ - -user=$(USER)
+ - -tenant-id=$(USER)
+ - -pass=$(PASS)
+ {{- else if $.Values.loki.auth_enabled }}
+ - -user={{ $.Values.monitoring.selfMonitoring.tenant.name }}
+ - -tenant-id={{ $.Values.monitoring.selfMonitoring.tenant.name }}
+ {{- end }}
+ {{- with .extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml $.Values.loki.containerSecurityContext | nindent 12 }}
+ ports:
+ - name: http-metrics
+ containerPort: 3500
+ protocol: TCP
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ {{ if $.Values.enterprise.enabled }}
+ - name: USER
+ valueFrom:
+ secretKeyRef:
+ name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}
+ key: username
+ - name: PASS
+ valueFrom:
+ secretKeyRef:
+ name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}
+ key: password
+ {{- end -}}
+ {{- with .extraEnv }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ readinessProbe:
+ httpGet:
+ path: /metrics
+ port: http-metrics
+ initialDelaySeconds: 15
+ timeoutSeconds: 1
+ {{- with .resources}}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/loki-canary/service.yaml b/charts/loki/templates/loki-canary/service.yaml
new file mode 100644
index 0000000..6d7ace5
--- /dev/null
+++ b/charts/loki/templates/loki-canary/service.yaml
@@ -0,0 +1,20 @@
+{{- with .Values.monitoring.lokiCanary -}}
+{{- if .enabled -}}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki-canary.fullname" $ }}
+ labels:
+ {{- include "loki-canary.labels" $ | nindent 4 }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3500
+ targetPort: http-metrics
+ protocol: TCP
+ selector:
+ {{- include "loki-canary.selectorLabels" $ | nindent 4 }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/loki/templates/loki-canary/serviceaccount.yaml b/charts/loki/templates/loki-canary/serviceaccount.yaml
new file mode 100644
index 0000000..2794942
--- /dev/null
+++ b/charts/loki/templates/loki-canary/serviceaccount.yaml
@@ -0,0 +1,20 @@
+{{- with .Values.monitoring.lokiCanary -}}
+{{- if .enabled -}}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "loki-canary.fullname" $ }}
+ labels:
+ {{- include "loki-canary.labels" $ | nindent 4 }}
+ annotations:
+ {{- with .annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ $.Values.serviceAccount.automountServiceAccountToken }}
+{{- with $.Values.serviceAccount.imagePullSecrets }}
+imagePullSecrets:
+ {{- toYaml . | nindent 2 }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/monitoring/_helpers-monitoring.tpl b/charts/loki/templates/monitoring/_helpers-monitoring.tpl
new file mode 100644
index 0000000..342fd2b
--- /dev/null
+++ b/charts/loki/templates/monitoring/_helpers-monitoring.tpl
@@ -0,0 +1,37 @@
+{{/*
+Client definition for LogsInstance
+*/}}
+{{- define "loki.logsInstanceClient" -}}
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- $url := printf "http://%s.%s.svc.%s:3100/loki/api/v1/push" (include "loki.writeFullname" .) .Release.Namespace .Values.global.clusterDomain }}
+{{- if $isSingleBinary }}
+ {{- $url = printf "http://%s.%s.svc.%s:3100/loki/api/v1/push" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain }}
+{{- else if .Values.gateway.enabled -}}
+ {{- $url = printf "http://%s.%s.svc.%s/loki/api/v1/push" (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain }}
+{{- end -}}
+- url: {{ $url }}
+ externalLabels:
+ cluster: {{ include "loki.fullname" . }}
+ {{- if .Values.enterprise.enabled }}
+ basicAuth:
+ username:
+ name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }}
+ key: username
+ password:
+ name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }}
+ key: password
+ {{- else if .Values.loki.auth_enabled }}
+ tenantId: {{ .Values.monitoring.selfMonitoring.tenant.name }}
+ {{- end }}
+{{- end -}}
+
+{{/*
+Convert a recording rule group to yaml
+*/}}
+{{- define "loki.ruleGroupToYaml" -}}
+{{- range . }}
+- name: {{ .name }}
+ rules:
+ {{- toYaml .rules | nindent 4 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl b/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl
new file mode 100644
index 0000000..00fd722
--- /dev/null
+++ b/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl
@@ -0,0 +1,6 @@
+{{/*
+dashboards name
+*/}}
+{{- define "loki.dashboardsName" -}}
+{{ include "loki.name" . }}-dashboards
+{{- end }}
diff --git a/charts/loki/templates/monitoring/dashboards/configmap-1.yaml b/charts/loki/templates/monitoring/dashboards/configmap-1.yaml
new file mode 100644
index 0000000..6447a49
--- /dev/null
+++ b/charts/loki/templates/monitoring/dashboards/configmap-1.yaml
@@ -0,0 +1,31 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- with .Values.monitoring.dashboards }}
+{{- if and $isSimpleScalable .enabled }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "loki.dashboardsName" $ }}-1
+ namespace: {{ .namespace | default $.Release.Namespace }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+data:
+ "loki-chunks.json": |
+ {{ $.Files.Get "src/dashboards/loki-chunks.json" | fromJson | toJson }}
+ "loki-deletion.json": |
+ {{ $.Files.Get "src/dashboards/loki-deletion.json" | fromJson | toJson }}
+ "loki-logs.json": |
+ {{ $.Files.Get "src/dashboards/loki-logs.json" | fromJson | toJson }}
+ "loki-mixin-recording-rules.json": |
+ {{ $.Files.Get "src/dashboards/loki-mixin-recording-rules.json" | fromJson | toJson }}
+ "loki-operational.json": |
+ {{ $.Files.Get "src/dashboards/loki-operational.json" | fromJson | toJson }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/loki/templates/monitoring/dashboards/configmap-2.yaml b/charts/loki/templates/monitoring/dashboards/configmap-2.yaml
new file mode 100644
index 0000000..6c66d15
--- /dev/null
+++ b/charts/loki/templates/monitoring/dashboards/configmap-2.yaml
@@ -0,0 +1,31 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- with .Values.monitoring.dashboards }}
+{{- if and $isSimpleScalable .enabled }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "loki.dashboardsName" $ }}-2
+ namespace: {{ .namespace | default $.Release.Namespace }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+data:
+ "loki-reads-resources.json": |
+ {{ $.Files.Get "src/dashboards/loki-reads-resources.json" | fromJson | toJson }}
+ "loki-reads.json": |
+ {{ $.Files.Get "src/dashboards/loki-reads.json" | fromJson | toJson }}
+ "loki-retention.json": |
+ {{ $.Files.Get "src/dashboards/loki-retention.json" | fromJson | toJson }}
+ "loki-writes-resources.json": |
+ {{ $.Files.Get "src/dashboards/loki-writes-resources.json" | fromJson | toJson }}
+ "loki-writes.json": |
+ {{ $.Files.Get "src/dashboards/loki-writes.json" | fromJson | toJson }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/loki/templates/monitoring/grafana-agent.yaml b/charts/loki/templates/monitoring/grafana-agent.yaml
new file mode 100644
index 0000000..0ac0f6c
--- /dev/null
+++ b/charts/loki/templates/monitoring/grafana-agent.yaml
@@ -0,0 +1,90 @@
+{{- if .Values.monitoring.selfMonitoring.enabled }}
+{{- with .Values.monitoring.selfMonitoring.grafanaAgent }}
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: GrafanaAgent
+metadata:
+ name: {{ include "loki.fullname" $ }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ serviceAccountName: {{ include "loki.fullname" $ }}-grafana-agent
+ enableConfigReadAPI: {{ .enableConfigReadAPI }}
+ logs:
+ instanceSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 8 }}
+ {{- with $.Values.monitoring.serviceMonitor}}
+ {{- if .metricsInstance.remoteWrite}}
+ metrics:
+ instanceSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 8 }}
+ {{- end }}
+ {{- end }}
+
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "loki.fullname" $ }}-grafana-agent
+ namespace: {{ .namespace | default $.Release.Namespace }}
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "loki.fullname" $ }}-grafana-agent
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - nodes
+ - nodes/proxy
+ - nodes/metrics
+ - services
+ - endpoints
+ - pods
+ - events
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - networking.k8s.io
+ resources:
+ - ingresses
+ verbs:
+ - get
+ - list
+ - watch
+- nonResourceURLs:
+ - /metrics
+ - /metrics/cadvisor
+ verbs:
+ - get
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "loki.fullname" $ }}-grafana-agent
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "loki.fullname" $ }}-grafana-agent
+subjects:
+- kind: ServiceAccount
+ name: {{ include "loki.fullname" $ }}-grafana-agent
+ namespace: {{ .namespace | default $.Release.Namespace }}
+{{- end}}
+{{- end}}
diff --git a/charts/loki/templates/monitoring/logs-instance.yaml b/charts/loki/templates/monitoring/logs-instance.yaml
new file mode 100644
index 0000000..34ab6e9
--- /dev/null
+++ b/charts/loki/templates/monitoring/logs-instance.yaml
@@ -0,0 +1,29 @@
+{{- if .Values.monitoring.selfMonitoring.enabled }}
+{{- with .Values.monitoring.selfMonitoring.logsInstance }}
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: LogsInstance
+metadata:
+ name: {{ include "loki.fullname" $ }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ clients:
+ {{- include "loki.logsInstanceClient" $ | nindent 4}}
+ {{- with .clients}}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+
+ podLogsNamespaceSelector: {}
+
+ podLogsSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 6 }}
+{{- end -}}
+{{- end -}}
diff --git a/charts/loki/templates/monitoring/loki-alerts.yaml b/charts/loki/templates/monitoring/loki-alerts.yaml
new file mode 100644
index 0000000..c473ed5
--- /dev/null
+++ b/charts/loki/templates/monitoring/loki-alerts.yaml
@@ -0,0 +1,22 @@
+{{- with .Values.monitoring.rules }}
+{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled .alerting }}
+---
+apiVersion: monitoring.coreos.com/v1
+kind: PrometheusRule
+metadata:
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ name: {{ include "loki.fullname" $ }}-loki-alerts
+ namespace: {{ .namespace | default $.Release.Namespace }}
+spec:
+ groups:
+ {{- include "loki.ruleGroupToYaml" ($.Files.Get "src/alerts.yaml" | fromYaml).groups | indent 4 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/monitoring/loki-rules.yaml b/charts/loki/templates/monitoring/loki-rules.yaml
new file mode 100644
index 0000000..f9eb392
--- /dev/null
+++ b/charts/loki/templates/monitoring/loki-rules.yaml
@@ -0,0 +1,23 @@
+{{- with .Values.monitoring.rules }}
+{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled }}
+---
+apiVersion: monitoring.coreos.com/v1
+kind: PrometheusRule
+metadata:
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ name: {{ include "loki.fullname" $ }}-loki-rules
+ namespace: {{ .namespace | default $.Release.Namespace }}
+spec:
+ groups:
+ {{- include "loki.ruleGroupToYaml" (tpl ($.Files.Get "src/rules.yaml.tpl") $ | fromYaml).groups | indent 4 }}
+ {{- include "loki.ruleGroupToYaml" .additionalGroups | indent 4 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/monitoring/metrics-instance.yaml b/charts/loki/templates/monitoring/metrics-instance.yaml
new file mode 100644
index 0000000..82102c0
--- /dev/null
+++ b/charts/loki/templates/monitoring/metrics-instance.yaml
@@ -0,0 +1,30 @@
+{{- if .Values.monitoring.serviceMonitor.enabled }}
+{{- with .Values.monitoring.serviceMonitor.metricsInstance }}
+{{- if and ($.Capabilities.APIVersions.Has "monitoring.grafana.com/v1alpha1/MetricsInstance") .enabled }}
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: MetricsInstance
+metadata:
+ name: {{ include "loki.fullname" $ }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .remoteWrite}}
+ remoteWrite:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+
+ serviceMonitorNamespaceSelector: {}
+
+ serviceMonitorSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 6 }}
+{{- end -}}
+{{- end -}}
+{{- end -}}
diff --git a/charts/loki/templates/monitoring/pod-logs.yaml b/charts/loki/templates/monitoring/pod-logs.yaml
new file mode 100644
index 0000000..e9d66d6
--- /dev/null
+++ b/charts/loki/templates/monitoring/pod-logs.yaml
@@ -0,0 +1,56 @@
+---
+{{- if .Values.monitoring.selfMonitoring.enabled }}
+{{- with .Values.monitoring.selfMonitoring.podLogs }}
+apiVersion: monitoring.grafana.com/v1alpha1
+kind: PodLogs
+metadata:
+ name: {{ include "loki.fullname" $ }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ pipelineStages:
+ - cri: { }
+ relabelings:
+ - sourceLabels:
+ - __meta_kubernetes_pod_node_name
+ targetLabel: __host__
+ - action: labelmap
+ regex: __meta_kubernetes_pod_label_(.+)
+ - action: replace
+ replacement: "$1"
+ separator: "-"
+ sourceLabels:
+ - __meta_kubernetes_pod_label_app_kubernetes_io_name
+ - __meta_kubernetes_pod_label_app_kubernetes_io_component
+ targetLabel: __service__
+ - action: replace
+ replacement: "$1"
+ separator: "/"
+ sourceLabels:
+ - __meta_kubernetes_namespace
+ - __service__
+ targetLabel: job
+ - action: replace
+ sourceLabels:
+ - __meta_kubernetes_pod_container_name
+ targetLabel: container
+ - replacement: "{{ include "loki.fullname" $ }}"
+ targetLabel: cluster
+ {{- with .relabelings }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ namespaceSelector:
+ matchNames:
+ - {{ $.Release.Namespace }}
+ selector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 6 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/monitoring/servicemonitor.yaml b/charts/loki/templates/monitoring/servicemonitor.yaml
new file mode 100644
index 0000000..c5dca1f
--- /dev/null
+++ b/charts/loki/templates/monitoring/servicemonitor.yaml
@@ -0,0 +1,56 @@
+{{- with .Values.monitoring.serviceMonitor }}
+{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") .enabled }}
+---
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ include "loki.fullname" $ }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "loki.labels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .namespaceSelector }}
+ namespaceSelector:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.selectorLabels" $ | nindent 6 }}
+ matchExpressions:
+ - key: prometheus.io/service-monitor
+ operator: NotIn
+ values:
+ - "false"
+ endpoints:
+ - port: http-metrics
+ path: /metrics
+ {{- with .interval }}
+ interval: {{ . }}
+ {{- end }}
+ {{- with .scrapeTimeout }}
+ scrapeTimeout: {{ . }}
+ {{- end }}
+ relabelings:
+ - sourceLabels: [job]
+ replacement: "{{ $.Release.Namespace }}/$1"
+ targetLabel: job
+ - replacement: "{{ include "loki.fullname" $ }}"
+ targetLabel: cluster
+ {{- with .relabelings }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .scheme }}
+ scheme: {{ . }}
+ {{- end }}
+ {{- with .tlsConfig }}
+ tlsConfig:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/networkpolicy.yaml b/charts/loki/templates/networkpolicy.yaml
new file mode 100644
index 0000000..a7de14b
--- /dev/null
+++ b/charts/loki/templates/networkpolicy.yaml
@@ -0,0 +1,198 @@
+{{- if .Values.networkPolicy.enabled }}
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-namespace-only
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Ingress
+ - Egress
+ podSelector: {}
+ egress:
+ - to:
+ - podSelector: {}
+ ingress:
+ - from:
+ - podSelector: {}
+
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-egress-dns
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Egress
+ podSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" . | nindent 6 }}
+ egress:
+ - ports:
+ - port: 53
+ protocol: UDP
+ to:
+ - namespaceSelector: {}
+
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-ingress
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Ingress
+ podSelector:
+ matchExpressions:
+ - key: app.kubernetes.io/component
+ operator: In
+ values:
+ {{- if .Values.gateway.enabled }}
+ - gateway
+ {{- else }}
+ - read
+ - write
+ {{- end }}
+ matchLabels:
+ {{- include "loki.selectorLabels" . | nindent 6 }}
+ ingress:
+ - ports:
+ - port: http
+ protocol: TCP
+ {{- if .Values.networkPolicy.ingress.namespaceSelector }}
+ from:
+ - namespaceSelector:
+ {{- toYaml .Values.networkPolicy.ingress.namespaceSelector | nindent 12 }}
+ {{- if .Values.networkPolicy.ingress.podSelector }}
+ podSelector:
+ {{- toYaml .Values.networkPolicy.ingress.podSelector | nindent 12 }}
+ {{- end }}
+ {{- end }}
+
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-ingress-metrics
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Ingress
+ podSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" . | nindent 6 }}
+ ingress:
+ - ports:
+ - port: http-metrics
+ protocol: TCP
+ {{- if .Values.networkPolicy.metrics.cidrs }}
+ from:
+ {{- range $cidr := .Values.networkPolicy.metrics.cidrs }}
+ - ipBlock:
+ cidr: {{ $cidr }}
+ {{- end }}
+ {{- if .Values.networkPolicy.metrics.namespaceSelector }}
+ - namespaceSelector:
+ {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 12 }}
+ {{- if .Values.networkPolicy.metrics.podSelector }}
+ podSelector:
+ {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 12 }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+
+{{- if .Values.ruler.enabled }}
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-egress-alertmanager
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Egress
+ podSelector:
+ matchLabels:
+ {{- include "loki.rulerSelectorLabels" . | nindent 6 }}
+ egress:
+ - ports:
+ - port: {{ .Values.networkPolicy.alertmanager.port }}
+ protocol: TCP
+ {{- if .Values.networkPolicy.alertmanager.namespaceSelector }}
+ to:
+ - namespaceSelector:
+ {{- toYaml .Values.networkPolicy.alertmanager.namespaceSelector | nindent 12 }}
+ {{- if .Values.networkPolicy.alertmanager.podSelector }}
+ podSelector:
+ {{- toYaml .Values.networkPolicy.alertmanager.podSelector | nindent 12 }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{- if .Values.networkPolicy.externalStorage.ports }}
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-egress-external-storage
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Egress
+ podSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" . | nindent 6 }}
+ egress:
+ - ports:
+ {{- range $port := .Values.networkPolicy.externalStorage.ports }}
+ - port: {{ $port }}
+ protocol: TCP
+ {{- end }}
+ {{- if .Values.networkPolicy.externalStorage.cidrs }}
+ to:
+ {{- range $cidr := .Values.networkPolicy.externalStorage.cidrs }}
+ - ipBlock:
+ cidr: {{ $cidr }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{- end }}
+
+{{- if .Values.networkPolicy.discovery.port }}
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: {{ include "loki.name" . }}-egress-discovery
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ policyTypes:
+ - Egress
+ podSelector:
+ matchLabels:
+ {{- include "loki.selectorLabels" . | nindent 6 }}
+ egress:
+ - ports:
+ - port: {{ .Values.networkPolicy.discovery.port }}
+ protocol: TCP
+ {{- if .Values.networkPolicy.discovery.namespaceSelector }}
+ to:
+ - namespaceSelector:
+ {{- toYaml .Values.networkPolicy.discovery.namespaceSelector | nindent 12 }}
+ {{- if .Values.networkPolicy.discovery.podSelector }}
+ podSelector:
+ {{- toYaml .Values.networkPolicy.discovery.podSelector | nindent 12 }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/podsecuritypolicy.yaml b/charts/loki/templates/podsecuritypolicy.yaml
new file mode 100644
index 0000000..9833d0c
--- /dev/null
+++ b/charts/loki/templates/podsecuritypolicy.yaml
@@ -0,0 +1,36 @@
+{{- if .Values.rbac.pspEnabled }}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+ name: {{ include "loki.name" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ privileged: false
+ allowPrivilegeEscalation: false
+ volumes:
+ - 'configMap'
+ - 'emptyDir'
+ - 'persistentVolumeClaim'
+ - 'secret'
+ hostNetwork: false
+ hostIPC: false
+ hostPID: false
+ runAsUser:
+ rule: 'MustRunAsNonRoot'
+ seLinux:
+ rule: 'RunAsAny'
+ supplementalGroups:
+ rule: 'MustRunAs'
+ ranges:
+ - min: 1
+ max: 65535
+ fsGroup:
+ rule: 'MustRunAs'
+ ranges:
+ - min: 1
+ max: 65535
+ readOnlyRootFilesystem: true
+ requiredDropCapabilities:
+ - ALL
+{{- end }}
diff --git a/charts/loki/templates/provisioner/_helpers.yaml b/charts/loki/templates/provisioner/_helpers.yaml
new file mode 100644
index 0000000..8b04b07
--- /dev/null
+++ b/charts/loki/templates/provisioner/_helpers.yaml
@@ -0,0 +1,32 @@
+{{/*
+provisioner fullname
+*/}}
+{{- define "enterprise-logs.provisionerFullname" -}}
+{{ include "loki.name" . }}-provisioner
+{{- end }}
+
+{{/*
+provisioner common labels
+*/}}
+{{- define "enterprise-logs.provisionerLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: provisioner
+{{- end }}
+
+{{/*
+provisioner selector labels
+*/}}
+{{- define "enterprise-logs.provisionerSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: provisioner
+{{- end }}
+
+{{/*
+provisioner image name
+*/}}
+{{- define "enterprise-logs.provisionerImage" -}}
+{{- $dict := dict "service" .Values.enterprise.provisioner.image "global" .Values.global.image "defaultVersion" "latest" -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+
diff --git a/charts/loki/templates/provisioner/job-provisioner.yaml b/charts/loki/templates/provisioner/job-provisioner.yaml
new file mode 100644
index 0000000..0845009
--- /dev/null
+++ b/charts/loki/templates/provisioner/job-provisioner.yaml
@@ -0,0 +1,127 @@
+{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }}
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+ labels:
+ {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.provisioner.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.provisioner.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+ "helm.sh/hook-weight": "15"
+spec:
+ backoffLimit: 6
+ completions: 1
+ parallelism: 1
+ template:
+ metadata:
+ labels:
+ {{- include "enterprise-logs.provisionerSelectorLabels" . | nindent 8 }}
+ {{- with .Values.enterprise.provisioner.labels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.enterprise.provisioner.annotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.enterprise.provisioner.priorityClassName }}
+ priorityClassName: {{ . }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.enterprise.provisioner.securityContext | nindent 8 }}
+ {{- if .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- range .Values.imagePullSecrets }}
+ - name: {{ . }}
+ {{- end }}
+ {{- end }}
+ initContainers:
+ - name: provisioner
+ image: {{ template "enterprise-logs.provisionerImage" . }}
+ imagePullPolicy: {{ .Values.enterprise.provisioner.image.pullPolicy }}
+ command:
+ - /bin/sh
+ - -exuc
+ - |
+ {{- range .Values.enterprise.provisioner.additionalTenants }}
+ /usr/bin/enterprise-logs-provisioner \
+ -bootstrap-path=/bootstrap \
+ -cluster-name={{ include "loki.clusterName" $ }} \
+ -gel-url={{ include "loki.address" $ }} \
+ -instance={{ .name }} \
+ -access-policy=write-{{ .name }}:{{ .name }}:logs:write \
+ -access-policy=read-{{ .name }}:{{ .name }}:logs:read \
+ -token=write-{{ .name }} \
+ -token=read-{{ .name }}
+ {{- end -}}
+
+ {{- with .Values.monitoring.selfMonitoring.tenant }}
+ /usr/bin/enterprise-logs-provisioner \
+ -bootstrap-path=/bootstrap \
+ -cluster-name={{ include "loki.clusterName" $ }} \
+ -gel-url={{ include "loki.address" $ }} \
+ -instance={{ .name }} \
+ -access-policy=self-monitoring:{{ .name }}:logs:write,logs:read \
+ -token=self-monitoring
+ {{- end }}
+ volumeMounts:
+ {{- with .Values.enterprise.provisioner.extraVolumeMounts }}
+ {{ toYaml . | nindent 12 }}
+ {{- end }}
+ - name: bootstrap
+ mountPath: /bootstrap
+ - name: admin-token
+ mountPath: /bootstrap/token
+ subPath: token
+ {{- with .Values.enterprise.provisioner.env }}
+ env:
+ {{ toYaml . | nindent 12 }}
+ {{- end }}
+ containers:
+ - name: create-secret
+ image: {{ include "loki.kubectlImage" . }}
+ imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }}
+ command:
+ - /bin/bash
+ - -exuc
+ - |
+ {{- range .Values.enterprise.provisioner.additionalTenants }}
+ kubectl --namespace "{{ .secretNamespace }}" create secret generic "{{ include "enterprise-logs.provisionedSecretPrefix" $ }}-{{ .name }}" \
+ --from-literal=token-write="$(cat /bootstrap/token-write-{{ .name }})" \
+ --from-literal=token-read="$(cat /bootstrap/token-read-{{ .name }})"
+ {{- end }}
+ {{- $namespace := $.Release.Namespace }}
+ {{- with .Values.monitoring.selfMonitoring.tenant }}
+ {{- $secretNamespace := tpl .secretNamespace $ }}
+ kubectl --namespace "{{ $namespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \
+ --from-literal=username="{{ .name }}" \
+ --from-literal=password="$(cat /bootstrap/token-self-monitoring)"
+ {{- if not (eq $secretNamespace $namespace) }}
+ kubectl --namespace "{{ $secretNamespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \
+ --from-literal=username="{{ .name }}" \
+ --from-literal=password="$(cat /bootstrap/token-self-monitoring)"
+ {{- end }}
+ {{- end }}
+ volumeMounts:
+ {{- with .Values.enterprise.provisioner.extraVolumeMounts }}
+ {{ toYaml . | nindent 12 }}
+ {{- end }}
+ - name: bootstrap
+ mountPath: /bootstrap
+ restartPolicy: OnFailure
+ serviceAccount: {{ include "enterprise-logs.provisionerFullname" . }}
+ serviceAccountName: {{ include "enterprise-logs.provisionerFullname" . }}
+ volumes:
+ - name: admin-token
+ secret:
+ secretName: "{{ include "enterprise-logs.adminTokenSecret" . }}"
+ - name: bootstrap
+ emptyDir: {}
+{{- end }}
diff --git a/charts/loki/templates/provisioner/role-provisioner.yaml b/charts/loki/templates/provisioner/role-provisioner.yaml
new file mode 100644
index 0000000..a8da599
--- /dev/null
+++ b/charts/loki/templates/provisioner/role-provisioner.yaml
@@ -0,0 +1,20 @@
+{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+ labels:
+ {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.provisioner.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.provisioner.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+rules:
+ - apiGroups: [""]
+ resources: ["secrets"]
+ verbs: ["create"]
+{{- end }}
diff --git a/charts/loki/templates/provisioner/rolebinding-provisioner.yaml b/charts/loki/templates/provisioner/rolebinding-provisioner.yaml
new file mode 100644
index 0000000..0fc46f4
--- /dev/null
+++ b/charts/loki/templates/provisioner/rolebinding-provisioner.yaml
@@ -0,0 +1,25 @@
+{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+ labels:
+ {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.provisioner.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.provisioner.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+subjects:
+ - kind: ServiceAccount
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end }}
diff --git a/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml b/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml
new file mode 100644
index 0000000..2dc67d2
--- /dev/null
+++ b/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml
@@ -0,0 +1,18 @@
+{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "enterprise-logs.provisionerFullname" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.provisioner.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.provisioner.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+{{- end }}
diff --git a/charts/loki/templates/read/_helpers-read.tpl b/charts/loki/templates/read/_helpers-read.tpl
new file mode 100644
index 0000000..d205314
--- /dev/null
+++ b/charts/loki/templates/read/_helpers-read.tpl
@@ -0,0 +1,32 @@
+{{/*
+read fullname
+*/}}
+{{- define "loki.readFullname" -}}
+{{ include "loki.name" . }}-read
+{{- end }}
+
+{{/*
+read common labels
+*/}}
+{{- define "loki.readLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: read
+{{- end }}
+
+{{/*
+read selector labels
+*/}}
+{{- define "loki.readSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: read
+{{- end }}
+
+{{/*
+read priority class name
+*/}}
+{{- define "loki.readPriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.read.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/read/deployment-read.yaml b/charts/loki/templates/read/deployment-read.yaml
new file mode 100644
index 0000000..9e9c26d
--- /dev/null
+++ b/charts/loki/templates/read/deployment-read.yaml
@@ -0,0 +1,148 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "loki.readFullname" . }}
+ labels:
+ app.kubernetes.io/part-of: memberlist
+ {{- include "loki.readLabels" . | nindent 4 }}
+spec:
+ {{- if not .Values.read.autoscaling.enabled }}
+ replicas: {{ .Values.read.replicas }}
+ {{- end }}
+ strategy:
+ rollingUpdate:
+ maxSurge: 0
+ maxUnavailable: 1
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ selector:
+ matchLabels:
+ {{- include "loki.readSelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ app.kubernetes.io/part-of: memberlist
+ {{- include "loki.readSelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 8 }}
+ {{- end }}
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.readPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }}
+ containers:
+ - name: loki
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.read.targetModule }}
+ - -legacy-read-mode=false
+ - -common.compactor-grpc-address={{ include "loki.backendFullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:9095
+ {{- with .Values.read.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ - name: http-memberlist
+ containerPort: 7946
+ protocol: TCP
+ {{- with .Values.read.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.read.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ - name: tmp
+ mountPath: /tmp
+ - name: data
+ mountPath: /var/loki
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ mountPath: /etc/loki/license
+ {{- end}}
+ {{- with .Values.read.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.read.resources | nindent 12 }}
+ {{- with .Values.read.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: data
+ emptyDir: {}
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ {{- end }}
+ {{- with .Values.read.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/read/poddisruptionbudget-read.yaml b/charts/loki/templates/read/poddisruptionbudget-read.yaml
new file mode 100644
index 0000000..3f2f5cd
--- /dev/null
+++ b/charts/loki/templates/read/poddisruptionbudget-read.yaml
@@ -0,0 +1,14 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (gt (int .Values.read.replicas) 1) }}
+apiVersion: {{ include "loki.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ include "loki.readFullname" . }}
+ labels:
+ {{- include "loki.readLabels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki.readSelectorLabels" . | nindent 6 }}
+ maxUnavailable: 1
+{{- end }}
diff --git a/charts/loki/templates/read/service-read-headless.yaml b/charts/loki/templates/read/service-read-headless.yaml
new file mode 100644
index 0000000..ec2d57a
--- /dev/null
+++ b/charts/loki/templates/read/service-read-headless.yaml
@@ -0,0 +1,26 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{ if $isSimpleScalable }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.readFullname" . }}-headless
+ labels:
+ {{- include "loki.readSelectorLabels" . | nindent 4 }}
+ prometheus.io/service-monitor: "false"
+spec:
+ type: ClusterIP
+ clusterIP: None
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ appProtocol: tcp
+ selector:
+ {{- include "loki.readSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/read/service-read.yaml b/charts/loki/templates/read/service-read.yaml
new file mode 100644
index 0000000..5512bce
--- /dev/null
+++ b/charts/loki/templates/read/service-read.yaml
@@ -0,0 +1,26 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if $isSimpleScalable }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.readFullname" . }}
+ labels:
+ {{- include "loki.readLabels" . | nindent 4 }}
+ {{- with .Values.read.serviceLabels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.readSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/read/statefulset-read.yaml b/charts/loki/templates/read/statefulset-read.yaml
new file mode 100644
index 0000000..066620b
--- /dev/null
+++ b/charts/loki/templates/read/statefulset-read.yaml
@@ -0,0 +1,173 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (.Values.read.legacyReadTarget ) }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "loki.readFullname" . }}
+ labels:
+ app.kubernetes.io/part-of: memberlist
+ {{- include "loki.readLabels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.read.replicas }}
+ podManagementPolicy: Parallel
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ serviceName: {{ printf "%s-headless" (include "loki.readFullname" .) }}
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.read.persistence.enableStatefulSetAutoDeletePVC) }}
+ {{/*
+ Data on the read nodes is easy to replace, so we want to always delete PVCs to make
+ operation easier, and will rely on re-fetching data when needed.
+ */}}
+ persistentVolumeClaimRetentionPolicy:
+ whenDeleted: Delete
+ whenScaled: Delete
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.readSelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ app.kubernetes.io/part-of: memberlist
+ {{- include "loki.readSelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 8 }}
+ {{- end }}
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+ {{ include "loki.enableServiceLinks" . }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.readPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }}
+ containers:
+ - name: loki
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.read.targetModule }}
+ {{- with .Values.read.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ - name: http-memberlist
+ containerPort: 7946
+ protocol: TCP
+ {{- with .Values.read.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.read.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ {{- with .Values.read.lifecycle }}
+ lifecycle:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ - name: tmp
+ mountPath: /tmp
+ - name: data
+ mountPath: /var/loki
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ mountPath: /etc/loki/license
+ {{- end}}
+ {{- with .Values.read.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.read.resources | nindent 12 }}
+ {{- with .Values.read.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.read.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ {{- end }}
+ {{- with .Values.read.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumeClaimTemplates:
+ - metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ {{- with .Values.read.persistence.storageClass }}
+ storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.read.persistence.size | quote }}
+ {{- with .Values.read.persistence.selector }}
+ selector:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/role.yaml b/charts/loki/templates/role.yaml
new file mode 100644
index 0000000..768dd39
--- /dev/null
+++ b/charts/loki/templates/role.yaml
@@ -0,0 +1,31 @@
+{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: {{ include "loki.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+{{- if .Values.rbac.pspEnabled }}
+rules:
+ - apiGroups:
+ - policy
+ resources:
+ - podsecuritypolicies
+ verbs:
+ - use
+ resourceNames:
+ - {{ include "loki.fullname" . }}
+{{- end }}
+{{- if .Values.rbac.sccEnabled }}
+rules:
+ - apiGroups:
+ - security.openshift.io
+ resources:
+ - securitycontextconstraints
+ verbs:
+ - use
+ resourceNames:
+ - {{ include "loki.fullname" . }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/rolebinding.yaml b/charts/loki/templates/rolebinding.yaml
new file mode 100644
index 0000000..71f9e8f
--- /dev/null
+++ b/charts/loki/templates/rolebinding.yaml
@@ -0,0 +1,16 @@
+{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ include "loki.name" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: {{ include "loki.name" . }}
+subjects:
+ - kind: ServiceAccount
+ name: {{ include "loki.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end }}
diff --git a/charts/loki/templates/runtime-configmap.yaml b/charts/loki/templates/runtime-configmap.yaml
new file mode 100644
index 0000000..a8a1344
--- /dev/null
+++ b/charts/loki/templates/runtime-configmap.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "loki.name" . }}-runtime
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+data:
+ runtime-config.yaml: |
+ {{ tpl (toYaml .Values.loki.runtimeConfig) . | nindent 4 }}
diff --git a/charts/loki/templates/secret-license.yaml b/charts/loki/templates/secret-license.yaml
new file mode 100644
index 0000000..31af72e
--- /dev/null
+++ b/charts/loki/templates/secret-license.yaml
@@ -0,0 +1,10 @@
+{{- if and (not .Values.enterprise.useExternalLicense) .Values.enterprise.enabled -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: enterprise-logs-license
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+data:
+ license.jwt: {{ .Values.enterprise.license.contents | b64enc }}
+{{- end }}
diff --git a/charts/loki/templates/securitycontextconstraints.yaml b/charts/loki/templates/securitycontextconstraints.yaml
new file mode 100644
index 0000000..c3a604d
--- /dev/null
+++ b/charts/loki/templates/securitycontextconstraints.yaml
@@ -0,0 +1,40 @@
+{{- if .Values.rbac.sccEnabled }}
+apiVersion: security.openshift.io/v1
+kind: SecurityContextConstraints
+metadata:
+ name: {{ include "loki.name" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+allowHostDirVolumePlugin: false
+allowHostIPC: false
+allowHostNetwork: false
+allowHostPID: false
+allowHostPorts: false
+allowPrivilegeEscalation: true
+allowPrivilegedContainer: false
+allowedCapabilities: []
+defaultAddCapabilities: null
+fsGroup:
+ type: RunAsAny
+groups: []
+priority: null
+readOnlyRootFilesystem: false
+requiredDropCapabilities:
+ - ALL
+runAsUser:
+ type: RunAsAny
+seLinuxContext:
+ type: MustRunAs
+seccompProfiles:
+ - '*'
+supplementalGroups:
+ type: RunAsAny
+volumes:
+ - configMap
+ - downwardAPI
+ - emptyDir
+ - hostPath
+ - persistentVolumeClaim
+ - projected
+ - secret
+{{- end }}
diff --git a/charts/loki/templates/service-memberlist.yaml b/charts/loki/templates/service-memberlist.yaml
new file mode 100644
index 0000000..ca10485
--- /dev/null
+++ b/charts/loki/templates/service-memberlist.yaml
@@ -0,0 +1,21 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.memberlist" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ type: ClusterIP
+ clusterIP: None
+ ports:
+ - name: tcp
+ port: 7946
+ targetPort: http-memberlist
+ protocol: TCP
+ {{- with .Values.memberlist.service.publishNotReadyAddresses }}
+ publishNotReadyAddresses: {{ . }}
+ {{- end }}
+ selector:
+ {{- include "loki.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/part-of: memberlist
diff --git a/charts/loki/templates/serviceaccount.yaml b/charts/loki/templates/serviceaccount.yaml
new file mode 100644
index 0000000..5734c01
--- /dev/null
+++ b/charts/loki/templates/serviceaccount.yaml
@@ -0,0 +1,20 @@
+{{ if .Values.serviceAccount.create }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "loki.serviceAccountName" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- tpl (toYaml . | nindent 4) $ }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+{{- with .Values.serviceAccount.imagePullSecrets }}
+imagePullSecrets:
+ {{- toYaml . | nindent 2 }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/single-binary/_helpers-single-binary.tpl b/charts/loki/templates/single-binary/_helpers-single-binary.tpl
new file mode 100644
index 0000000..4ea3c6d
--- /dev/null
+++ b/charts/loki/templates/single-binary/_helpers-single-binary.tpl
@@ -0,0 +1,34 @@
+{{/*
+singleBinary common labels
+*/}}
+{{- define "loki.singleBinaryLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: single-binary
+{{- end }}
+
+
+{{/* singleBinary selector labels */}}
+{{- define "loki.singleBinarySelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: single-binary
+{{- end }}
+
+{{/*
+singleBinary priority class name
+*/}}
+{{- define "loki.singleBinaryPriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.singleBinary.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
+
+{{/* singleBinary replicas calculation */}}
+{{- define "loki.singleBinaryReplicas" -}}
+{{- $replicas := 1 }}
+{{- $usingObjectStorage := eq (include "loki.isUsingObjectStorage" .) "true" }}
+{{- if and $usingObjectStorage (gt (int .Values.singleBinary.replicas) 1)}}
+{{- $replicas = int .Values.singleBinary.replicas -}}
+{{- end }}
+{{- printf "%d" $replicas }}
+{{- end }}
diff --git a/charts/loki/templates/single-binary/pdb.yaml b/charts/loki/templates/single-binary/pdb.yaml
new file mode 100644
index 0000000..65bc53d
--- /dev/null
+++ b/charts/loki/templates/single-binary/pdb.yaml
@@ -0,0 +1,16 @@
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- if and .Values.podDisruptionBudget $isSingleBinary -}}
+---
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+ name: {{ template "loki.fullname" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }}
+{{ toYaml .Values.podDisruptionBudget | indent 2 }}
+{{- end }}
diff --git a/charts/loki/templates/single-binary/service-headless.yaml b/charts/loki/templates/single-binary/service-headless.yaml
new file mode 100644
index 0000000..9d4d85e
--- /dev/null
+++ b/charts/loki/templates/single-binary/service-headless.yaml
@@ -0,0 +1,22 @@
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- if $isSingleBinary }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.name" . }}-headless
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+ variant: headless
+ prometheus.io/service-monitor: "false"
+spec:
+ clusterIP: None
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ selector:
+ {{- include "loki.selectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/single-binary/service.yaml b/charts/loki/templates/single-binary/service.yaml
new file mode 100644
index 0000000..698438e
--- /dev/null
+++ b/charts/loki/templates/single-binary/service.yaml
@@ -0,0 +1,26 @@
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- if $isSingleBinary }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.singleBinaryFullname" . }}
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.singleBinarySelectorLabels" . | nindent 4 }}
+ {{- with .Values.singleBinary.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/single-binary/statefulset.yaml b/charts/loki/templates/single-binary/statefulset.yaml
new file mode 100644
index 0000000..ed757f8
--- /dev/null
+++ b/charts/loki/templates/single-binary/statefulset.yaml
@@ -0,0 +1,179 @@
+{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}}
+{{- if $isSingleBinary }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "loki.singleBinaryFullname" . }}
+ labels:
+ {{- include "loki.singleBinaryLabels" . | nindent 4 }}
+ app.kubernetes.io/part-of: memberlist
+spec:
+ replicas: {{ include "loki.singleBinaryReplicas" . }}
+ podManagementPolicy: Parallel
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ serviceName: {{ include "loki.singleBinaryFullname" . }}-headless
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.singleBinary.persistence.enableStatefulSetAutoDeletePVC) }}
+ {{/*
+ Data on the singleBinary nodes is easy to replace, so we want to always delete PVCs to make
+ operation easier, and will rely on re-fetching data when needed.
+ */}}
+ persistentVolumeClaimRetentionPolicy:
+ whenDeleted: Delete
+ whenScaled: Delete
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.singleBinary.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "loki.singleBinarySelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.singleBinary.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.singleBinary.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 8 }}
+ {{- end }}
+ app.kubernetes.io/part-of: memberlist
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+ {{ include "loki.enableServiceLinks" . }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.singleBinaryPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.singleBinary.terminationGracePeriodSeconds }}
+ {{- if .Values.singleBinary.initContainers }}
+ initContainers:
+ {{- with .Values.singleBinary.initContainers }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- end }}
+ containers:
+ - name: loki
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.singleBinary.targetModule }}
+ {{- with .Values.singleBinary.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ - name: http-memberlist
+ containerPort: 7946
+ protocol: TCP
+ {{- with .Values.singleBinary.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.singleBinary.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ volumeMounts:
+ - name: tmp
+ mountPath: /tmp
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ {{- if .Values.singleBinary.persistence.enabled }}
+ - name: storage
+ mountPath: /var/loki
+ {{- end }}
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ mountPath: /etc/loki/license
+ {{- end }}
+ {{- with .Values.singleBinary.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.singleBinary.resources | nindent 12 }}
+ {{- with .Values.singleBinary.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.singleBinary.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.singleBinary.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: tmp
+ emptyDir: {}
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ {{- end }}
+ {{- with .Values.singleBinary.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- if .Values.singleBinary.persistence.enabled }}
+ volumeClaimTemplates:
+ - metadata:
+ name: storage
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ {{- with .Values.singleBinary.persistence.storageClass }}
+ storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.singleBinary.persistence.size | quote }}
+ {{- with .Values.singleBinary.persistence.selector }}
+ selector:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/table-manager/_helpers-table-manager.tpl b/charts/loki/templates/table-manager/_helpers-table-manager.tpl
new file mode 100644
index 0000000..ff25832
--- /dev/null
+++ b/charts/loki/templates/table-manager/_helpers-table-manager.tpl
@@ -0,0 +1,32 @@
+{{/*
+table-manager fullname
+*/}}
+{{- define "loki.tableManagerFullname" -}}
+{{ include "loki.fullname" . }}-table-manager
+{{- end }}
+
+{{/*
+table-manager common labels
+*/}}
+{{- define "loki.tableManagerLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: table-manager
+{{- end }}
+
+{{/*
+table-manager selector labels
+*/}}
+{{- define "loki.tableManagerSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: table-manager
+{{- end }}
+
+{{/*
+table-manager priority class name
+*/}}
+{{- define "loki.tableManagerPriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.tableManager.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/table-manager/deployment-table-manager.yaml b/charts/loki/templates/table-manager/deployment-table-manager.yaml
new file mode 100644
index 0000000..f5529eb
--- /dev/null
+++ b/charts/loki/templates/table-manager/deployment-table-manager.yaml
@@ -0,0 +1,112 @@
+{{- if .Values.tableManager.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "loki.tableManagerFullname" . }}
+ labels:
+ {{- include "loki.tableManagerLabels" . | nindent 4 }}
+ {{- with .Values.loki.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ replicas: 1
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ selector:
+ matchLabels:
+ {{- include "loki.tableManagerSelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tableManager.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "loki.tableManagerSelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tableManager.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.tableManagerPriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.tableManager.terminationGracePeriodSeconds }}
+ containers:
+ - name: table-manager
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target=table-manager
+ {{- with .Values.tableManager.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ {{- with .Values.tableManager.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.tableManager.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ livenessProbe:
+ {{- toYaml .Values.loki.livenessProbe | nindent 12 }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/loki/config
+ {{- with .Values.tableManager.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.tableManager.resources | nindent 12 }}
+ {{- if .Values.tableManager.extraContainers }}
+ {{- toYaml .Values.tableManager.extraContainers | nindent 8}}
+ {{- end }}
+ {{- with .Values.tableManager.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tableManager.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tableManager.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.fullname" . }}
+ {{- end }}
+ {{- with .Values.tableManager.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/table-manager/service-table-manager.yaml b/charts/loki/templates/table-manager/service-table-manager.yaml
new file mode 100644
index 0000000..4673120
--- /dev/null
+++ b/charts/loki/templates/table-manager/service-table-manager.yaml
@@ -0,0 +1,30 @@
+{{- if .Values.tableManager.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.fullname" . }}-table-manager
+ labels:
+ {{- include "loki.labels" . | nindent 4 }}
+ {{- with .Values.tableManager.serviceLabels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ app.kubernetes.io/component: table-manager
+ {{- with .Values.loki.serviceAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.selectorLabels" . | nindent 4 }}
+ app.kubernetes.io/component: table-manager
+{{- end }}
diff --git a/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml b/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml
new file mode 100644
index 0000000..09aa727
--- /dev/null
+++ b/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml
@@ -0,0 +1,57 @@
+{{- if .Values.tableManager.enabled }}
+{{- with .Values.serviceMonitor }}
+{{- if .enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ include "loki.tableManagerFullname" $ }}
+ {{- with .namespace }}
+ namespace: {{ . }}
+ {{- end }}
+ {{- with .annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "loki.tableManagerLabels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .namespaceSelector }}
+ namespaceSelector:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.tableManagerSelectorLabels" $ | nindent 6 }}
+ endpoints:
+ - port: http-metrics
+ {{- with .interval }}
+ interval: {{ . }}
+ {{- end }}
+ {{- with .scrapeTimeout }}
+ scrapeTimeout: {{ . }}
+ {{- end }}
+ {{- with .relabelings }}
+ relabelings:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .metricRelabelings }}
+ metricRelabelings:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .scheme }}
+ scheme: {{ . }}
+ {{- end }}
+ {{- with .tlsConfig }}
+ tlsConfig:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .targetLabels }}
+ targetLabels:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/tests/_helpers.tpl b/charts/loki/templates/tests/_helpers.tpl
new file mode 100644
index 0000000..9ef7c15
--- /dev/null
+++ b/charts/loki/templates/tests/_helpers.tpl
@@ -0,0 +1,16 @@
+{{/*
+Docker image name for loki helm test
+*/}}
+{{- define "loki.helmTestImage" -}}
+{{- $dict := dict "service" .Values.test.image "global" .Values.global.image "defaultVersion" "latest" -}}
+{{- include "loki.baseImage" $dict -}}
+{{- end -}}
+
+
+{{/*
+test common labels
+*/}}
+{{- define "loki.helmTestLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: helm-test
+{{- end }}
diff --git a/charts/loki/templates/tests/test-canary.yaml b/charts/loki/templates/tests/test-canary.yaml
new file mode 100644
index 0000000..eb41772
--- /dev/null
+++ b/charts/loki/templates/tests/test-canary.yaml
@@ -0,0 +1,33 @@
+{{- with .Values.test }}
+{{- if and .enabled $.Values.monitoring.selfMonitoring.enabled $.Values.monitoring.lokiCanary.enabled }}
+---
+apiVersion: v1
+kind: Pod
+metadata:
+ name: "{{ include "loki.name" $ }}-helm-test"
+ labels:
+ {{- include "loki.helmTestLabels" $ | nindent 4 }}
+ {{- with .labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": test
+spec:
+ containers:
+ - name: loki-helm-test
+ image: {{ include "loki.helmTestImage" $ }}
+ env:
+ - name: CANARY_PROMETHEUS_ADDRESS
+ value: "{{ .prometheusAddress }}"
+ {{- with .timeout }}
+ - name: CANARY_TEST_TIMEOUT
+ value: "{{ . }}"
+ {{- end }}
+ args:
+ - -test.v
+ restartPolicy: Never
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/tokengen/_helpers.yaml b/charts/loki/templates/tokengen/_helpers.yaml
new file mode 100644
index 0000000..3c881f2
--- /dev/null
+++ b/charts/loki/templates/tokengen/_helpers.yaml
@@ -0,0 +1,22 @@
+{{/*
+tokengen fullname
+*/}}
+{{- define "enterprise-logs.tokengenFullname" -}}
+{{ include "loki.name" . }}-tokengen
+{{- end }}
+
+{{/*
+tokengen common labels
+*/}}
+{{- define "enterprise-logs.tokengenLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: tokengen
+{{- end }}
+
+{{/*
+tokengen selector labels
+*/}}
+{{- define "enterprise-logs.tokengenSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: tokengen
+{{- end }}
diff --git a/charts/loki/templates/tokengen/clusterrole-tokengen.yaml b/charts/loki/templates/tokengen/clusterrole-tokengen.yaml
new file mode 100644
index 0000000..2ebfb14
--- /dev/null
+++ b/charts/loki/templates/tokengen/clusterrole-tokengen.yaml
@@ -0,0 +1,21 @@
+{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+ labels:
+ {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.tokengen.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.tokengen.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+rules:
+ - apiGroups: [""]
+ resources: ["secrets"]
+ verbs: ["create"]
+{{- end }}
diff --git a/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml b/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml
new file mode 100644
index 0000000..3c7fb13
--- /dev/null
+++ b/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml
@@ -0,0 +1,25 @@
+{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+ labels:
+ {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.tokengen.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.tokengen.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+subjects:
+ - kind: ServiceAccount
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end }}
diff --git a/charts/loki/templates/tokengen/job-tokengen.yaml b/charts/loki/templates/tokengen/job-tokengen.yaml
new file mode 100644
index 0000000..670a812
--- /dev/null
+++ b/charts/loki/templates/tokengen/job-tokengen.yaml
@@ -0,0 +1,129 @@
+{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }}
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+ labels:
+ {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.tokengen.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.tokengen.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+ "helm.sh/hook-weight": "10"
+spec:
+ backoffLimit: 6
+ completions: 1
+ parallelism: 1
+ template:
+ metadata:
+ labels:
+ {{- include "enterprise-logs.tokengenSelectorLabels" . | nindent 8 }}
+ {{- with .Values.enterprise.tokengen.labels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.tokengen.annotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.enterprise.tokengen.priorityClassName }}
+ priorityClassName: {{ . }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.enterprise.tokengen.securityContext | nindent 8 }}
+ {{- if .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml .Values.imagePullSecrets | nindent 8 }}
+ {{- end }}
+ initContainers:
+ - name: loki
+ image: {{ template "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.enterprise.tokengen.targetModule }}
+ - -tokengen.token-file=/shared/admin-token
+ {{- with .Values.enterprise.tokengen.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ {{- if .Values.enterprise.tokengen.extraVolumeMounts }}
+ {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }}
+ {{- end }}
+ - name: shared
+ mountPath: /shared
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ - name: license
+ mountPath: /etc/loki/license
+ env:
+ {{- if .Values.enterprise.tokengen.env }}
+ {{ toYaml .Values.enterprise.tokengen.env | nindent 12 }}
+ {{- end }}
+ {{- with .Values.enterprise.tokengen.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ containers:
+ - name: create-secret
+ image: {{ include "loki.kubectlImage" . }}
+ imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }}
+ command:
+ - /bin/bash
+ - -euc
+ - |
+ kubectl create secret generic "{{ include "enterprise-logs.adminTokenSecret" . }}" --from-file=token=/shared/admin-token
+ {{- with .Values.enterprise.adminToken.additionalNamespaces }}
+ {{- range . }}
+ kubectl --namespace "{{ . }}" create secret generic "{{ include "enterprise-logs.adminTokenSecret" $ }}" --from-file=token=/shared/admin-token
+ {{- end }}
+ {{- end }}
+ volumeMounts:
+ {{- if .Values.enterprise.tokengen.extraVolumeMounts }}
+ {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }}
+ {{- end }}
+ - name: shared
+ mountPath: /shared
+ - name: config
+ mountPath: /etc/loki/config
+ - name: license
+ mountPath: /etc/loki/license
+ restartPolicy: OnFailure
+ serviceAccount: {{ template "enterprise-logs.tokengenFullname" . }}
+ serviceAccountName: {{ template "enterprise-logs.tokengenFullname" . }}
+ {{- with .Values.enterprise.tokengen.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: config
+ {{- if .Values.enterprise.useExternalConfig }}
+ secret:
+ secretName: {{ .Values.enterprise.externalConfigName }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ - name: shared
+ emptyDir: {}
+ {{- if .Values.enterprise.tokengen.extraVolumes }}
+ {{ toYaml .Values.enterprise.tokengen.extraVolumes | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml b/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml
new file mode 100644
index 0000000..25e6ca8
--- /dev/null
+++ b/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml
@@ -0,0 +1,18 @@
+{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "enterprise-logs.tokengenFullname" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }}
+ {{- with .Values.enterprise.tokengen.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ annotations:
+ {{- with .Values.enterprise.tokengen.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ "helm.sh/hook": post-install
+{{- end }}
diff --git a/charts/loki/templates/validate.yaml b/charts/loki/templates/validate.yaml
new file mode 100644
index 0000000..3a2e8ca
--- /dev/null
+++ b/charts/loki/templates/validate.yaml
@@ -0,0 +1,27 @@
+{{- if .Values.config }}
+{{- fail "Top level 'config' is not allowed. Most common configuration sections are exposed under the `loki` section. If you need to override the whole config, provide the configuration as a string that can contain template expressions under `loki.config`. Alternatively, you can provide the configuration as an external secret." }}
+{{- end }}
+
+{{- if and (not .Values.monitoring.selfMonitoring.enabled) .Values.test.enabled }}
+{{- fail "Helm test requires self monitoring to be enabled"}}
+{{- end }}
+
+{{- if and (not .Values.monitoring.lokiCanary.enabled) .Values.test.enabled }}
+{{- fail "Helm test requires the Loki Canary to be enabled"}}
+{{- end }}
+
+{{- if and .Values.test.enabled (not .Values.test.prometheusAddress) }}
+{{- fail "Helm test requires a prometheusAddress for an instance scraping the Loki canary's metrics"}}
+{{- end }}
+
+{{- $singleBinaryReplicas := int .Values.singleBinary.replicas }}
+{{- $isUsingFilesystem := eq (include "loki.isUsingObjectStorage" .) "false" }}
+{{- $atLeastOneScalableReplica := or (gt (int .Values.backend.replicas) 0) (gt (int .Values.read.replicas) 0) (gt (int .Values.write.replicas) 0) }}
+
+{{- if and $isUsingFilesystem (gt $singleBinaryReplicas 1) }}
+{{- fail "Cannot run more than 1 Single Binary replica without an object storage backend."}}
+{{- end }}
+
+{{- if and $isUsingFilesystem (and (eq $singleBinaryReplicas 0) $atLeastOneScalableReplica) }}
+{{- fail "Cannot run Scalable targets (backend, read, write) without an object storage backend."}}
+{{- end }}
diff --git a/charts/loki/templates/write/_helpers-write.tpl b/charts/loki/templates/write/_helpers-write.tpl
new file mode 100644
index 0000000..8f526bc
--- /dev/null
+++ b/charts/loki/templates/write/_helpers-write.tpl
@@ -0,0 +1,32 @@
+{{/*
+write fullname
+*/}}
+{{- define "loki.writeFullname" -}}
+{{ include "loki.name" . }}-write
+{{- end }}
+
+{{/*
+write common labels
+*/}}
+{{- define "loki.writeLabels" -}}
+{{ include "loki.labels" . }}
+app.kubernetes.io/component: write
+{{- end }}
+
+{{/*
+write selector labels
+*/}}
+{{- define "loki.writeSelectorLabels" -}}
+{{ include "loki.selectorLabels" . }}
+app.kubernetes.io/component: write
+{{- end }}
+
+{{/*
+write priority class name
+*/}}
+{{- define "loki.writePriorityClassName" -}}
+{{- $pcn := coalesce .Values.global.priorityClassName .Values.write.priorityClassName -}}
+{{- if $pcn }}
+priorityClassName: {{ $pcn }}
+{{- end }}
+{{- end }}
diff --git a/charts/loki/templates/write/poddisruptionbudget-write.yaml b/charts/loki/templates/write/poddisruptionbudget-write.yaml
new file mode 100644
index 0000000..9acfc74
--- /dev/null
+++ b/charts/loki/templates/write/poddisruptionbudget-write.yaml
@@ -0,0 +1,14 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if and $isSimpleScalable (gt (int .Values.write.replicas) 1) }}
+apiVersion: {{ include "loki.podDisruptionBudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ include "loki.writeFullname" . }}
+ labels:
+ {{- include "loki.writeLabels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "loki.writeSelectorLabels" . | nindent 6 }}
+ maxUnavailable: 1
+{{- end }}
diff --git a/charts/loki/templates/write/service-write-headless.yaml b/charts/loki/templates/write/service-write-headless.yaml
new file mode 100644
index 0000000..26f1682
--- /dev/null
+++ b/charts/loki/templates/write/service-write-headless.yaml
@@ -0,0 +1,26 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if $isSimpleScalable }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.writeFullname" . }}-headless
+ labels:
+ {{- include "loki.writeSelectorLabels" . | nindent 4 }}
+ prometheus.io/service-monitor: "false"
+spec:
+ type: ClusterIP
+ clusterIP: None
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ appProtocol: tcp
+ selector:
+ {{- include "loki.writeSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/write/service-write.yaml b/charts/loki/templates/write/service-write.yaml
new file mode 100644
index 0000000..3afc57e
--- /dev/null
+++ b/charts/loki/templates/write/service-write.yaml
@@ -0,0 +1,26 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if $isSimpleScalable }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "loki.writeFullname" . }}
+ labels:
+ {{- include "loki.writeLabels" . | nindent 4 }}
+ {{- with .Values.write.serviceLabels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ type: ClusterIP
+ ports:
+ - name: http-metrics
+ port: 3100
+ targetPort: http-metrics
+ protocol: TCP
+ - name: grpc
+ port: 9095
+ targetPort: grpc
+ protocol: TCP
+ selector:
+ {{- include "loki.writeSelectorLabels" . | nindent 4 }}
+{{- end }}
diff --git a/charts/loki/templates/write/statefulset-write.yaml b/charts/loki/templates/write/statefulset-write.yaml
new file mode 100644
index 0000000..702f7f9
--- /dev/null
+++ b/charts/loki/templates/write/statefulset-write.yaml
@@ -0,0 +1,176 @@
+{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}}
+{{- if $isSimpleScalable }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "loki.writeFullname" . }}
+ labels:
+ {{- include "loki.writeLabels" . | nindent 4 }}
+ app.kubernetes.io/part-of: memberlist
+spec:
+ replicas: {{ .Values.write.replicas }}
+
+ podManagementPolicy: Parallel
+ updateStrategy:
+ rollingUpdate:
+ partition: 0
+ serviceName: {{ include "loki.writeFullname" . }}-headless
+ revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }}
+ {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.write.persistence.enableStatefulSetAutoDeletePVC) }}
+ {{/*
+ Data on the write nodes is easy to replace, so we want to always delete PVCs to make
+ operation easier, and will rely on re-fetching data when needed.
+ */}}
+ persistentVolumeClaimRetentionPolicy:
+ whenDeleted: Delete
+ whenScaled: Delete
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "loki.writeSelectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- with .Values.loki.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.write.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "loki.writeSelectorLabels" . | nindent 8 }}
+ {{- with .Values.loki.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.write.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.write.selectorLabels }}
+ {{- tpl (toYaml .) $ | nindent 8 }}
+ {{- end }}
+ app.kubernetes.io/part-of: memberlist
+ spec:
+ serviceAccountName: {{ include "loki.serviceAccountName" . }}
+ automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+ {{ include "loki.enableServiceLinks" . }}
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- include "loki.writePriorityClassName" . | nindent 6 }}
+ securityContext:
+ {{- toYaml .Values.loki.podSecurityContext | nindent 8 }}
+ terminationGracePeriodSeconds: {{ .Values.write.terminationGracePeriodSeconds }}
+ {{- if .Values.write.initContainers }}
+ initContainers:
+ {{- with .Values.write.initContainers }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- end }}
+ containers:
+ - name: loki
+ image: {{ include "loki.image" . }}
+ imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
+ args:
+ - -config.file=/etc/loki/config/config.yaml
+ - -target={{ .Values.write.targetModule }}
+ {{- with .Values.write.extraArgs }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http-metrics
+ containerPort: 3100
+ protocol: TCP
+ - name: grpc
+ containerPort: 9095
+ protocol: TCP
+ - name: http-memberlist
+ containerPort: 7946
+ protocol: TCP
+ {{- with .Values.write.extraEnv }}
+ env:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.write.extraEnvFrom }}
+ envFrom:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }}
+ readinessProbe:
+ {{- toYaml .Values.loki.readinessProbe | nindent 12 }}
+ {{- with .Values.write.lifecycle }}
+ lifecycle:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ - name: config
+ mountPath: /etc/loki/config
+ - name: runtime-config
+ mountPath: /etc/loki/runtime-config
+ - name: data
+ mountPath: /var/loki
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ mountPath: /etc/loki/license
+ {{- end}}
+ {{- with .Values.write.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.write.resources | nindent 12 }}
+ {{- with .Values.write.affinity }}
+ affinity:
+ {{- tpl . $ | nindent 8 }}
+ {{- end }}
+ {{- with .Values.write.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.write.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumes:
+ - name: config
+ {{- if .Values.loki.existingSecretForConfig }}
+ secret:
+ secretName: {{ .Values.loki.existingSecretForConfig }}
+ {{- else }}
+ configMap:
+ name: {{ include "loki.name" . }}
+ {{- end }}
+ - name: runtime-config
+ configMap:
+ name: {{ template "loki.name" . }}-runtime
+ {{- if .Values.enterprise.enabled }}
+ - name: license
+ secret:
+ {{- if .Values.enterprise.useExternalLicense }}
+ secretName: {{ .Values.enterprise.externalLicenseName }}
+ {{- else }}
+ secretName: enterprise-logs-license
+ {{- end }}
+ {{- end }}
+ {{- with .Values.write.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumeClaimTemplates:
+ - metadata:
+ name: data
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ {{- with .Values.write.persistence.storageClass }}
+ storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.write.persistence.size | quote }}
+ {{- with .Values.write.persistence.selector }}
+ selector:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/loki/values.yaml b/charts/loki/values.yaml
new file mode 100644
index 0000000..ac047d1
--- /dev/null
+++ b/charts/loki/values.yaml
@@ -0,0 +1,1301 @@
+---
+global:
+ image:
+ # -- Overrides the Docker registry globally for all images
+ registry: null
+ # -- Overrides the priorityClassName for all pods
+ priorityClassName: null
+ # -- configures cluster domain ("cluster.local" by default)
+ clusterDomain: "cluster.local"
+ # -- configures DNS service name
+ dnsService: "kube-dns"
+ # -- configures DNS service namespace
+ dnsNamespace: "kube-system"
+
+# -- Overrides the chart's name
+nameOverride: null
+
+# -- Overrides the chart's computed fullname
+fullnameOverride: null
+
+# -- Image pull secrets for Docker images
+imagePullSecrets: []
+
+kubectlImage:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: bitnami/kubectl
+ # -- Overrides the image tag whose default is the chart's appVersion
+ tag: null
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+
+loki:
+ # Configures the readiness probe for all of the Loki pods
+ readinessProbe:
+ httpGet:
+ path: /ready
+ port: http-metrics
+ initialDelaySeconds: 30
+ timeoutSeconds: 1
+ image:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: grafana/loki
+ # -- Overrides the image tag whose default is the chart's appVersion
+ # TODO: needed for 3rd target backend functionality
+ # revert to null or latest once this behavior is relased
+ tag: null
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+ # -- Common annotations for all pods
+ podAnnotations: {}
+ # -- Common labels for all pods
+ podLabels: {}
+ # -- The number of old ReplicaSets to retain to allow rollback
+ revisionHistoryLimit: 10
+ # -- The SecurityContext for Loki pods
+ podSecurityContext:
+ fsGroup: 10001
+ runAsGroup: 10001
+ runAsNonRoot: true
+ runAsUser: 10001
+ # -- The SecurityContext for Loki containers
+ containerSecurityContext:
+ readOnlyRootFilesystem: true
+ capabilities:
+ drop:
+ - ALL
+ allowPrivilegeEscalation: false
+ # -- Should enableServiceLinks be enabled. Default to enable
+ enableServiceLinks: true
+ # -- Specify an existing secret containing loki configuration. If non-empty, overrides `loki.config`
+ existingSecretForConfig: ""
+ # -- Config file contents for Loki
+ # @default -- See values.yaml
+ config: |
+ {{- if .Values.enterprise.enabled}}
+ {{- tpl .Values.enterprise.config . }}
+ {{- else }}
+ auth_enabled: {{ .Values.loki.auth_enabled }}
+ {{- end }}
+
+ {{- with .Values.loki.server }}
+ server:
+ {{- toYaml . | nindent 2}}
+ {{- end}}
+
+ memberlist:
+ join_members:
+ - {{ include "loki.memberlist" . }}
+ {{- with .Values.migrate.fromDistributed }}
+ {{- if .enabled }}
+ - {{ .memberlistService }}
+ {{- end }}
+ {{- end }}
+
+ {{- with .Values.loki.ingester }}
+ ingester:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ {{- if .Values.loki.commonConfig}}
+ common:
+ {{- toYaml .Values.loki.commonConfig | nindent 2}}
+ storage:
+ {{- include "loki.commonStorageConfig" . | nindent 4}}
+ {{- end}}
+
+ {{- with .Values.loki.limits_config }}
+ limits_config:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ runtime_config:
+ file: /etc/loki/runtime-config/runtime-config.yaml
+
+ {{- with .Values.loki.memcached.chunk_cache }}
+ {{- if and .enabled (or .host .addresses) }}
+ chunk_store_config:
+ chunk_cache_config:
+ memcached:
+ batch_size: {{ .batch_size }}
+ parallelism: {{ .parallelism }}
+ memcached_client:
+ {{- if .host }}
+ host: {{ .host }}
+ {{- end }}
+ {{- if .addresses }}
+ addresses: {{ .addresses }}
+ {{- end }}
+ service: {{ .service }}
+ {{- end }}
+ {{- end }}
+
+ {{- if .Values.loki.schemaConfig}}
+ schema_config:
+ {{- toYaml .Values.loki.schemaConfig | nindent 2}}
+ {{- else }}
+ schema_config:
+ configs:
+ - from: 2022-01-11
+ store: boltdb-shipper
+ object_store: {{ .Values.loki.storage.type }}
+ schema: v12
+ index:
+ prefix: loki_index_
+ period: 24h
+ {{- end }}
+
+ {{ include "loki.rulerConfig" . }}
+
+ table_manager:
+ retention_deletes_enabled: false
+ retention_period: 0
+
+ {{- with .Values.loki.memcached.results_cache }}
+ query_range:
+ align_queries_with_step: true
+ {{- if and .enabled (or .host .addresses) }}
+ cache_results: {{ .enabled }}
+ results_cache:
+ cache:
+ default_validity: {{ .default_validity }}
+ memcached_client:
+ {{- if .host }}
+ host: {{ .host }}
+ {{- end }}
+ {{- if .addresses }}
+ addresses: {{ .addresses }}
+ {{- end }}
+ service: {{ .service }}
+ timeout: {{ .timeout }}
+ {{- end }}
+ {{- end }}
+
+ {{- with .Values.loki.storage_config }}
+ storage_config:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ {{- with .Values.loki.query_scheduler }}
+ query_scheduler:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ {{- with .Values.loki.compactor }}
+ compactor:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ {{- with .Values.loki.analytics }}
+ analytics:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ {{- with .Values.loki.querier }}
+ querier:
+ {{- tpl (. | toYaml) $ | nindent 4 }}
+ {{- end }}
+
+ # Should authentication be enabled
+ auth_enabled: true
+
+ # -- Check https://grafana.com/docs/loki/latest/configuration/#server for more info on the server configuration.
+ server:
+ http_listen_port: 3100
+ grpc_listen_port: 9095
+
+ # -- Limits config
+ limits_config:
+ enforce_metric_name: false
+ reject_old_samples: true
+ reject_old_samples_max_age: 168h
+ max_cache_freshness_per_query: 10m
+ split_queries_by_interval: 15m
+
+ # -- Provides a reloadable runtime configuration file for some specific configuration
+ runtimeConfig: {}
+
+ # -- Check https://grafana.com/docs/loki/latest/configuration/#common_config for more info on how to provide a common configuration
+ commonConfig:
+ path_prefix: /var/loki
+ replication_factor: 3
+ compactor_address: '{{ include "loki.compactorAddress" . }}'
+
+ # -- Storage config. Providing this will automatically populate all necessary storage configs in the templated config.
+ storage:
+ bucketNames:
+ chunks: chunks
+ ruler: ruler
+ admin: admin
+ type: s3
+ s3:
+ s3: null
+ endpoint: null
+ region: null
+ secretAccessKey: null
+ accessKeyId: null
+ s3ForcePathStyle: false
+ insecure: false
+ http_config: {}
+ gcs:
+ chunkBufferSize: 0
+ requestTimeout: "0s"
+ enableHttp2: true
+ azure:
+ accountName: null
+ accountKey: null
+ useManagedIdentity: false
+ userAssignedId: null
+ requestTimeout: null
+ filesystem:
+ chunks_directory: /var/loki/chunks
+ rules_directory: /var/loki/rules
+
+ # -- Configure memcached as an external cache for chunk and results cache. Disabled by default
+ # must enable and specify a host for each cache you would like to use.
+ memcached:
+ chunk_cache:
+ enabled: false
+ host: ""
+ service: "memcached-client"
+ batch_size: 256
+ parallelism: 10
+ results_cache:
+ enabled: false
+ host: ""
+ service: "memcached-client"
+ timeout: "500ms"
+ default_validity: "12h"
+
+ # -- Check https://grafana.com/docs/loki/latest/configuration/#schema_config for more info on how to configure schemas
+ schemaConfig: {}
+
+ # -- Check https://grafana.com/docs/loki/latest/configuration/#ruler for more info on configuring ruler
+ rulerConfig: {}
+
+ # -- Structured loki configuration, takes precedence over `loki.config`, `loki.schemaConfig`, `loki.storageConfig`
+ structuredConfig: {}
+
+ # -- Additional query scheduler config
+ query_scheduler: {}
+
+ # -- Additional storage config
+ storage_config:
+ hedging:
+ at: "250ms"
+ max_per_second: 20
+ up_to: 3
+
+ # -- Optional compactor configuration
+ compactor: {}
+
+ # -- Optional analytics configuration
+ analytics: {}
+
+ # -- Optional querier configuration
+ querier: {}
+
+ # -- Optional ingester configuration
+ ingester: {}
+
+enterprise:
+ # Enable enterprise features, license must be provided
+ enabled: false
+
+ # Default verion of GEL to deploy
+ version: v1.6.1
+
+ # -- Optional name of the GEL cluster, otherwise will use .Release.Name
+ # The cluster name must match what is in your GEL license
+ cluster_name: null
+
+ # -- Grafana Enterprise Logs license
+ # In order to use Grafana Enterprise Logs features, you will need to provide
+ # the contents of your Grafana Enterprise Logs license, either by providing the
+ # contents of the license.jwt, or the name Kubernetes Secret that contains your
+ # license.jwt.
+ # To set the license contents, use the flag `--set-file 'license.contents=./license.jwt'`
+ license:
+ contents: "NOTAVALIDLICENSE"
+
+ # -- Set to true when providing an external license
+ useExternalLicense: false
+
+ # -- Name of external license secret to use
+ externalLicenseName: null
+
+ # -- Name of the external config secret to use
+ externalConfigName: ""
+
+ # -- If enabled, the correct admin_client storage will be configured. If disabled while running enterprise,
+ # make sure auth is set to `type: trust`, or that `auth_enabled` is set to `false`.
+ adminApi:
+ enabled: true
+
+ # enterprise specific sections of the config.yaml file
+ config: |
+ {{- if .Values.enterprise.adminApi.enabled }}
+ {{- if or .Values.minio.enabled (eq .Values.loki.storage.type "s3") (eq .Values.loki.storage.type "gcs") (eq .Values.loki.storage.type "azure") }}
+ admin_client:
+ storage:
+ s3:
+ bucket_name: {{ .Values.loki.storage.bucketNames.admin }}
+ {{- end }}
+ {{- end }}
+ auth:
+ type: {{ .Values.enterprise.adminApi.enabled | ternary "enterprise" "trust" }}
+ auth_enabled: {{ .Values.loki.auth_enabled }}
+ cluster_name: {{ include "loki.clusterName" . }}
+ license:
+ path: /etc/loki/license/license.jwt
+
+ image:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: grafana/enterprise-logs
+ # -- Docker image tag
+ # TODO: needed for 3rd target backend functionality
+ # revert to null or latest once this behavior is relased
+ tag: main-96f32b9f
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+
+ adminToken:
+ # -- Alternative name for admin token secret, needed by tokengen and provisioner jobs
+ secret: null
+ # -- Additional namespace to also create the token in. Useful if your Grafana instance
+ # is in a different namespace
+ additionalNamespaces: []
+
+ # -- Alternative name of the secret to store token for the canary
+ canarySecret: null
+
+ # -- Configuration for `tokengen` target
+ tokengen:
+ # -- Whether the job should be part of the deployment
+ enabled: true
+ # -- Comma-separated list of Loki modules to load for tokengen
+ targetModule: "tokengen"
+ # -- Additional CLI arguments for the `tokengen` target
+ extraArgs: []
+ # -- Additional Kubernetes environment
+ env: []
+ # -- Additional labels for the `tokengen` Job
+ labels: {}
+ # -- Additional annotations for the `tokengen` Job
+ annotations: {}
+ # -- Tolerations for tokengen Job
+ tolerations: []
+ # -- Additional volumes for Pods
+ extraVolumes: []
+ # -- Additional volume mounts for Pods
+ extraVolumeMounts: []
+ # -- Run containers as user `enterprise-logs(uid=10001)`
+ securityContext:
+ runAsNonRoot: true
+ runAsGroup: 10001
+ runAsUser: 10001
+ fsGroup: 10001
+ # -- Environment variables from secrets or configmaps to add to the tokengen pods
+ extraEnvFrom: []
+ # -- The name of the PriorityClass for tokengen Pods
+ priorityClassName: ""
+
+ # -- Configuration for `provisioner` target
+ provisioner:
+ # -- Whether the job should be part of the deployment
+ enabled: true
+ # -- Name of the secret to store provisioned tokens in
+ provisionedSecretPrefix: null
+ # -- Additional tenants to be created. Each tenant will get a read and write policy
+ # and associated token. Tenant must have a name and a namespace for the secret containting
+ # the token to be created in. For example
+ # additionalTenants:
+ # - name: loki
+ # secretNamespace: grafana
+ additionalTenants: []
+ # -- Additional Kubernetes environment
+ env: []
+ # -- Additional labels for the `provisioner` Job
+ labels: {}
+ # -- Additional annotations for the `provisioner` Job
+ annotations: {}
+ # -- The name of the PriorityClass for provisioner Job
+ priorityClassName: null
+ # -- Run containers as user `enterprise-logs(uid=10001)`
+ securityContext:
+ runAsNonRoot: true
+ runAsGroup: 10001
+ runAsUser: 10001
+ fsGroup: 10001
+ # -- Provisioner image to Utilize
+ image:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: grafana/enterprise-logs-provisioner
+ # -- Overrides the image tag whose default is the chart's appVersion
+ tag: null
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+ # -- Volume mounts to add to the provisioner pods
+ extraVolumeMounts: []
+
+# -- Options that may be necessary when performing a migration from another helm chart
+migrate:
+ # -- When migrating from a distributed chart like loki-distributed or enterprise-logs
+ fromDistributed:
+ # -- Set to true if migrating from a distributed helm chart
+ enabled: false
+ # -- If migrating from a distributed service, provide the distributed deployment's
+ # memberlist service DNS so the new deployment can join it's ring.
+ memberlistService: ""
+
+serviceAccount:
+ # -- Specifies whether a ServiceAccount should be created
+ create: true
+ # -- The name of the ServiceAccount to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: null
+ # -- Image pull secrets for the service account
+ imagePullSecrets: []
+ # -- Annotations for the service account
+ annotations: {}
+ # -- Labels for the service account
+ labels: {}
+ # -- Set this toggle to false to opt out of automounting API credentials for the service account
+ automountServiceAccountToken: true
+
+# RBAC configuration
+rbac:
+ # -- If pspEnabled true, a PodSecurityPolicy is created for K8s that use psp.
+ pspEnabled: false
+ # -- For OpenShift set pspEnabled to 'false' and sccEnabled to 'true' to use the SecurityContextConstraints.
+ sccEnabled: false
+
+# -- Section for configuring optional Helm test
+test:
+ enabled: true
+ # -- Address of the prometheus server to query for the test
+ prometheusAddress: "http://prometheus:9090"
+ # -- Number of times to retry the test before failing
+ timeout: 1m
+ # -- Additional labels for the test pods
+ labels: {}
+ # -- Additional annotations for test pods
+ annotations: {}
+ # -- Image to use for loki canary
+ image:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: grafana/loki-helm-test
+ # -- Overrides the image tag whose default is the chart's appVersion
+ tag: null
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+
+# Monitoring section determines which monitoring features to enable
+monitoring:
+ # Dashboards for monitoring Loki
+ dashboards:
+ # -- If enabled, create configmap with dashboards for monitoring Loki
+ enabled: true
+ # -- Alternative namespace to create dashboards ConfigMap in
+ namespace: null
+ # -- Additional annotations for the dashboards ConfigMap
+ annotations: {}
+ # -- Labels for the dashboards ConfigMap
+ labels:
+ grafana_dashboard: "1"
+
+ # Recording rules for monitoring Loki, required for some dashboards
+ rules:
+ # -- If enabled, create PrometheusRule resource with Loki recording rules
+ enabled: true
+ # -- Include alerting rules
+ alerting: true
+ # -- Alternative namespace to create PrometheusRule resources in
+ namespace: null
+ # -- Additional annotations for the rules PrometheusRule resource
+ annotations: {}
+ # -- Additional labels for the rules PrometheusRule resource
+ labels: {}
+ # -- Additional groups to add to the rules file
+ additionalGroups: []
+ # - name: additional-loki-rules
+ # rules:
+ # - record: job:loki_request_duration_seconds_bucket:sum_rate
+ # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job)
+ # - record: job_route:loki_request_duration_seconds_bucket:sum_rate
+ # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route)
+ # - record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate
+ # expr: sum(rate(container_cpu_usage_seconds_total[1m])) by (node, namespace, pod, container)
+
+ # ServiceMonitor configuration
+ serviceMonitor:
+ # -- If enabled, ServiceMonitor resources for Prometheus Operator are created
+ enabled: true
+ # -- Namespace selector for ServiceMonitor resources
+ namespaceSelector: {}
+ # -- ServiceMonitor annotations
+ annotations: {}
+ # -- Additional ServiceMonitor labels
+ labels: {}
+ # -- ServiceMonitor scrape interval
+ interval: null
+ # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s)
+ scrapeTimeout: null
+ # -- ServiceMonitor relabel configs to apply to samples before scraping
+ # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig
+ relabelings: []
+ # -- ServiceMonitor will use http by default, but you can pick https as well
+ scheme: http
+ # -- ServiceMonitor will use these tlsConfig settings to make the health check requests
+ tlsConfig: null
+ # -- If defined, will create a MetricsInstance for the Grafana Agent Operator.
+ metricsInstance:
+ # -- If enabled, MetricsInstance resources for Grafana Agent Operator are created
+ enabled: true
+ # -- MetricsInstance annotations
+ annotations: {}
+ # -- Additional MetricsInstance labels
+ labels: {}
+ # -- If defined a MetricsInstance will be created to remote write metrics.
+ remoteWrite: null
+
+ # Self monitoring determines whether Loki should scrape it's own logs.
+ # This feature currently relies on the Grafana Agent Operator being installed,
+ # which is installed by default using the grafana-agent-operator sub-chart.
+ # It will create custom resources for GrafanaAgent, LogsInstance, and PodLogs to configure
+ # scrape configs to scrape it's own logs with the labels expected by the included dashboards.
+ selfMonitoring:
+ enabled: true
+
+ # -- Tenant to use for self monitoring
+ tenant:
+ # -- Name of the tenant
+ name: "self-monitoring"
+ # -- Namespace to create additional tenant token secret in. Useful if your Grafana instance
+ # is in a separate namespace. Token will still be created in the canary namespace.
+ secretNamespace: "{{ .Release.Namespace }}"
+
+ # Grafana Agent configuration
+ grafanaAgent:
+ # -- Controls whether to install the Grafana Agent Operator and its CRDs.
+ # Note that helm will not install CRDs if this flag is enabled during an upgrade.
+ # In that case install the CRDs manually from https://github.com/grafana/agent/tree/main/production/operator/crds
+ installOperator: true
+ # -- Grafana Agent annotations
+ annotations: {}
+ # -- Additional Grafana Agent labels
+ labels: {}
+ # -- Enable the config read api on port 8080 of the agent
+ enableConfigReadAPI: false
+
+ # PodLogs configuration
+ podLogs:
+ # -- PodLogs annotations
+ annotations: {}
+ # -- Additional PodLogs labels
+ labels: {}
+ # -- PodLogs relabel configs to apply to samples before scraping
+ # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig
+ relabelings: []
+
+ # LogsInstance configuration
+ logsInstance:
+ # -- LogsInstance annotations
+ annotations: {}
+ # -- Additional LogsInstance labels
+ labels: {}
+ # -- Additional clients for remote write
+ clients: null
+
+ # The Loki canary pushes logs to and queries from this loki installation to test
+ # that it's working correctly
+ lokiCanary:
+ enabled: true
+ # -- Additional annotations for the `loki-canary` Daemonset
+ annotations: {}
+ # -- Additional CLI arguments for the `loki-canary' command
+ extraArgs: []
+ # -- Environment variables to add to the canary pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the canary pods
+ extraEnvFrom: []
+ # -- Resource requests and limits for the canary
+ resources: {}
+ # -- Node selector for canary pods
+ nodeSelector: {}
+ # -- Tolerations for canary pods
+ tolerations: []
+ # -- Image to use for loki canary
+ image:
+ # -- The Docker registry
+ registry: docker.io
+ # -- Docker image repository
+ repository: grafana/loki-canary
+ # -- Overrides the image tag whose default is the chart's appVersion
+ tag: null
+ # -- Docker image pull policy
+ pullPolicy: IfNotPresent
+
+# Configuration for the write pod(s)
+write:
+ # -- Number of replicas for the write
+ replicas: 3
+ image:
+ # -- The Docker registry for the write image. Overrides `loki.image.registry`
+ registry: null
+ # -- Docker image repository for the write image. Overrides `loki.image.repository`
+ repository: null
+ # -- Docker image tag for the write image. Overrides `loki.image.tag`
+ tag: null
+ # -- The name of the PriorityClass for write pods
+ priorityClassName: null
+ # -- Annotations for write pods
+ podAnnotations: {}
+ # -- Additional labels for each `write` pod
+ podLabels: {}
+ # -- Additional selector labels for each `write` pod
+ selectorLabels: {}
+ # -- Labels for ingester service
+ serviceLabels: {}
+ # -- Comma-separated list of Loki modules to load for the write
+ targetModule: "write"
+ # -- Additional CLI args for the write
+ extraArgs: []
+ # -- Environment variables to add to the write pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the write pods
+ extraEnvFrom: []
+ # -- Lifecycle for the write container
+ lifecycle: {}
+ # -- Init containers to add to the write pods
+ initContainers: []
+ # -- Volume mounts to add to the write pods
+ extraVolumeMounts: []
+ # -- Volumes to add to the write pods
+ extraVolumes: []
+ # -- Resource requests and limits for the write
+ resources: {}
+ # -- Grace period to allow the write to shutdown before it is killed. Especially for the ingester,
+ # this must be increased. It must be long enough so writes can be gracefully shutdown flushing/transferring
+ # all data and to successfully leave the member ring on shutdown.
+ terminationGracePeriodSeconds: 300
+ # -- Affinity for write pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.writeSelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ # -- Node selector for write pods
+ nodeSelector: {}
+ # -- Tolerations for write pods
+ tolerations: []
+ persistence:
+ # -- Enable StatefulSetAutoDeletePVC feature
+ enableStatefulSetAutoDeletePVC: false
+ # -- Size of persistent disk
+ size: 10Gi
+ # -- Storage class to be used.
+ # If defined, storageClassName: <storageClass>.
+ # If set to "-", storageClassName: "", which disables dynamic provisioning.
+ # If empty or set to null, no storageClassName spec is
+ # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack).
+ storageClass: null
+ # -- Selector for persistent disk
+ selector: null
+
+# Configuration for the table-manager
+tableManager:
+ # -- Specifies whether the table-manager should be enabled
+ enabled: false
+ image:
+ # -- The Docker registry for the table-manager image. Overrides `loki.image.registry`
+ registry: null
+ # -- Docker image repository for the table-manager image. Overrides `loki.image.repository`
+ repository: null
+ # -- Docker image tag for the table-manager image. Overrides `loki.image.tag`
+ tag: null
+ # -- Command to execute instead of defined in Docker image
+ command: null
+ # -- The name of the PriorityClass for table-manager pods
+ priorityClassName: null
+ # -- Labels for table-manager pods
+ podLabels: {}
+ # -- Annotations for table-manager pods
+ podAnnotations: {}
+ # -- Labels for table-manager service
+ serviceLabels: {}
+ # -- Additional CLI args for the table-manager
+ extraArgs: []
+ # -- Environment variables to add to the table-manager pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the table-manager pods
+ extraEnvFrom: []
+ # -- Volume mounts to add to the table-manager pods
+ extraVolumeMounts: []
+ # -- Volumes to add to the table-manager pods
+ extraVolumes: []
+ # -- Resource requests and limits for the table-manager
+ resources: {}
+ # -- Containers to add to the table-manager pods
+ extraContainers: []
+ # -- Grace period to allow the table-manager to shutdown before it is killed
+ terminationGracePeriodSeconds: 30
+ # -- Affinity for table-manager pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.tableManagerSelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchLabels:
+ {{- include "loki.tableManagerSelectorLabels" . | nindent 12 }}
+ topologyKey: failure-domain.beta.kubernetes.io/zone
+ # -- Node selector for table-manager pods
+ nodeSelector: {}
+ # -- Tolerations for table-manager pods
+ tolerations: []
+
+# Configuration for the read pod(s)
+read:
+ # -- Number of replicas for the read
+ replicas: 3
+ autoscaling:
+ # -- Enable autoscaling for the read, this is only used if `queryIndex.enabled: true`
+ enabled: false
+ # -- Minimum autoscaling replicas for the read
+ minReplicas: 1
+ # -- Maximum autoscaling replicas for the read
+ maxReplicas: 3
+ # -- Target CPU utilisation percentage for the read
+ targetCPUUtilizationPercentage: 60
+ # -- Target memory utilisation percentage for the read
+ targetMemoryUtilizationPercentage:
+ image:
+ # -- The Docker registry for the read image. Overrides `loki.image.registry`
+ registry: null
+ # -- Docker image repository for the read image. Overrides `loki.image.repository`
+ repository: null
+ # -- Docker image tag for the read image. Overrides `loki.image.tag`
+ tag: null
+ # -- The name of the PriorityClass for read pods
+ priorityClassName: null
+ # -- Annotations for read pods
+ podAnnotations: {}
+ # -- Additional labels for each `read` pod
+ podLabels: {}
+ # -- Additional selector labels for each `read` pod
+ selectorLabels: {}
+ # -- Labels for read service
+ serviceLabels: {}
+ # -- Comma-separated list of Loki modules to load for the read
+ targetModule: "read"
+ # -- Whether or not to use the 2 target type simple scalable mode (read, write) or the
+ # 3 target type (read, write, backend). Legacy refers to the 2 target type, so true will
+ # run two targets, false will run 3 targets.
+ legacyReadTarget: true
+ # -- Additional CLI args for the read
+ extraArgs: []
+ # -- Environment variables to add to the read pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the read pods
+ extraEnvFrom: []
+ # -- Lifecycle for the read container
+ lifecycle: {}
+ # -- Volume mounts to add to the read pods
+ extraVolumeMounts: []
+ # -- Volumes to add to the read pods
+ extraVolumes: []
+ # -- Resource requests and limits for the read
+ resources: {}
+ # -- Grace period to allow the read to shutdown before it is killed
+ terminationGracePeriodSeconds: 30
+ # -- Affinity for read pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.readSelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ # -- Node selector for read pods
+ nodeSelector: {}
+ # -- Tolerations for read pods
+ tolerations: []
+ persistence:
+ # -- Enable StatefulSetAutoDeletePVC feature
+ enableStatefulSetAutoDeletePVC: true
+ # -- Size of persistent disk
+ size: 10Gi
+ # -- Storage class to be used.
+ # If defined, storageClassName: <storageClass>.
+ # If set to "-", storageClassName: "", which disables dynamic provisioning.
+ # If empty or set to null, no storageClassName spec is
+ # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack).
+ storageClass: null
+ # -- Selector for persistent disk
+ selector: null
+
+# Configuration for the backend pod(s)
+backend:
+ # -- Number of replicas for the backend
+ replicas: 3
+ image:
+ # -- The Docker registry for the backend image. Overrides `loki.image.registry`
+ registry: null
+ # -- Docker image repository for the backend image. Overrides `loki.image.repository`
+ repository: null
+ # -- Docker image tag for the backend image. Overrides `loki.image.tag`
+ tag: null
+ # -- The name of the PriorityClass for backend pods
+ priorityClassName: null
+ # -- Annotations for backend pods
+ podAnnotations: {}
+ # -- Additional labels for each `backend` pod
+ podLabels: {}
+ # -- Additional selector labels for each `backend` pod
+ selectorLabels: {}
+ # -- Labels for ingester service
+ serviceLabels: {}
+ # -- Comma-separated list of Loki modules to load for the read
+ targetModule: "backend"
+ # -- Additional CLI args for the backend
+ extraArgs: []
+ # -- Environment variables to add to the backend pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the backend pods
+ extraEnvFrom: []
+ # -- Init containers to add to the backend pods
+ initContainers: []
+ # -- Volume mounts to add to the backend pods
+ extraVolumeMounts: []
+ # -- Volumes to add to the backend pods
+ extraVolumes: []
+ # -- Resource requests and limits for the backend
+ resources: {}
+ # -- Grace period to allow the backend to shutdown before it is killed. Especially for the ingester,
+ # this must be increased. It must be long enough so backends can be gracefully shutdown flushing/transferring
+ # all data and to successfully leave the member ring on shutdown.
+ terminationGracePeriodSeconds: 300
+ # -- Affinity for backend pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.backendSelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ # -- Node selector for backend pods
+ nodeSelector: {}
+ # -- Tolerations for backend pods
+ tolerations: []
+ persistence:
+ # -- Enable StatefulSetAutoDeletePVC feature
+ enableStatefulSetAutoDeletePVC: true
+ # -- Size of persistent disk
+ size: 10Gi
+ # -- Storage class to be used.
+ # If defined, storageClassName: <storageClass>.
+ # If set to "-", storageClassName: "", which disables dynamic provisioning.
+ # If empty or set to null, no storageClassName spec is
+ # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack).
+ storageClass: null
+ # -- Selector for persistent disk
+ selector: null
+
+# Configuration for the single binary node(s)
+singleBinary:
+ # -- Number of replicas for the single binary
+ replicas: 0
+ autoscaling:
+ # -- Enable autoscaling, this is only used if `queryIndex.enabled: true`
+ enabled: false
+ # -- Minimum autoscaling replicas for the single binary
+ minReplicas: 1
+ # -- Maximum autoscaling replicas for the single binary
+ maxReplicas: 3
+ # -- Target CPU utilisation percentage for the single binary
+ targetCPUUtilizationPercentage: 60
+ # -- Target memory utilisation percentage for the single binary
+ targetMemoryUtilizationPercentage:
+ image:
+ # -- The Docker registry for the single binary image. Overrides `loki.image.registry`
+ registry: null
+ # -- Docker image repository for the single binary image. Overrides `loki.image.repository`
+ repository: null
+ # -- Docker image tag for the single binary image. Overrides `loki.image.tag`
+ tag: null
+ # -- The name of the PriorityClass for single binary pods
+ priorityClassName: null
+ # -- Annotations for single binary pods
+ podAnnotations: {}
+ # -- Additional labels for each `single binary` pod
+ podLabels: {}
+ # -- Additional selector labels for each `single binary` pod
+ selectorLabels: {}
+ # -- Comma-separated list of Loki modules to load for the single binary
+ targetModule: "all"
+ # -- Labels for single binary service
+ extraArgs: []
+ # -- Environment variables to add to the single binary pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the single binary pods
+ extraEnvFrom: []
+ # -- Init containers to add to the single binary pods
+ initContainers: []
+ # -- Volume mounts to add to the single binary pods
+ extraVolumeMounts: []
+ # -- Volumes to add to the single binary pods
+ extraVolumes: []
+ # -- Resource requests and limits for the single binary
+ resources: {}
+ # -- Grace period to allow the single binary to shutdown before it is killed
+ terminationGracePeriodSeconds: 30
+ # -- Affinity for single binary pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.singleBinarySelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ # -- Node selector for single binary pods
+ nodeSelector: {}
+ # -- Tolerations for single binary pods
+ tolerations: []
+ persistence:
+ # -- Enable StatefulSetAutoDeletePVC feature
+ enableStatefulSetAutoDeletePVC: true
+ # -- Enable persistent disk
+ enabled: true
+ # -- Size of persistent disk
+ size: 10Gi
+ # -- Storage class to be used.
+ # If defined, storageClassName: <storageClass>.
+ # If set to "-", storageClassName: "", which disables dynamic provisioning.
+ # If empty or set to null, no storageClassName spec is
+ # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack).
+ storageClass: null
+ # -- Selector for persistent disk
+ selector: null
+
+# Use either this ingress or the gateway, but not both at once.
+# If you enable this, make sure to disable the gateway.
+# You'll need to supply authn configuration for your ingress controller.
+ingress:
+ enabled: false
+ ingressClassName: ""
+ annotations: {}
+ # nginx.ingress.kubernetes.io/auth-type: basic
+ # nginx.ingress.kubernetes.io/auth-secret: loki-distributed-basic-auth
+ # nginx.ingress.kubernetes.io/auth-secret-type: auth-map
+ # nginx.ingress.kubernetes.io/configuration-snippet: |
+ # proxy_set_header X-Scope-OrgID $remote_user;
+ paths:
+ write:
+ - /api/prom/push
+ - /loki/api/v1/push
+ read:
+ - /api/prom/tail
+ - /loki/api/v1/tail
+ - /loki/api
+ - /api/prom/rules
+ - /loki/api/v1/rules
+ - /prometheus/api/v1/rules
+ - /prometheus/api/v1/alerts
+ singleBinary:
+ - /api/prom/push
+ - /loki/api/v1/push
+ - /api/prom/tail
+ - /loki/api/v1/tail
+ - /loki/api
+ - /api/prom/rules
+ - /loki/api/v1/rules
+ - /prometheus/api/v1/rules
+ - /prometheus/api/v1/alerts
+
+ hosts:
+ - loki.example.com
+ tls: []
+# - hosts:
+# - loki.example.com
+# secretName: loki-distributed-tls
+
+# Configuration for the memberlist service
+memberlist:
+ service:
+ publishNotReadyAddresses: false
+
+# Configuration for the gateway
+gateway:
+ # -- Specifies whether the gateway should be enabled
+ enabled: true
+ # -- Number of replicas for the gateway
+ replicas: 1
+ # -- Enable logging of 2xx and 3xx HTTP requests
+ verboseLogging: true
+ autoscaling:
+ # -- Enable autoscaling for the gateway
+ enabled: false
+ # -- Minimum autoscaling replicas for the gateway
+ minReplicas: 1
+ # -- Maximum autoscaling replicas for the gateway
+ maxReplicas: 3
+ # -- Target CPU utilisation percentage for the gateway
+ targetCPUUtilizationPercentage: 60
+ # -- Target memory utilisation percentage for the gateway
+ targetMemoryUtilizationPercentage:
+ # -- See `kubectl explain deployment.spec.strategy` for more
+ # -- ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
+ deploymentStrategy:
+ type: RollingUpdate
+ image:
+ # -- The Docker registry for the gateway image
+ registry: docker.io
+ # -- The gateway image repository
+ repository: nginxinc/nginx-unprivileged
+ # -- The gateway image tag
+ tag: 1.19-alpine
+ # -- The gateway image pull policy
+ pullPolicy: IfNotPresent
+ # -- The name of the PriorityClass for gateway pods
+ priorityClassName: null
+ # -- Annotations for gateway pods
+ podAnnotations: {}
+ # -- Additional labels for gateway pods
+ podLabels: {}
+ # -- Additional CLI args for the gateway
+ extraArgs: []
+ # -- Environment variables to add to the gateway pods
+ extraEnv: []
+ # -- Environment variables from secrets or configmaps to add to the gateway pods
+ extraEnvFrom: []
+ # -- Lifecycle for the gateway container
+ lifecycle: {}
+ # -- Volumes to add to the gateway pods
+ extraVolumes: []
+ # -- Volume mounts to add to the gateway pods
+ extraVolumeMounts: []
+ # -- The SecurityContext for gateway containers
+ podSecurityContext:
+ fsGroup: 101
+ runAsGroup: 101
+ runAsNonRoot: true
+ runAsUser: 101
+ # -- The SecurityContext for gateway containers
+ containerSecurityContext:
+ readOnlyRootFilesystem: true
+ capabilities:
+ drop:
+ - ALL
+ allowPrivilegeEscalation: false
+ # -- Resource requests and limits for the gateway
+ resources: {}
+ # -- Grace period to allow the gateway to shutdown before it is killed
+ terminationGracePeriodSeconds: 30
+ # -- Affinity for gateway pods. Passed through `tpl` and, thus, to be configured as string
+ # @default -- Hard node and soft zone anti-affinity
+ affinity: |
+ podAntiAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchLabels:
+ {{- include "loki.gatewaySelectorLabels" . | nindent 10 }}
+ topologyKey: kubernetes.io/hostname
+ # -- Node selector for gateway pods
+ nodeSelector: {}
+ # -- Tolerations for gateway pods
+ tolerations: []
+ # Gateway service configuration
+ service:
+ # -- Port of the gateway service
+ port: 80
+ # -- Type of the gateway service
+ type: ClusterIP
+ # -- ClusterIP of the gateway service
+ clusterIP: null
+ # -- (int) Node port if service type is NodePort
+ nodePort: null
+ # -- Load balancer IPO address if service type is LoadBalancer
+ loadBalancerIP: null
+ # -- Annotations for the gateway service
+ annotations: {}
+ # -- Labels for gateway service
+ labels: {}
+ # Gateway ingress configuration
+ ingress:
+ # -- Specifies whether an ingress for the gateway should be created
+ enabled: false
+ # -- Ingress Class Name. MAY be required for Kubernetes versions >= 1.18
+ ingressClassName: ""
+ # -- Annotations for the gateway ingress
+ annotations: {}
+ # -- Hosts configuration for the gateway ingress
+ hosts:
+ - host: gateway.loki.example.com
+ paths:
+ - path: /
+ # -- pathType (e.g. ImplementationSpecific, Prefix, .. etc.) might also be required by some Ingress Controllers
+ # pathType: Prefix
+ # -- TLS configuration for the gateway ingress
+ tls:
+ - secretName: loki-gateway-tls
+ hosts:
+ - gateway.loki.example.com
+ # Basic auth configuration
+ basicAuth:
+ # -- Enables basic authentication for the gateway
+ enabled: false
+ # -- The basic auth username for the gateway
+ username: null
+ # -- The basic auth password for the gateway
+ password: null
+ # -- Uses the specified username and password to compute a htpasswd using Sprig's `htpasswd` function.
+ # The value is templated using `tpl`. Override this to use a custom htpasswd, e.g. in case the default causes
+ # high CPU load.
+ htpasswd: >-
+ {{ htpasswd (required "'gateway.basicAuth.username' is required" .Values.gateway.basicAuth.username) (required "'gateway.basicAuth.password' is required" .Values.gateway.basicAuth.password) }}
+
+ # -- Existing basic auth secret to use. Must contain '.htpasswd'
+ existingSecret: null
+ # Configures the readiness probe for the gateway
+ readinessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 15
+ timeoutSeconds: 1
+ nginxConfig:
+ # -- NGINX log format
+ logFormat: |-
+ main '$remote_addr - $remote_user [$time_local] $status '
+ '"$request" $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+ # -- Allows appending custom configuration to the server block
+ serverSnippet: ""
+ # -- Allows appending custom configuration to the http block
+ httpSnippet: ""
+ # -- Override Read URL
+ customReadUrl: null
+ # -- Override Write URL
+ customWriteUrl: null
+ # -- Override Backend URL
+ customBackendUrl: null
+ # -- Config file contents for Nginx. Passed through the `tpl` function to allow templating
+ # @default -- See values.yaml
+ file: |
+ {{- include "loki.nginxFile" . | indent 2 -}}
+networkPolicy:
+ # -- Specifies whether Network Policies should be created
+ enabled: false
+ metrics:
+ # -- Specifies the Pods which are allowed to access the metrics port.
+ # As this is cross-namespace communication, you also need the namespaceSelector.
+ podSelector: {}
+ # -- Specifies the namespaces which are allowed to access the metrics port
+ namespaceSelector: {}
+ # -- Specifies specific network CIDRs which are allowed to access the metrics port.
+ # In case you use namespaceSelector, you also have to specify your kubelet networks here.
+ # The metrics ports are also used for probes.
+ cidrs: []
+ ingress:
+ # -- Specifies the Pods which are allowed to access the http port.
+ # As this is cross-namespace communication, you also need the namespaceSelector.
+ podSelector: {}
+ # -- Specifies the namespaces which are allowed to access the http port
+ namespaceSelector: {}
+ alertmanager:
+ # -- Specify the alertmanager port used for alerting
+ port: 9093
+ # -- Specifies the alertmanager Pods.
+ # As this is cross-namespace communication, you also need the namespaceSelector.
+ podSelector: {}
+ # -- Specifies the namespace the alertmanager is running in
+ namespaceSelector: {}
+ externalStorage:
+ # -- Specify the port used for external storage, e.g. AWS S3
+ ports: []
+ # -- Specifies specific network CIDRs you want to limit access to
+ cidrs: []
+ discovery:
+ # -- (int) Specify the port used for discovery
+ port: null
+ # -- Specifies the Pods labels used for discovery.
+ # As this is cross-namespace communication, you also need the namespaceSelector.
+ podSelector: {}
+ # -- Specifies the namespace the discovery Pods are running in
+ namespaceSelector: {}
+
+tracing:
+ jaegerAgentHost: ""
+
+# -------------------------------------
+# Configuration for `minio` child chart
+# -------------------------------------
+minio:
+ enabled: false
+ replicas: 1
+ # Minio requires 2 to 16 drives for erasure code (drivesPerNode * replicas)
+ # https://docs.min.io/docs/minio-erasure-code-quickstart-guide
+ # Since we only have 1 replica, that means 2 drives must be used.
+ drivesPerNode: 2
+ rootUser: enterprise-logs
+ rootPassword: supersecret
+ buckets:
+ - name: chunks
+ policy: none
+ purge: false
+ - name: ruler
+ policy: none
+ purge: false
+ - name: admin
+ policy: none
+ purge: false
+ persistence:
+ size: 5Gi
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+
+# Create extra manifests via values. Would be passed through `tpl` for templating
+extraObjects: []
+# - apiVersion: v1
+# kind: ConfigMap
+# metadata:
+# name: loki-alerting-rules
+# data:
+# loki-alerting-rules.yaml: |-
+# groups:
+# - name: example
+# rules:
+# - alert: example
+# expr: |
+# sum(count_over_time({app="loki"} |~ "error")) > 0
+# for: 3m
+# labels:
+# severity: warning
+# category: logs
+# annotations:
+# message: "loki has encountered errors"
diff --git a/charts/vector/.helmignore b/charts/vector/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/charts/vector/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/vector/Chart.yaml b/charts/vector/Chart.yaml
new file mode 100644
index 0000000..be62c86
--- /dev/null
+++ b/charts/vector/Chart.yaml
@@ -0,0 +1,32 @@
+annotations:
+ artifacthub.io/images: |
+ - name: vector
+ image: timberio/vector:0.27.0-distroless-libc
+ - name: haproxy
+ image: haproxytech/haproxy-alpine:2.4.17
+ artifacthub.io/license: MPL-2.0
+ artifacthub.io/links: |
+ - name: Chart Source
+ url: https://github.com/vectordotdev/helm-charts
+ artifacthub.io/prerelease: "false"
+apiVersion: v2
+appVersion: 0.27.0-distroless-libc
+description: A lightweight, ultra-fast tool for building observability pipelines
+home: https://vector.dev/
+icon: https://vector.dev/press/vector-icon.svg
+keywords:
+- vector
+- events
+- logs
+- metrics
+- observability
+- stream-processing
+kubeVersion: '>=1.15.0-0'
+maintainers:
+- email: vector@datadoghq.com
+ name: Datadog
+name: vector
+sources:
+- https://github.com/vectordotdev/vector/
+type: application
+version: 0.19.0
diff --git a/charts/vector/README.md b/charts/vector/README.md
new file mode 100644
index 0000000..70036af
--- /dev/null
+++ b/charts/vector/README.md
@@ -0,0 +1,265 @@
+# Vector
+
+  
+
+[Vector](https://vector.dev/) is a high-performance, end-to-end observability data pipeline that puts you in control of your observability data. Collect, transform, and route all your logs, metrics, and traces to any vendors you want today and any other vendors you may want tomorrow. Vector enables dramatic cost reduction, novel data enrichment, and data security where you need it, not where is most convenient for your vendors.
+
+## How to use Vector Helm repository
+
+You need to add this repository to your Helm repositories:
+
+```
+helm repo add vector https://helm.vector.dev
+helm repo update
+```
+
+## Requirements
+
+Kubernetes: `>=1.15.0-0`
+
+## Quick start
+
+By default, Vector runs as a `StatefulSet` in the "Aggregator" role. It can alternatively run as a `Deployment` for the "Stateless-Aggregator" role or a `DaemonSet` for the "Agent" role.
+
+### Installing the Vector chart
+
+To install the chart with the release name `<RELEASE_NAME>` run:
+
+```bash
+helm install --name <RELEASE_NAME> \
+ vector/vector
+```
+
+### Upgrading
+
+#### From original charts
+
+* [Migrate from the `vector-agent` chart](docs/Migrate_from_vector-agent.md)
+* [Migrate from the `vector-aggregator` chart](docs/Migrate_from_vector-aggregator.md)
+
+### Uninstalling the chart
+
+To uninstall/delete the `<RELEASE_NAME>` deployment:
+
+```bash
+helm delete <RELEASE_NAME>
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Configuration
+
+1. Using our [`default-values.yaml`](values.yaml) configuration file as a reference, create your own `values.yaml`.
+2. Upgrade the Vector chart with your new `values.yaml` file:
+
+```bash
+helm upgrade -f values.yaml <RELEASE_NAME> vector/vector
+```
+
+**Vector recommends that your `values.yaml` only contain values that need to be overridden, as it allows a smoother experience when upgrading chart versions.**
+
+See the [configuration options](#all-configuration-options) section to discover all possibilities offered by the Vector chart.
+
+### Running on control plane nodes
+
+Depending on your Kubernetes distribution, you may need to configure `tolerations` to run Vector on nodes acting as the control plane.
+
+For example to run Vector on [Openshift](https://www.redhat.com/en/technologies/cloud-computing/openshift) control plane nodes you can set:
+
+```yaml
+tolerations:
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/master
+ operator: Exists
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/infra
+ operator: Exists
+```
+
+Or for [RKE](https://rancher.com/products/rke) control plane nodes set:
+
+```yaml
+tolerations:
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/controlplane
+ operator: Exists
+ - effect: NoExecute
+ key: node-role.kubernetes.io/etcd
+ operator: Exists
+```
+
+### Using template syntax in `customConfig`
+
+As Vector's [template syntax](https://vector.dev/docs/reference/configuration/template-syntax/) shares the same syntax as Helm templates, explicit handling is required
+if you are using Vector's template syntax in the `customConfig` option. To avoid Helm templating configuration intended for Vector you can supply configuration like so:
+
+```yaml
+customConfig:
+ #...
+ sinks:
+ loki:
+ #...
+ labels:
+ foo: bar
+ host: |-
+ {{ print "{{ host }}" }}
+ source: |-
+ {{ print "{{ source_type }}" }}
+```
+
+## All configuration options
+
+The following table lists the configurable parameters of the Vector chart and their default values. Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
+
+```bash
+helm install --name <RELEASE_NAME> \
+ --set role=Agent \
+ vector/vector
+```
+
+## Values
+
+### Vector values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| affinity | object | `{}` | Configure [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) rules for Vector Pods. |
+| args | list | `["--config-dir","/etc/vector/"]` | Override Vector's default arguments. |
+| autoscaling.behavior | object | `{}` | Configure separate scale-up and scale-down behaviors. |
+| autoscaling.customMetric | object | `{}` | Target a custom metric for autoscaling. |
+| autoscaling.enabled | bool | `false` | Create a [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) for Vector. Valid for the "Aggregator" and "Stateless-Aggregator" roles. |
+| autoscaling.maxReplicas | int | `10` | Maximum replicas for Vector's HPA. |
+| autoscaling.minReplicas | int | `1` | Minimum replicas for Vector's HPA. |
+| autoscaling.targetCPUUtilizationPercentage | int | `80` | Target CPU utilization for Vector's HPA. |
+| autoscaling.targetMemoryUtilizationPercentage | int | `nil` | Target memory utilization for Vector's HPA. |
+| command | list | `[]` | Override Vector's default command. |
+| commonLabels | object | `{}` | Add additional labels to all created resources. |
+| containerPorts | list | `[]` | Manually define Vector's containerPorts, overriding automated generation of containerPorts. |
+| customConfig | object | `{}` | Override Vector's default configs, if used **all** options need to be specified. This section supports using helm templates to populate dynamic values. See Vector's [configuration documentation](https://vector.dev/docs/reference/configuration/) for all options. |
+| dataDir | string | `""` | Specify the path for Vector's data, only used when existingConfigMaps are used. |
+| dnsConfig | object | `{}` | Specify the [dnsConfig](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config) options for Vector Pods. |
+| dnsPolicy | string | `"ClusterFirst"` | Specify the [dnsPolicy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy) for Vector Pods. |
+| env | list | `[]` | Set environment variables for Vector containers. |
+| envFrom | list | `[]` | Define environment variables from Secrets or ConfigMaps. |
+| existingConfigMaps | list | `[]` | List of existing ConfigMaps for Vector's configuration instead of creating a new one. Requires dataDir to be set. Additionally, containerPorts, service.ports, and serviceHeadless.ports should be specified based on your supplied configuration. If set, this parameter takes precedence over customConfig and the chart's default configs. |
+| extraContainers | list | `[]` | Extra Containers to be added to the Vector Pods. |
+| extraVolumeMounts | list | `[]` | Additional Volume to mount into Vector Containers. |
+| extraVolumes | list | `[]` | Additional Volumes to use with Vector Pods. |
+| fullnameOverride | string | `""` | Override the full name of resources. |
+| image.pullPolicy | string | `"IfNotPresent"` | The [pullPolicy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) for Vector's image. |
+| image.pullSecrets | list | `[]` | The [imagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) to reference for the Vector Pods. |
+| image.repository | string | `"timberio/vector"` | Override default registry and name for Vector's image. |
+| image.sha | string | `""` | The SHA to use for Vector's image. |
+| image.tag | string | Derived from the Chart's appVersion. | The tag to use for Vector's image. |
+| ingress.annotations | object | `{}` | Set annotations on the Ingress. |
+| ingress.className | string | `""` | Specify the [ingressClassName](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress), requires Kubernetes >= 1.18 |
+| ingress.enabled | bool | `false` | If true, create and use an Ingress resource. |
+| ingress.hosts | list | `[]` | Configure the hosts and paths for the Ingress. |
+| ingress.tls | list | `[]` | Configure TLS for the Ingress. |
+| initContainers | list | `[]` | Init Containers to be added to the Vector Pods. |
+| lifecycle | object | `{}` | Set lifecycle hooks for Vector containers. |
+| livenessProbe | object | `{}` | Override default liveness probe settings. If customConfig is used, requires customConfig.api.enabled to be set to true. |
+| nameOverride | string | `""` | Override the name of resources. |
+| nodeSelector | object | `{}` | Configure a [nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) for Vector Pods. |
+| persistence.accessModes | list | `["ReadWriteOnce"]` | Specifies the accessModes for PersistentVolumeClaims. Valid for the "Aggregator" role. |
+| persistence.enabled | bool | `false` | If true, create and use PersistentVolumeClaims. |
+| persistence.existingClaim | string | `""` | Name of an existing PersistentVolumeClaim to use. Valid for the "Aggregator" role. |
+| persistence.finalizers | list | `["kubernetes.io/pvc-protection"]` | Specifies the finalizers of PersistentVolumeClaims. Valid for the "Aggregator" role. |
+| persistence.hostPath.path | string | `"/var/lib/vector"` | Override path used for hostPath persistence. Valid for the "Agent" role, persistence is always used for the "Agent" role. |
+| persistence.selectors | object | `{}` | Specifies the selectors for PersistentVolumeClaims. Valid for the "Aggregator" role. |
+| persistence.size | string | `"10Gi"` | Specifies the size of PersistentVolumeClaims. Valid for the "Aggregator" role. |
+| podAnnotations | object | `{}` | Set annotations on Vector Pods. |
+| podDisruptionBudget.enabled | bool | `false` | Enable a [PodDisruptionBudget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for Vector. |
+| podDisruptionBudget.maxUnavailable | int | `nil` | The number of Pods that can be unavailable after an eviction. |
+| podDisruptionBudget.minAvailable | int | `1` | The number of Pods that must still be available after an eviction. |
+| podHostNetwork | bool | `false` | Configure hostNetwork on Vector Pods. |
+| podLabels | object | `{"vector.dev/exclude":"true"}` | Set labels on Vector Pods. |
+| podManagementPolicy | string | `"OrderedReady"` | Specify the [podManagementPolicy](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies) for the StatefulSet. Valid for the "Aggregator" role. |
+| podMonitor.additionalLabels | object | `{}` | Adds additional labels to the PodMonitor. |
+| podMonitor.enabled | bool | `false` | If true, create a PodMonitor for Vector. |
+| podMonitor.honorLabels | bool | `false` | If true, honor_labels is set to true in the [scrape config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config). |
+| podMonitor.honorTimestamps | bool | `true` | If true, honor_timestamps is set to true in the [scrape config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config). |
+| podMonitor.jobLabel | string | `"app.kubernetes.io/name"` | Override the label to retrieve the job name from. |
+| podMonitor.metricRelabelings | list | `[]` | [MetricRelabelConfigs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs) to apply to samples before ingestion. |
+| podMonitor.path | string | `"/metrics"` | Override the path to scrape. |
+| podMonitor.port | string | `"prom-exporter"` | Override the port to scrape. |
+| podMonitor.relabelings | list | `[]` | [RelabelConfigs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) to apply to samples before scraping. |
+| podPriorityClassName | string | `""` | Set the [priorityClassName](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass) on Vector Pods. |
+| podSecurityContext | object | `{}` | Allows you to overwrite the default [PodSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for Vector Pods. |
+| psp.create | bool | `false` | If true, create a [PodSecurityPolicy](https://kubernetes.io/docs/concepts/security/pod-security-policy/) resource. PodSecurityPolicy is deprecated as of Kubernetes v1.21, and will be removed in v1.25. Intended for use with the "Agent" role. |
+| rbac.create | bool | `true` | If true, create and use RBAC resources. Only valid for the "Agent" role. |
+| readinessProbe | object | `{}` | Override default readiness probe settings. If customConfig is used, requires customConfig.api.enabled to be set to true. |
+| replicas | int | `1` | Specify the number of Pods to create. Valid for the "Aggregator" and "Stateless-Aggregator" roles. |
+| resources | object | `{}` | Set Vector resource requests and limits. |
+| role | string | `"Aggregator"` | [Role](https://vector.dev/docs/setup/deployment/roles/) for this Vector instance, valid options are: "Agent", "Aggregator", and "Stateless-Aggregator". |
+| rollWorkload | bool | `true` | Add a checksum of the generated ConfigMap to workload annotations. |
+| secrets.generic | object | `{}` | Each Key/Value will be added to the Secret's data key, each value should be raw and NOT base64 encoded. Any secrets can be provided here. It's commonly used for credentials and other access related values. **NOTE: Don't commit unencrypted secrets to git!** |
+| securityContext | object | `{}` | Specify securityContext on Vector containers. |
+| service.annotations | object | `{}` | Set annotations on Vector's Service. |
+| service.enabled | bool | `true` | If true, create and provide a Service resource for Vector. |
+| service.externalTrafficPolicy | string | `""` | Specify the [externalTrafficPolicy](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip). |
+| service.ipFamilies | list | `[]` | Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/). |
+| service.ipFamilyPolicy | string | `""` | Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/). |
+| service.loadBalancerIP | string | `""` | Specify the [loadBalancerIP](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer). |
+| service.ports | list | `[]` | Manually set the Service ports, overriding automated generation of Service ports. |
+| service.topologyKeys | list | `[]` | Specify the [topologyKeys](https://kubernetes.io/docs/concepts/services-networking/service-topology/#using-service-topology) field on Vector's Service. |
+| service.type | string | `"ClusterIP"` | Set the type for Vector's Service. |
+| serviceAccount.annotations | object | `{}` | Annotations to add to Vector's ServiceAccount. |
+| serviceAccount.automountToken | bool | `true` | Automount API credentials for Vector's ServiceAccount. |
+| serviceAccount.create | bool | `true` | If true, create a ServiceAccount for Vector. |
+| serviceAccount.name | string | `nil` | The name of the ServiceAccount to use. If not set and serviceAccount.create is true, a name is generated using the fullname template. |
+| serviceHeadless.enabled | bool | `true` | If true, create and provide a Headless Service resource for Vector. |
+| terminationGracePeriodSeconds | int | `60` | Override Vector's terminationGracePeriodSeconds. |
+| tolerations | list | `[]` | Configure Vector Pods to be scheduled on [tainted](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) nodes. |
+| topologySpreadConstraints | list | `[]` | Configure [topology spread constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) for Vector Pods. Valid for the "Aggregator" and "Stateless-Aggregator" roles. |
+| updateStrategy | object | `{}` | Customize the updateStrategy used to replace Vector Pods, this is also used for the DeploymentStrategy for the "Stateless-Aggregators". Valid options depend on the chosen role. |
+
+### HAProxy values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| haproxy.affinity | object | `{}` | Configure [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) rules for HAProxy Pods. |
+| haproxy.autoscaling.customMetric | object | `{}` | Target a custom metric for autoscaling. |
+| haproxy.autoscaling.enabled | bool | `false` | Create a HorizontalPodAutoscaler for HAProxy. |
+| haproxy.autoscaling.maxReplicas | int | `10` | Maximum replicas for HAProxy's HPA. |
+| haproxy.autoscaling.minReplicas | int | `1` | Minimum replicas for HAProxy's HPA. |
+| haproxy.autoscaling.targetCPUUtilizationPercentage | int | `80` | Target CPU utilization for HAProxy's HPA. |
+| haproxy.autoscaling.targetMemoryUtilizationPercentage | int | `nil` | Target memory utilization for HAProxy's HPA. |
+| haproxy.containerPorts | list | `[]` | Manually define HAProxy's containerPorts, overrides automated generation of containerPorts. |
+| haproxy.customConfig | string | `""` | Override HAProxy's default configs, if used **all** options need to be specified. This parameter supports using Helm templates to insert values dynamically. By default, this chart will parse Vector's configuration from customConfig to generate HAProxy's config, which can be overwritten with haproxy.customConfig. |
+| haproxy.enabled | bool | `false` | If true, create a HAProxy load balancer. |
+| haproxy.existingConfigMap | string | `""` | Use this existing ConfigMap for HAProxy's configuration instead of creating a new one. Additionally, haproxy.containerPorts and haproxy.service.ports should be specified based on your supplied configuration. If set, this parameter takes precedence over customConfig and the chart's default configs. |
+| haproxy.extraContainers | list | `[]` | Extra Containers to be added to the HAProxy Pods. |
+| haproxy.extraVolumeMounts | list | `[]` | Additional Volume to mount into HAProxy Containers. |
+| haproxy.extraVolumes | list | `[]` | Additional Volumes to use with HAProxy Pods. |
+| haproxy.image.pullPolicy | string | `"IfNotPresent"` | HAProxy image pullPolicy. |
+| haproxy.image.pullSecrets | list | `[]` | The [imagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) to reference for the HAProxy Pods. |
+| haproxy.image.repository | string | `"haproxytech/haproxy-alpine"` | Override default registry and name for HAProxy. |
+| haproxy.image.tag | string | `"2.4.17"` | The tag to use for HAProxy's image. |
+| haproxy.initContainers | list | `[]` | Init Containers to be added to the HAProxy Pods. |
+| haproxy.livenessProbe | object | `{"tcpSocket":{"port":1024}}` | Override default HAProxy liveness probe settings. |
+| haproxy.nodeSelector | object | `{}` | Configure a [nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) for HAProxy Pods |
+| haproxy.podAnnotations | object | `{}` | Set annotations on HAProxy Pods. |
+| haproxy.podLabels | object | `{}` | Set labels on HAProxy Pods. |
+| haproxy.podPriorityClassName | string | `""` | Set the priorityClassName on HAProxy Pods. |
+| haproxy.podSecurityContext | object | `{}` | Allows you to overwrite the default PodSecurityContext for HAProxy. |
+| haproxy.readinessProbe | object | `{"tcpSocket":{"port":1024}}` | Override default HAProxy readiness probe settings. |
+| haproxy.replicas | int | `1` | Set the number of HAProxy Pods to create. |
+| haproxy.resources | object | `{}` | Set HAProxy resource requests and limits. |
+| haproxy.rollWorkload | bool | `true` | Add a checksum of the generated ConfigMap to the HAProxy Deployment. |
+| haproxy.securityContext | object | `{}` | Specify securityContext on HAProxy containers. |
+| haproxy.service.annotations | object | `{}` | Set annotations on HAProxy's Service. |
+| haproxy.service.externalTrafficPolicy | string | `""` | Specify the [externalTrafficPolicy](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip). |
+| haproxy.service.ipFamilies | list | `[]` | Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/). |
+| haproxy.service.ipFamilyPolicy | string | `""` | Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/). |
+| haproxy.service.loadBalancerIP | string | `""` | Specify the [loadBalancerIP](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer). |
+| haproxy.service.ports | list | `[]` | Manually set HAPRoxy's Service ports, overrides automated generation of Service ports. |
+| haproxy.service.topologyKeys | list | `[]` | Specify the [topologyKeys](https://kubernetes.io/docs/concepts/services-networking/service-topology/#using-service-topology) field on HAProxy's Service spec. |
+| haproxy.service.type | string | `"ClusterIP"` | Set type of HAProxy's Service. |
+| haproxy.serviceAccount.annotations | object | `{}` | Annotations to add to the HAProxy ServiceAccount. |
+| haproxy.serviceAccount.automountToken | bool | `true` | Automount API credentials for the HAProxy ServiceAccount. |
+| haproxy.serviceAccount.create | bool | `true` | If true, create a HAProxy ServiceAccount. |
+| haproxy.serviceAccount.name | string | `nil` | The name of the HAProxy ServiceAccount to use. If not set and create is true, a name is generated using the fullname template. |
+| haproxy.strategy | object | `{}` | Customize the [strategy](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/) used to replace HAProxy Pods. |
+| haproxy.terminationGracePeriodSeconds | int | `60` | Override HAProxy's terminationGracePeriodSeconds. |
+| haproxy.tolerations | list | `[]` | Configure HAProxy Pods to be scheduled on [tainted](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) nodes. |
diff --git a/charts/vector/README.md.gotmpl b/charts/vector/README.md.gotmpl
new file mode 100644
index 0000000..2d939ae
--- /dev/null
+++ b/charts/vector/README.md.gotmpl
@@ -0,0 +1,138 @@
+# Vector
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+[Vector](https://vector.dev/) is a high-performance, end-to-end observability data pipeline that puts you in control of your observability data. Collect, transform, and route all your logs, metrics, and traces to any vendors you want today and any other vendors you may want tomorrow. Vector enables dramatic cost reduction, novel data enrichment, and data security where you need it, not where is most convenient for your vendors.
+
+## How to use Vector Helm repository
+
+You need to add this repository to your Helm repositories:
+
+```
+helm repo add vector https://helm.vector.dev
+helm repo update
+```
+
+{{ template "chart.requirementsSection" . }}
+
+## Quick start
+
+By default, Vector runs as a `StatefulSet` in the "Aggregator" role. It can alternatively run as a `Deployment` for the "Stateless-Aggregator" role or a `DaemonSet` for the "Agent" role.
+
+### Installing the Vector chart
+
+To install the chart with the release name `<RELEASE_NAME>` run:
+
+```bash
+helm install --name <RELEASE_NAME> \
+ vector/vector
+```
+
+### Upgrading
+
+#### From original charts
+
+* [Migrate from the `vector-agent` chart](docs/Migrate_from_vector-agent.md)
+* [Migrate from the `vector-aggregator` chart](docs/Migrate_from_vector-aggregator.md)
+
+### Uninstalling the chart
+
+To uninstall/delete the `<RELEASE_NAME>` deployment:
+
+```bash
+helm delete <RELEASE_NAME>
+```
+
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Configuration
+
+1. Using our [`default-values.yaml`](values.yaml) configuration file as a reference, create your own `values.yaml`.
+2. Upgrade the Vector chart with your new `values.yaml` file:
+
+```bash
+helm upgrade -f values.yaml <RELEASE_NAME> vector/vector
+```
+
+**Vector recommends that your `values.yaml` only contain values that need to be overridden, as it allows a smoother experience when upgrading chart versions.**
+
+See the [configuration options](#all-configuration-options) section to discover all possibilities offered by the Vector chart.
+
+### Running on control plane nodes
+
+Depending on your Kubernetes distribution, you may need to configure `tolerations` to run Vector on nodes acting as the control plane.
+
+For example to run Vector on [Openshift](https://www.redhat.com/en/technologies/cloud-computing/openshift) control plane nodes you can set:
+
+```yaml
+tolerations:
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/master
+ operator: Exists
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/infra
+ operator: Exists
+```
+
+Or for [RKE](https://rancher.com/products/rke) control plane nodes set:
+
+```yaml
+tolerations:
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/controlplane
+ operator: Exists
+ - effect: NoExecute
+ key: node-role.kubernetes.io/etcd
+ operator: Exists
+```
+
+### Using template syntax in `customConfig`
+
+As Vector's [template syntax](https://vector.dev/docs/reference/configuration/template-syntax/) shares the same syntax as Helm templates, explicit handling is required
+if you are using Vector's template syntax in the `customConfig` option. To avoid Helm templating configuration intended for Vector you can supply configuration like so:
+
+```yaml
+customConfig:
+ #...
+ sinks:
+ loki:
+ #...
+ labels:
+ foo: bar
+ host: |-
+ {{ print "{{ print \"{{ host }}\" }}" }}
+ source: |-
+ {{ print "{{ print \"{{ source_type }}\" }}" }}
+```
+
+## All configuration options
+
+The following table lists the configurable parameters of the Vector chart and their default values. Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
+
+```bash
+helm install --name <RELEASE_NAME> \
+ --set role=Agent \
+ vector/vector
+```
+
+{{ template "chart.valuesHeader" . }}
+
+### Vector values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+{{- range .Values }}
+ {{- if not (contains "haproxy" .Key) }}
+| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
+ {{- end }}
+{{- end }}
+
+### HAProxy values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+{{- range .Values }}
+ {{- if (contains "haproxy" .Key) }}
+| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} |
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/ci/agent-default-values.yaml b/charts/vector/ci/agent-default-values.yaml
new file mode 100644
index 0000000..c6bb4c6
--- /dev/null
+++ b/charts/vector/ci/agent-default-values.yaml
@@ -0,0 +1,3 @@
+# Agent role
+## Values file for testing default Agent parameters.
+role: Agent
diff --git a/charts/vector/ci/aggregator-all-values.yaml b/charts/vector/ci/aggregator-all-values.yaml
new file mode 100644
index 0000000..86bc5e7
--- /dev/null
+++ b/charts/vector/ci/aggregator-all-values.yaml
@@ -0,0 +1,126 @@
+# Aggregator role
+## Values file for testing all Aggregator parameters.
+podSecurityContext:
+ fsGroup: 2000
+
+securityContext:
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+
+resources:
+ requests:
+ cpu: 200m
+ memory: 256Mi
+ limits:
+ cpu: 200m
+ memory: 256Mi
+
+updateStrategy:
+ type: OnDelete
+
+nodeSelector:
+ kubernetes.io/os: linux
+
+tolerations:
+ - key: node-role.kubernetes.io/master
+ effect: NoSchedule
+
+affinity:
+ nodeAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 1
+ preference:
+ matchExpressions:
+ - key: kubernetes.io/e2e-az-name
+ operator: In
+ values:
+ - e2e-az1
+ - e2e-az2
+
+topologySpreadConstraints:
+ - labelSelector:
+ matchLabels:
+ app.kubernetes.io/name: vector
+ app.kubernetes.io/instance: vector
+ app.kubernetes.io/component: Aggregator
+ maxSkew: 1
+ topologyKey: topology.kubernetes.io/zone
+ whenUnsatisfiable: ScheduleAnyway
+
+customConfig:
+ data_dir: /data
+ api:
+ enabled: true
+ address: 0.0.0.0:1212
+ healthchecks:
+ enabled: false
+ sources:
+ kafka:
+ type: kafka
+ acknowledgements: true
+ bootstrap_servers: kafka-bootstrap.svc.cluster.local:9092
+ group_id: vector-consumer
+ topics: [application-logs]
+ prom_remote:
+ type: prometheus_remote_write
+ address: 0.0.0.0:9999
+ transforms:
+ aggregate:
+ type: aggregate
+ inputs: [prom_remote]
+ interval_ms: 15000
+ remap:
+ type: remap
+ inputs: [kafka]
+ drop_on_error: true
+ source: |
+ . |= object!(parse_json!(.message))
+ sample:
+ type: sample
+ inputs: [remap]
+ exclude: |
+ .status_code != 200 && !includes(["info", "debug"], .severity)
+ rate: 10
+ sinks:
+ s3_archive:
+ type: aws_s3
+ inputs: [remap]
+ bucket: logs-archive
+ key_prefix: date=%F/
+ compression: gzip
+ encoding:
+ codec: json
+ region: us-east-1
+ elasticsearch:
+ type: elasticsearch
+ inputs: [aggregate, sample]
+ endpoint: http://elasticsearch.svc.cluster.local:9000
+ index: vector-%F
+ mode: data_stream
+ compression: gzip
+
+service:
+ enabled: true
+
+persistence:
+ enabled: true
+ storageClassName: standard
+ accessModes:
+ - ReadWriteOnce
+ size: 50Gi
+ finalizers:
+ - kubernetes.io/pvc-protection
+
+livenessProbe:
+ httpGet:
+ path: /health
+ port: api
+
+readinessProbe:
+ httpGet:
+ path: /health
+ port: api
diff --git a/charts/vector/ci/aggregator-default-values.yaml b/charts/vector/ci/aggregator-default-values.yaml
new file mode 100644
index 0000000..1aed48a
--- /dev/null
+++ b/charts/vector/ci/aggregator-default-values.yaml
@@ -0,0 +1,2 @@
+# Aggregator role
+## Emptry values file for testing default Aggregator parameters.
diff --git a/charts/vector/ci/aggregator-haproxy-default-values.yaml b/charts/vector/ci/aggregator-haproxy-default-values.yaml
new file mode 100644
index 0000000..a0c4538
--- /dev/null
+++ b/charts/vector/ci/aggregator-haproxy-default-values.yaml
@@ -0,0 +1,4 @@
+# HAProxy usage
+## Values file for testing HAProxy parameters.
+haproxy:
+ enabled: true
diff --git a/charts/vector/ci/aggregator-ingress-values.yaml b/charts/vector/ci/aggregator-ingress-values.yaml
new file mode 100644
index 0000000..c263456
--- /dev/null
+++ b/charts/vector/ci/aggregator-ingress-values.yaml
@@ -0,0 +1,16 @@
+# Ingress usage
+## Values file for testing Ingress parameters.
+ingress:
+ enabled: true
+ className: "nginx"
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+ kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths:
+ - path: /api/v1
+ pathType: Prefix
+ port:
+ name: "http"
+ number: "8080"
diff --git a/charts/vector/ci/dupe-ports-values.yaml b/charts/vector/ci/dupe-ports-values.yaml
new file mode 100644
index 0000000..e523861
--- /dev/null
+++ b/charts/vector/ci/dupe-ports-values.yaml
@@ -0,0 +1,24 @@
+# Components sharing the same port with different protocols
+## Values file for testing config that shares the same numeric port.
+customConfig:
+ api:
+ enabled: false
+ sources:
+ syslog-tcp:
+ type: syslog
+ address: 0.0.0.0:514
+ max_length: 102400
+ mode: tcp
+ shutdown_timeout_secs: 30
+ syslog-udp:
+ type: syslog
+ address: 0.0.0.0:514
+ max_length: 102400
+ mode: udp
+ shutdown_timeout_secs: 30
+ sinks:
+ stdout:
+ type: console
+ inputs: ["syslog-*"]
+ encoding:
+ codec: json
diff --git a/charts/vector/ci/extra-volume-values.yaml b/charts/vector/ci/extra-volume-values.yaml
new file mode 100644
index 0000000..803eeb4
--- /dev/null
+++ b/charts/vector/ci/extra-volume-values.yaml
@@ -0,0 +1,15 @@
+# Including additional Volumes
+## Values file for testing adding additional Volumes to Vector Pods.
+extraVolumes:
+ - name: podinfo
+ downwardAPI:
+ items:
+ - path: "labels"
+ fieldRef:
+ fieldPath: metadata.labels
+ - path: "annotations"
+ fieldRef:
+ fieldPath: metadata.annotations
+extraVolumeMounts:
+ - name: podinfo
+ mountPath: "/etc/podinfo"
diff --git a/charts/vector/ci/extraContainers-and-extraVolumeMounts-values.yaml b/charts/vector/ci/extraContainers-and-extraVolumeMounts-values.yaml
new file mode 100644
index 0000000..fa0f435
--- /dev/null
+++ b/charts/vector/ci/extraContainers-and-extraVolumeMounts-values.yaml
@@ -0,0 +1,19 @@
+# Including extraContainers and extraVolumes
+## Values file for testing adding extraContainers and extraVolumeMounts to Vector Pods.
+extraContainers:
+ - name: sleep
+ image: busybox
+ command: ['sh', '-c', "sleep 5"]
+extraVolumes:
+ - name: podinfo
+ downwardAPI:
+ items:
+ - path: "labels"
+ fieldRef:
+ fieldPath: metadata.labels
+ - path: "annotations"
+ fieldRef:
+ fieldPath: metadata.annotations
+extraVolumeMounts:
+ - name: podinfo
+ mountPath: "/etc/podinfo"
diff --git a/charts/vector/ci/extraContainers-values.yaml b/charts/vector/ci/extraContainers-values.yaml
new file mode 100644
index 0000000..ce66b67
--- /dev/null
+++ b/charts/vector/ci/extraContainers-values.yaml
@@ -0,0 +1,6 @@
+# Including extraContainers
+## Values file for testing adding extraContainers to Vector Pods.
+extraContainers:
+ - name: sleep
+ image: busybox
+ command: ['sh', '-c', "sleep 5"]
diff --git a/charts/vector/ci/haproxy-extraContainers-values.yaml b/charts/vector/ci/haproxy-extraContainers-values.yaml
new file mode 100644
index 0000000..231e260
--- /dev/null
+++ b/charts/vector/ci/haproxy-extraContainers-values.yaml
@@ -0,0 +1,7 @@
+# Including haproxy.extraContainers
+## Values file for testing adding extraContainers to HAProxy Pods.
+haproxy:
+ extraContainers:
+ - name: sleep
+ image: busybox
+ command: ['sh', '-c', "sleep 5"]
diff --git a/charts/vector/ci/initContainers-values.yaml b/charts/vector/ci/initContainers-values.yaml
new file mode 100644
index 0000000..8688175
--- /dev/null
+++ b/charts/vector/ci/initContainers-values.yaml
@@ -0,0 +1,14 @@
+# Including initContainers
+## Values file for testing adding initContainers to Vector Pods.
+initContainers:
+ - name: sleep
+ image: busybox
+ command: ['sh', '-c', "sleep 5"]
+ - name: touch
+ image: busybox
+ command:
+ - touch
+ - "/vector-data-dir/test"
+ volumeMounts:
+ - name: data
+ mountPath: "/vector-data-dir"
diff --git a/charts/vector/ci/kubeval.yaml b/charts/vector/ci/kubeval.yaml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/charts/vector/ci/kubeval.yaml
@@ -0,0 +1 @@
+---
diff --git a/charts/vector/ci/manual-port-values.yaml b/charts/vector/ci/manual-port-values.yaml
new file mode 100644
index 0000000..54504df
--- /dev/null
+++ b/charts/vector/ci/manual-port-values.yaml
@@ -0,0 +1,11 @@
+# Manually setting Ports
+## Values file for testing manually setting ports and overriding automatically generated configuration.
+containerPorts:
+ - name: override
+ containerPort: 9999
+ protocol: TCP
+service:
+ ports:
+ - name: override
+ port: 9999
+ protocol: TCP
diff --git a/charts/vector/ci/serviceHeadless-disabled.yaml b/charts/vector/ci/serviceHeadless-disabled.yaml
new file mode 100644
index 0000000..176a1fe
--- /dev/null
+++ b/charts/vector/ci/serviceHeadless-disabled.yaml
@@ -0,0 +1,8 @@
+# Separately disable the Headless Service
+## Values file for testing separate enabling for service and serviceHeadless.
+
+service:
+ enabled: true
+serviceHeadless:
+ enabled: false
+
diff --git a/charts/vector/ci/stateless-aggregator-default-values.yaml b/charts/vector/ci/stateless-aggregator-default-values.yaml
new file mode 100644
index 0000000..b37b356
--- /dev/null
+++ b/charts/vector/ci/stateless-aggregator-default-values.yaml
@@ -0,0 +1,3 @@
+# Stateless-Aggregator role
+## Values file for testing default Agent parameters.
+role: Stateless-Aggregator
diff --git a/charts/vector/ci/vector-templating-values.yaml b/charts/vector/ci/vector-templating-values.yaml
new file mode 100644
index 0000000..fdefcf6
--- /dev/null
+++ b/charts/vector/ci/vector-templating-values.yaml
@@ -0,0 +1,24 @@
+# Using Vector's template syntax
+## Values file for testing Vector's template syntax in `customConfig`.
+customConfig:
+ data_dir: /data
+ api:
+ enabled: true
+ address: 127.0.0.1:8686
+ healthchecks:
+ enabled: false
+ sources:
+ generator:
+ type: demo_logs
+ format: json
+ sinks:
+ s3:
+ type: aws_s3
+ inputs: [generator]
+ bucket: logs-archive
+ key_prefix: >-
+ {{ print "{{kubernetes.pod_labels.\"app.kubernetes.io/client-id\"}}/%Y/%m/%d/{{kubernetes.pod_name}}/" }}
+ compression: gzip
+ encoding:
+ codec: json
+ region: us-east-1
diff --git a/charts/vector/docs/Migrate_from_vector-agent.md b/charts/vector/docs/Migrate_from_vector-agent.md
new file mode 100644
index 0000000..6319322
--- /dev/null
+++ b/charts/vector/docs/Migrate_from_vector-agent.md
@@ -0,0 +1,82 @@
+# Migrate from `vector-agent` guide
+
+To deploy the chart as a `DaemonSet`, set `role: "Agent"` in your `values.yaml` or with Helm arguments.
+The `tolerations` option is no longer populated with default values, to match previous behavior you
+can use the following:
+
+```yaml
+tolerations:
+ - key: node-role.kubernetes.io/master
+ effect: NoSchedule
+```
+
+There have been a couple minor changes to the default configuration:
+
+- Vector's API is enabled
+- A `console` sink is now included
+- The default `prometheus_exporter` sink was renamed from "prometheus_sink" to "prom_exporter"
+
+To keep the original defaults, use the following `customConfig`:
+
+```yaml
+customConfig:
+ data_dir: /vector-data-dir
+ api:
+ enabled: false
+ sources:
+ kubernetes_logs:
+ type: kubernetes_logs
+ host_metrics:
+ filesystem:
+ devices:
+ excludes: [binfmt_misc]
+ filesystems:
+ excludes: [binfmt_misc]
+ mountPoints:
+ excludes: ["*/proc/sys/fs/binfmt_misc"]
+ type: host_metrics
+ internal_metrics:
+ type: internal_metrics
+ sinks:
+ prometheus_sink:
+ type: prometheus_exporter
+ inputs: [host_metrics, internal_metrics]
+ address: 0.0.0.0:9090
+```
+
+## Upgrading
+
+Once you have determined the changes you need to make to your `values.yaml` the upgrade is as simple as:
+
+```bash
+helm upgrade -f values.yaml <ORIGINAL_RELEASE_NAME> vector/vector -n <ORIGINAL_NAMESPACE>
+```
+
+## Vector values
+
+| Old parameter | New parameter | Comment |
+|--------------------------------------------------------|-----------------------------|---------------------------------------------------------------------------------------------------------|
+| `dataVolume.hostPath.path` | `persistence.hostPath.path` | |
+| `existingConfigMap` and `extraConfigDirSources` | `existingConfigMaps` | All ConfigMaps in the `existingConfigMaps` list are projected into Vector's configuration directory |
+| `extraContainersPorts` | `containerPorts` | Ports will be automatically generated from `customConfig` but can be manually set with `containerPorts` |
+| `globalOptions.*` | ∅ | Deprecated |
+| `hostMetricsSource.*` | ∅ | Deprecated |
+| `internalMetricsSource.*` | ∅ | Deprecated |
+| `image.version`, `image.base` | ∅ | Only `image.tag` is now used to set the Vector tag |
+| `imagePullSecrets` | `image.pullSecrets` | |
+| `logSchema.*` | ∅ | Deprecated |
+| `kubernetesLogsSource.*` | ∅ | Deprecated |
+| `maxUnavailable` | ∅ | `maxUnavailable` should be passed in as part of the `updateStrategy` object |
+| `podMonitor.additionalLabels` | ∅ | |
+| `podMonitor.extraRelabelings` | `podMonitor.relabelings` | The chart adds no default relabelings |
+| `podRollmeAnnotation` and`podValuesChecksumAnnotation` | ∅ | Replaced by `rollWorkload`, enabled by default |
+| `prometheusSink.*` | ∅ | Deprecated |
+| `psp.enabled` | `psp.create` | |
+| `rbac.enabled` | `rbac.create` | |
+| `secrets.generic` | ⚠️ | `secrets.generic` now takes raw values rather than base64 encoded values |
+| `sinks.*` | ∅ | Deprecated |
+| `sources.*` | ∅ | Deprecated |
+| `transforms.*` | ∅ | Deprecated |
+| `updateStrategy` | ⚠️ | `updateStrategy` now takes an object instead of a string |
+| `vectorApi.*` | ∅ | Deprecated |
+| `vectorSink.*` | ∅ | Deprecated |
diff --git a/charts/vector/docs/Migrate_from_vector-aggregator.md b/charts/vector/docs/Migrate_from_vector-aggregator.md
new file mode 100644
index 0000000..88624bf
--- /dev/null
+++ b/charts/vector/docs/Migrate_from_vector-aggregator.md
@@ -0,0 +1,85 @@
+# Migrate from `vector-aggregator` guide
+
+By default, the chart will deploy Vector as a `StatefulSet` and the default `role` option should remain "Aggregator".
+
+There have been a number of changes to the default configuration:
+
+- Vector's API is enabled
+- A `datadog_agent` source is now included
+- A `fluent` source is now included
+- A `logstash` source is now included
+- A `splunk_hec` source is now included
+- A `statsd` source is now included
+- A `syslog` source is now included
+- A `console` sink is now included
+- The default `prometheus_exporter` sink was renamed from "prometheus_sink" to "prom_exporter"
+
+To keep the original defaults, use the following `customConfig`:
+
+```yaml
+customConfig:
+ data_dir: /vector-data-dir
+ api:
+ enabled: false
+ sources:
+ vector:
+ address: 0.0.0.0:9000
+ type: vector
+ version: "2"
+ internal_metrics:
+ type: internal_metrics
+ sinks:
+ prometheus_sink:
+ type: prometheus_exporter
+ inputs: [internal_metrics]
+ address: 0.0.0.0:9090
+```
+
+## Upgrading
+
+Once you have determined the changes you need to make to your `values.yaml` the upgrade is as simple as:
+
+```bash
+helm upgrade -f values.yaml <ORIGINAL_RELEASE_NAME> vector/vector -n <ORIGINAL_NAMESPACE>
+```
+
+## Vector values
+
+| Old parameter | New parameter | Comment |
+|--------------------------------------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------|
+| `existingConfigMap` and `extraConfigDirSources` | `existingConfigMaps` | All ConfigMaps in the `existingConfigMaps` list are projected into Vector's configuration directory |
+| `extraContainersPorts` | `containerPorts` | Ports will be automatically generated from `customConfig` but can be manually set with `containerPorts` |
+| `global.clusterDomain` and `global.kubeDNSAddress` | ∅ | The paramters are set by default or by `haproxy.customConfig` or `haproxy.existingConfigMap` |
+| `globalOptions.*` | ∅ | Deprecated |
+| `internalMetricsSource.*` | ∅ | Deprecated |
+| `image.version`, `image.base` | ∅ | Only `image.tag` is now used to set the Vector tag |
+| `imagePullSecrets` | `image.pullSecrets` | |
+| `logSchema.*` | ∅ | Deprecated |
+| `podMonitor.additionalLabels` | ∅ | |
+| `podMonitor.extraRelabelings` | `podMonitor.relabelings` | The chart adds no default relabelings |
+| `podRollmeAnnotation` and`podValuesChecksumAnnotation` | ∅ | Replaced by `rollWorkload`, enabled by default |
+| `prometheusSink.*` | ∅ | Deprecated |
+| `psp.enabled` | `psp.create` | |
+| `rbac.enabled` | `rbac.create` | |
+| `secrets.generic` | ⚠️ | `secrets.generic` now takes raw values rather than base64 encoded values |
+| `sinks.*` | ∅ | Deprecated |
+| `sources.*` | ∅ | Deprecated |
+| `storage.mode` | ∅ | If `persistence.enabled` a PersistentVolumeClaim will be created, unless `persistence.existingClaim` is set |
+| `storage.hostPath` | ∅ | Vector running as an Aggregator no longer supports `hostPath` based storage |
+| `storage.managedPersistentVolumeClaim.size` | `persistence.size` | |
+| `storage.managedPersistentVolumeClaim.storageClass` | `persistence.storageClassName` | |
+| `storage.existingPersistentVolumeClaim` | `persistence.existingClaim` | |
+| `transforms.*` | ∅ | Deprecated |
+| `vectorApi.*` | ∅ | Deprecated |
+
+## HAProxy values
+
+| Old parameter | New parameter | Comment |
+|------------------------------------|----------------|---------------------------------------------------------------|
+| `config` | `customConfig` | Default HAProxy config can be overwritten with `customConfig` |
+| `mountedSecrets` | ∅ | |
+| `podSecurityContext.*` | ⚠️ | `podSecurityContext` now takes an object |
+| `replicaCount` | `replicas` | |
+| `service.clusterIP` | ∅ | |
+| `service.loadBalancerIP` | ∅ | |
+| `service.loadBalancerSourceRanges` | ∅ | |
diff --git a/charts/vector/docs/quickstart.md b/charts/vector/docs/quickstart.md
new file mode 100644
index 0000000..49b3c98
--- /dev/null
+++ b/charts/vector/docs/quickstart.md
@@ -0,0 +1,174 @@
+# Quickstart
+
+In this quickstart guide, we will walk you through installing Vector with Helm
+for a variety of common platforms and tools.
+
+_NOTE: The instructions here assume the use of Helm v3, and Bash._
+
+## Getting started with Datadog
+
+### Prerequisites
+
+Verify you have `helm` and `kubectl` installed locally to proceed. `helm` should
+be `v3.0+`.
+
+```bash
+helm version
+```
+
+Ensure you have both the Datadog and Vector charts, and they are up-to-date.
+
+```bash
+helm repo add datadog https://helm.datadoghq.com
+helm repo add vector https://helm.vector.dev
+helm repo update
+```
+
+Access to a pre-existing Kubernetes cluster, or start a new cluster locally
+with `minikube`.
+
+```bash
+minikube start
+minikube addons enable metrics-server
+minikube status
+```
+
+Clone this repository locally to have access to the quickstart values files.
+
+```bash
+git clone https://github.com/vectordotdev/helm-charts.git && \
+ cd helm-charts/charts/vector
+```
+
+### Installing
+
+Export your Datadog API key into your local environment.
+
+```bash
+export DATADOG_API_KEY="<REPLACE_ME>"
+```
+
+Then install Vector into its own namespace, providing your API key as an
+environment variable.
+
+```bash
+helm install vector vector/vector --namespace vector --create-namespace \
+ --values examples/datadog-values.yaml --set secrets.generic.datadog_api_key="${DATADOG_API_KEY}"
+```
+
+Run the next command to confirm Vector has been configured properly and can
+connect to your Datadog account.
+
+```bash
+kubectl logs statefulset/vector --namespace vector --follow
+```
+
+Running the above will tail Vector's logs and allow to confirm your API key
+is correct. In the logs you should only see INFO messages, and the following
+logs (one for each configured sink):
+
+```json lines
+{"timestamp":"2022-03-30T20:25:48.016522Z","level":"INFO","message":"Healthcheck: Passed.","target":"vector::topology::builder"}
+{"timestamp":"2022-03-30T20:25:48.024391Z","level":"INFO","message":"Healthcheck: Passed.","target":"vector::topology::builder"}
+```
+
+Once Vector has been installed and configured, you can install your Datadog Agents.
+By default, the Agents will forward their logs and metrics directly to Datadog's
+hosted intake, we'll create a values file to override that behavior to forward to
+your new Vector Aggregators.
+
+For Datadog Agents version `7.35`/`6.35` or greater:
+
+```bash
+cat <<-'VALUES' > dd-agent.yaml
+---
+datadog:
+ logs:
+ enabled: true
+ containerCollectAll: true
+agents:
+ useConfigMap: true
+ customAgentConfig:
+ # NOTE: If you're using a quickstart environment like `minikube`,
+ # uncomment the line below; otherwise, we recommend leaving it with the
+ # default setting of `true`.
+ # kubelet_tls_verify: false
+ vector:
+ logs:
+ enabled: true
+ # Use https if SSL is enabled in Vector source configuration
+ url: http://vector-haproxy.vector:8282
+ metrics:
+ enabled: true
+ # Use https if SSL is enabled in Vector source configuration
+ url: http://vector-haproxy.vector:8282
+VALUES
+```
+
+For Datadog Agents version `7.34`/`6.34` and older:
+
+_NOTE: Metrics will not be routed through Vector for Datadog Agent versions older
+than `7.35`/`6.35`._
+
+```bash
+cat <<-'VALUES' > dd-agent.yaml
+---
+datadog:
+ logs:
+ enabled: true
+ containerCollectAll: true
+agents:
+ useConfigMap: true
+ customAgentConfig:
+ # NOTE: If you're using a quickstart environment like `minikube`,
+ # uncomment the line below; otherwise, we recommend leaving it with the
+ # default setting of `true`.
+ # kubelet_tls_verify: false
+ logs_config:
+ logs_dd_url: vector-haproxy.vector:8282
+ # Set to false if SSL is enabled in Vector source configuration
+ logs_no_ssl: true
+ use_http: true
+VALUES
+```
+
+_NOTE: When you have the `datadog_agent` source configured, a `helm install` or
+`helm upgrade` will output the appropriate values to provide to the datadog helm
+chart._
+
+```bash
+helm install datadog datadog/datadog --namespace datadog --create-namespace \
+ --values dd-agent.yaml --set datadog.apiKey="${DATADOG_API_KEY}"
+```
+
+Once the Datadog Agents are running you should be able to see your logs in
+Datadog's [Live Tail](https://app.datadoghq.com/logs/livetail?query=sender%3Avector) view,
+by filtering for `sender:vector`. You can also use `vector top` to view Vector's
+topology and related metrics:
+
+```bash
+kubectl --namespace vector exec --stdin --tty statefulset/vector -- vector top
+```
+
+### Troubleshooting
+
+To diagnose problems the following commands may prove useful:
+
+For Datadog Agents:
+
+```bash
+kubectl --namespace datadog exec --stdin --tty daemonset/datadog -- agent status
+```
+
+For the HAProxy:
+
+```bash
+kubectl --namespace vector logs --follow deployment/vector-haproxy
+```
+
+For the Vector Aggregators:
+
+```bash
+kubectl --namespace vector exec --stdin --tty statefulset/vector -- vector tap internal_logs
+```
+
diff --git a/charts/vector/examples/datadog-values.yaml b/charts/vector/examples/datadog-values.yaml
new file mode 100644
index 0000000..d69a0fc
--- /dev/null
+++ b/charts/vector/examples/datadog-values.yaml
@@ -0,0 +1,186 @@
+## See Vector helm documentation to learn more:
+## https://vector.dev/docs/setup/installation/package-managers/helm/
+
+# nameOverride -- Override name of app
+fullnameOverride: vector
+
+## Create a Secret resource for Vector to use
+secrets:
+ # secrets.generic -- Each Key/Value will be added to the Secret's data key, each value should be raw and NOT base64 encoded
+ ## Any secrets can be provided here, it's commonly used for credentials and other access related values.
+ ## NOTE: Don't commit unencrypted secrets to git!
+ generic:
+ datadog_api_key: "REPLACE_ME"
+
+## Configure a HorizontalPodAutoscaler for Vector
+autoscaling:
+ enabled: true
+ minReplicas: 2
+ ## The provided HAProxy config is limited to 10 backends
+ maxReplicas: 10
+ targetCPUUtilizationPercentage: 80
+
+podDisruptionBudget:
+ enabled: true
+ minAvailable: 1
+
+# env -- Set environment variables in Vector containers
+## The examples below leverage examples from secrets.generic and assume no name overrides with a Release name of "vector"
+env:
+ - name: DATADOG_API_KEY
+ valueFrom:
+ secretKeyRef:
+ name: vector
+ key: datadog_api_key
+ - name: VECTOR_LOG_FORMAT
+ value: json
+
+# envFrom -- Define environment variables from Secrets or ConfigMaps
+envFrom:
+ - secretRef:
+ name: vector
+
+# resources -- Set Vector resource requests and limits.
+resources:
+ ## Required for HPA to function
+ requests:
+ cpu: 1000m
+ memory: 512Mi
+ # limits:
+ # cpu: 200m
+ # memory: 256Mi
+
+# affinity -- Allow Vector to schedule using affinity rules
+## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
+affinity:
+ ## Scale across different AZs by default.
+ podAntiAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchExpressions:
+ - key: app.kubernetes.io/name
+ operator: In
+ values:
+ - vector
+ - key: app.kubernetes.io/component
+ operator: In
+ values:
+ - Aggregator
+ topologyKey: topology.kubernetes.io/zone
+
+# customConfig -- Override Vector's default configs, if used **all** options need to be specified
+## This section supports using helm templates to populate dynamic values
+## Ref: https://vector.dev/docs/reference/configuration/
+customConfig:
+ data_dir: /vector-data-dir
+ api:
+ enabled: true
+ address: 0.0.0.0:8686
+ playground: false
+ sources:
+ datadog_agent:
+ address: 0.0.0.0:8282
+ type: datadog_agent
+ multiple_outputs: true
+ internal_metrics:
+ type: internal_metrics
+ transforms:
+ remap_logs:
+ type: remap
+ inputs:
+ - datadog_agent.logs
+ source: |
+ # Parse the received .ddtags field so we can more easily access the contained tags
+ .ddtags = parse_key_value!(.ddtags, key_value_delimiter: ":", field_delimiter: ",")
+ .ddtags.sender = "vector"
+ .ddtags.vector_aggregator = get_hostname!()
+ # Re-encode Datadog tags as a string for the `datadog_logs` sink
+ .ddtags = encode_key_value(.ddtags, key_value_delimiter: ":", field_delimiter: ",")
+
+ # Datadog Agents pass a "status" field that is stripped when ingested
+ del(.status)
+ sinks:
+ datadog_logs:
+ type: datadog_logs
+ inputs:
+ - remap_logs
+ default_api_key: ${DATADOG_API_KEY}
+ compression: gzip
+ datadog_metrics:
+ type: datadog_metrics
+ inputs:
+ - datadog_agent.metrics
+ - internal_metrics
+ default_api_key: ${DATADOG_API_KEY}
+ # TODO: soon!
+ # datadog_traces:
+ # type: datadog_traces
+
+# livenessProbe -- Override default liveness probe settings, if customConfig is used requires customConfig.api.enabled true
+## Requires Vector's API to be enabled
+livenessProbe:
+ httpGet:
+ path: /health
+ port: api
+
+# readinessProbe -- Override default readiness probe settings, if customConfig is used requires customConfig.api.enabled true
+## Requires Vector's API to be enabled
+readinessProbe:
+ httpGet:
+ path: /health
+ port: api
+
+## Optional built-in HAProxy load balancer
+haproxy:
+ # haproxy.enabled -- If true, create a HAProxy load balancer
+ enabled: true
+
+ # haproxy.customConfig -- Override HAProxy's default configs, if used **all** options need to be specified.
+ # This parameter supports using Helm templates to insert values dynamically
+ ## By default this chart will parse Vector's configuration from customConfig to generate HAProxy's config, this generated config
+ ## can be overwritten with haproxy.customConfig
+ customConfig: |
+ global
+ log stdout format raw local0
+ maxconn 4096
+ stats socket /tmp/haproxy
+ hard-stop-after {{ .Values.haproxy.terminationGracePeriodSeconds }}s
+
+ defaults
+ log global
+ option dontlognull
+ retries 3
+ option redispatch
+ option allbackups
+ timeout client 5s
+ timeout server 5s
+ timeout connect 5s
+
+ resolvers coredns
+ nameserver dns1 kube-dns.kube-system.svc.cluster.local:53
+ resolve_retries 3
+ timeout resolve 2s
+ timeout retry 1s
+ accepted_payload_size 8192
+ hold valid 10s
+ hold obsolete 60s
+
+ frontend stats
+ mode http
+ bind :::1024
+ option httplog
+ http-request use-service prometheus-exporter if { path /metrics }
+
+ frontend datadog-agent
+ mode http
+ bind :::8282
+ option httplog
+ default_backend datadog-agent
+
+ backend datadog-agent
+ mode http
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _datadog-agent._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
diff --git a/charts/vector/templates/NOTES.txt b/charts/vector/templates/NOTES.txt
new file mode 100644
index 0000000..f8a7a59
--- /dev/null
+++ b/charts/vector/templates/NOTES.txt
@@ -0,0 +1,10 @@
+{{ template "_divider" }}
+
+{{ include "_logo" . | indent 34 }}
+
+{{ template "_divider" }}
+
+{{ include "_vector.top" . }}
+
+{{ if not .Values.quiet }}{{ include "_configure.datadog" . }}{{ end }}
+
diff --git a/charts/vector/templates/_helpers.tpl b/charts/vector/templates/_helpers.tpl
new file mode 100644
index 0000000..af82257
--- /dev/null
+++ b/charts/vector/templates/_helpers.tpl
@@ -0,0 +1,341 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "vector.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "vector.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "vector.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels.
+*/}}
+{{- define "vector.labels" -}}
+helm.sh/chart: {{ include "vector.chart" . }}
+{{ include "vector.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{ with .Values.commonLabels }}
+{{- toYaml . -}}
+{{- end }}
+{{- end }}
+
+{{/*
+Selector labels.
+*/}}
+{{- define "vector.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "vector.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if or (ne .Values.role "Agent") (ne .Values.role "Aggregator") (ne .Values.role "Stateless-Aggregator") }}
+app.kubernetes.io/component: {{ .Values.role }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use.
+*/}}
+{{- define "vector.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "vector.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+Return the appropriate apiVersion for PodDisruptionBudget policy APIs.
+*/}}
+{{- define "policy.poddisruptionbudget.apiVersion" -}}
+{{- if or (.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget") (semverCompare ">=1.21" .Capabilities.KubeVersion.Version) -}}
+"policy/v1"
+{{- else -}}
+"policy/v1beta1"
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiVersion for HPA autoscaling APIs.
+*/}}
+{{- define "autoscaling.apiVersion" -}}
+{{- if or (.Capabilities.APIVersions.Has "autoscaling/v2/HorizontalPodAutoscaler") (semverCompare ">=1.23" .Capabilities.KubeVersion.Version) -}}
+"autoscaling/v2"
+{{- else -}}
+"autoscaling/v2beta2"
+{{- end -}}
+{{- end -}}
+
+{{/*
+Generate an array of ServicePorts based on `.Values.customConfig`.
+*/}}
+{{- define "vector.ports" -}}
+ {{- range $componentKind, $components := .Values.customConfig }}
+ {{- if eq $componentKind "sources" }}
+ {{- tuple $components "_helper.generatePort" | include "_helper.componentIter" }}
+ {{- else if eq $componentKind "sinks" }}
+ {{- tuple $components "_helper.generatePort" | include "_helper.componentIter" }}
+ {{- else if eq $componentKind "api" }}
+ {{- if $components.enabled }}
+- name: api
+ port: {{ mustRegexFind "[0-9]+$" (get $components "address") }}
+ protocol: TCP
+ targetPort: {{ mustRegexFind "[0-9]+$" (get $components "address") }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{/*
+Iterate over the components defined in `.Values.customConfig`.
+*/}}
+{{- define "_helper.componentIter" -}}
+{{- $components := index . 0 }}
+{{- $helper := index . 1 }}
+ {{- range $id, $options := $components }}
+ {{- if (hasKey $options "address") }}
+ {{- tuple $id $options | include $helper -}}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{/*
+Generate a single ServicePort based on a component configuration.
+*/}}
+{{- define "_helper.generatePort" -}}
+{{- $name := index . 0 | kebabcase -}}
+{{- $config := index . 1 -}}
+{{- $port := mustRegexFind "[0-9]+$" (get $config "address") -}}
+{{- $protocol := default "TCP" (get $config "mode" | upper) }}
+- name: {{ $name }}
+ port: {{ $port }}
+ protocol: {{ $protocol }}
+ targetPort: {{ $port }}
+{{- if not (mustHas $protocol (list "TCP" "UDP")) }}
+{{ fail "Component's `mode` is not a supported protocol, please raise a issue at https://github.com/vectordotdev/vector" }}
+{{- end }}
+{{- end }}
+
+{{/*
+Generate an array of ContainerPorts based on `.Values.customConfig`.
+*/}}
+{{- define "vector.containerPorts" -}}
+ {{- range $componentKind, $components := .Values.customConfig }}
+ {{- if eq $componentKind "sources" }}
+ {{- tuple $components "_helper.generateContainerPort" | include "_helper.componentIter" }}
+ {{- else if eq $componentKind "sinks" }}
+ {{- tuple $components "_helper.generateContainerPort" | include "_helper.componentIter" }}
+ {{- else if eq $componentKind "api" }}
+ {{- if $components.enabled }}
+- name: api
+ containerPort: {{ mustRegexFind "[0-9]+$" (get $components "address") }}
+ protocol: TCP
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{/*
+Generate a single ContainerPort based on a component configuration.
+*/}}
+{{- define "_helper.generateContainerPort" -}}
+{{- $name := index . 0 | kebabcase -}}
+{{- $config := index . 1 -}}
+{{- $port := mustRegexFind "[0-9]+$" (get $config "address") -}}
+{{- $protocol := default "TCP" (get $config "mode" | upper) }}
+- name: {{ $name | trunc 15 | trimSuffix "-" }}
+ containerPort: {{ $port }}
+ protocol: {{ $protocol }}
+{{- if not (mustHas $protocol (list "TCP" "UDP")) }}
+{{ fail "Component's `mode` is not a supported protocol, please raise a issue at https://github.com/vectordotdev/vector" }}
+{{- end }}
+{{- end }}
+
+{{/*
+Print Vector's logo.
+*/}}
+{{- define "_logo" -}}
+{{ print "__ __ __" }}
+{{ print "\\ \\ / / / /" }}
+{{ print " \\ V / / / " }}
+{{ print " \\_/ \\/ " }}
+{{ print "V E C T O R" }}
+{{- end }}
+
+{{/*
+Print line divider.
+*/}}
+{{- define "_divider" -}}
+{{ print "--------------------------------------------------------------------------------" }}
+{{- end }}
+
+{{/*
+Print `vector top` instructions.
+*/}}
+{{- define "_vector.top" -}}
+ {{- if eq "true" (include "_vector.apiEnabled" $) -}}
+{{ print "Vector is starting in your cluster. After a few minutes, you can use Vector's" }}
+{{ println "API to view internal metrics by running:" }}
+ {{- $resource := include "_vector.role" $ -}}
+ {{- $url := include "_vector.url" $ }}
+ $ kubectl -n {{ $.Release.Namespace }} exec -it {{ $resource }}/{{ include "vector.fullname" $ }} -- vector top {{ $url }}
+ {{- else -}}
+ {{- $resource := include "_vector.role" $ -}}
+{{ print "Vector is starting in your cluster. After a few minutes, you can view Vector's" }}
+{{ println "internal logs by running:" }}
+ $ kubectl -n {{ $.Release.Namespace }} logs -f {{ $resource }}/{{ include "vector.fullname" $ }}
+ {{- end }}
+{{- end }}
+
+{{/*
+Return `true` if we can determine if Vector's API is enabled.
+*/}}
+{{- define "_vector.apiEnabled" -}}
+ {{- if $.Values.existingConfigMaps -}}
+false
+ {{- else if $.Values.customConfig -}}
+ {{- if $.Values.customConfig.api -}}
+ {{- if $.Values.customConfig.api.enabled -}}
+true
+ {{- end }}
+ {{- end }}
+ {{- else -}}
+true
+ {{- end }}
+{{- end }}
+
+{{/*
+Return Vector's Resource type based on its `.Values.role`.
+*/}}
+{{- define "_vector.role" -}}
+ {{- if eq $.Values.role "Stateless-Aggregator" -}}
+deployment
+ {{- else if eq $.Values.role "Agent" -}}
+daemonset
+ {{- else -}}
+statefulset
+ {{- end -}}
+{{- end }}
+
+{{/*
+Print the `url` option for the Vector command.
+*/}}
+{{- define "_vector.url" -}}
+ {{- if $.Values.customConfig -}}
+ {{- if $.Values.customConfig.api -}}
+ {{- if $.Values.customConfig.api.address -}}
+{{ print "\\" }}
+ --url {{ printf "http://%s/graphql" $.Values.customConfig.api.address }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+
+{{/*
+Configuring Datadog Agents to forward to Vector.
+This is really alpha level, and should be refactored
+to be more generally usable for other components.
+*/}}
+{{- define "_configure.datadog" -}}
+{{- $hasSourceDatadogAgent := false }}
+{{- $sourceDatadogAgentPort := "" }}
+{{- $hasTls := "" }}
+{{- $protocol := "http" }}
+{{- range $componentKind, $configs := .Values.customConfig }}
+ {{- if eq $componentKind "sources" }}
+ {{- range $componentId, $componentConfig := $configs }}
+ {{- if eq (get $componentConfig "type") "datadog_agent" }}
+ {{- $hasSourceDatadogAgent = true }}
+ {{- $sourceDatadogAgentPort = mustRegexFind "[0-9]+$" (get $componentConfig "address") }}
+ {{- if (hasKey $componentConfig "tls") }}
+ {{- $tlsOpts := get $componentConfig "tls" }}
+ {{- $hasTls = get $tlsOpts "enabled" }}
+ {{- if $hasTls }}{{ $protocol = "https" }}{{ end }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+{{- if or (not .Values.customConfig) (and .Values.customConfig $hasSourceDatadogAgent) }}
+{{- template "_divider" }}
+
+{{ print "datadog_agent:" }}
+
+To forward logs from Datadog Agents deployed with the "datadog" Helm chart,
+include the following in the "values.yaml" for your "datadog" chart:
+
+For Datadog Agents version "7.34"/"6.34" or lower:
+
+datadog:
+ containerExclude: "name:vector"
+ logs:
+ enabled: true
+ containerCollectAll: true
+agents:
+ useConfigMap: true
+ customAgentConfig:
+ kubelet_tls_verify: false
+ logs_config:
+ {{- if .Values.haproxy.enabled }}
+ logs_dd_url: "{{ include "haproxy.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- else }}
+ logs_dd_url: "{{ include "vector.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- end }}
+ {{- if $hasTls }}
+ logs_no_ssl: false
+ {{- else }}
+ logs_no_ssl: true
+ {{- end }}
+ use_http: true
+{{- end }}
+
+For Datadog Agents version "7.35"/"6.35" or greater:
+
+datadog:
+ containerExclude: "name:vector"
+ logs:
+ enabled: true
+ containerCollectAll: true
+agents:
+ useConfigMap: true
+ customAgentConfig:
+ kubelet_tls_verify: false
+ vector:
+ logs:
+ enabled: true
+ {{- if .Values.haproxy.enabled }}
+ url: "{{ $protocol }}://{{ include "haproxy.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- else }}
+ url: "{{ $protocol }}://{{ include "vector.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- end }}
+ metrics:
+ enabled: true
+ {{- if .Values.haproxy.enabled }}
+ url: "{{ $protocol }}://{{ include "haproxy.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- else }}
+ url: "{{ $protocol }}://{{ include "vector.fullname" $ }}.{{ $.Release.Namespace }}:{{ $sourceDatadogAgentPort | default "8282" }}"
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/_pod.tpl b/charts/vector/templates/_pod.tpl
new file mode 100644
index 0000000..3d5b64f
--- /dev/null
+++ b/charts/vector/templates/_pod.tpl
@@ -0,0 +1,222 @@
+{{/*
+Defines the PodSpec for Vector.
+*/}}
+{{- define "vector.pod" -}}
+serviceAccountName: {{ include "vector.serviceAccountName" . }}
+{{- with .Values.podHostNetwork }}
+hostNetwork: {{ . }}
+{{- end }}
+{{- with .Values.podSecurityContext }}
+securityContext:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.podPriorityClassName }}
+priorityClassName: {{ . }}
+{{- end }}
+{{- with .Values.dnsPolicy }}
+dnsPolicy: {{ . }}
+{{- end }}
+{{- with .Values.dnsConfig }}
+dnsConfig:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.image.pullSecrets }}
+imagePullSecrets:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.initContainers }}
+initContainers:
+{{ toYaml . | indent 2 }}
+{{- end }}
+containers:
+ - name: vector
+{{- with .Values.securityContext }}
+ securityContext:
+{{ toYaml . | indent 6 }}
+{{- end }}
+{{- if .Values.image.sha }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}"
+{{- else }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+{{- end }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+{{- with .Values.command }}
+ command:
+ {{- toYaml . | nindent 6 }}
+{{- end }}
+{{- with .Values.args }}
+ args:
+ {{- toYaml . | nindent 6 }}
+{{- end }}
+ env:
+{{- if .Values.env }}
+{{- with .Values.env }}
+ {{- toYaml . | nindent 6 }}
+{{- end }}
+{{- end }}
+{{- if (eq .Values.role "Agent") }}
+ - name: VECTOR_SELF_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ - name: VECTOR_SELF_POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: VECTOR_SELF_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: PROCFS_ROOT
+ value: "/host/proc"
+ - name: SYSFS_ROOT
+ value: "/host/sys"
+{{- end }}
+{{- if .Values.envFrom }}
+{{- with .Values.envFrom }}
+ envFrom:
+ {{- toYaml . | nindent 6 }}
+{{- end }}
+{{- end }}
+ ports:
+{{- if or .Values.containerPorts .Values.existingConfigMaps }}
+ {{- toYaml .Values.containerPorts | nindent 6 }}
+{{- else if .Values.customConfig }}
+ {{- include "vector.containerPorts" . | indent 6 }}
+{{- else if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") }}
+ - name: datadog-agent
+ containerPort: 8282
+ protocol: TCP
+ - name: fluent
+ containerPort: 24224
+ protocol: TCP
+ - name: logstash
+ containerPort: 5044
+ protocol: TCP
+ - name: splunk-hec
+ containerPort: 8080
+ protocol: TCP
+ - name: statsd
+ containerPort: 8125
+ protocol: TCP
+ - name: syslog
+ containerPort: 9000
+ protocol: TCP
+ - name: vector
+ containerPort: 6000
+ protocol: TCP
+ - name: prom-exporter
+ containerPort: 9090
+ protocol: TCP
+{{- else if (eq .Values.role "Agent") }}
+ - name: prom-exporter
+ containerPort: 9090
+ protocol: TCP
+{{- end }}
+{{- with .Values.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | trim | nindent 6 }}
+{{- end }}
+{{- with .Values.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | trim | nindent 6 }}
+{{- end }}
+{{- with .Values.resources }}
+ resources:
+{{- toYaml . | nindent 6 }}
+{{- end }}
+{{- with .Values.lifecycle }}
+ lifecycle:
+{{- toYaml . | nindent 6 }}
+{{- end }}
+ volumeMounts:
+ - name: data
+ {{- if .Values.existingConfigMaps }}
+ mountPath: "{{ if .Values.dataDir }}{{ .Values.dataDir }}{{ else }}{{ fail "Specify `dataDir` if you're using `existingConfigMaps`" }}{{ end }}"
+ {{- else }}
+ mountPath: "{{ .Values.customConfig.data_dir | default "/vector-data-dir" }}"
+ {{- end }}
+ - name: config
+ mountPath: "/etc/vector/"
+ readOnly: true
+{{- if (eq .Values.role "Agent") }}
+ - name: var-log
+ mountPath: "/var/log/"
+ readOnly: true
+ - name: var-lib
+ mountPath: "/var/lib"
+ readOnly: true
+ - name: procfs
+ mountPath: "/host/proc"
+ readOnly: true
+ - name: sysfs
+ mountPath: "/host/sys"
+ readOnly: true
+{{- end }}
+{{- with .Values.extraVolumeMounts }}
+{{- toYaml . | nindent 6 }}
+{{- end }}
+{{- with .Values.extraContainers }}
+{{ toYaml . | indent 2 }}
+{{- end }}
+terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
+{{- with .Values.nodeSelector }}
+nodeSelector:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.affinity }}
+affinity:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.tolerations }}
+tolerations:
+{{ toYaml . | indent 2 }}
+{{- end }}
+{{- with .Values.topologySpreadConstraints }}
+topologySpreadConstraints:
+{{- toYaml . | nindent 2 }}
+{{- end }}
+volumes:
+{{- if and .Values.persistence.enabled (eq .Values.role "Aggregator") }}
+{{- with .Values.persistence.existingClaim }}
+ - name: data
+ persistentVolumeClaim:
+ claimName: {{ . }}
+{{- end }}
+{{- else if (ne .Values.role "Agent") }}
+ - name: data
+ emptyDir: {}
+{{- end }}
+ - name: config
+ projected:
+ sources:
+{{- if .Values.existingConfigMaps }}
+ {{- range .Values.existingConfigMaps }}
+ - configMap:
+ name: {{ . }}
+ {{- end }}
+{{- else }}
+ - configMap:
+ name: {{ template "vector.fullname" . }}
+{{- end }}
+{{- if (eq .Values.role "Agent") }}
+ - name: data
+ hostPath:
+ path: {{ .Values.persistence.hostPath.path | quote }}
+ - name: var-log
+ hostPath:
+ path: "/var/log/"
+ - name: var-lib
+ hostPath:
+ path: "/var/lib/"
+ - name: procfs
+ hostPath:
+ path: "/proc"
+ - name: sysfs
+ hostPath:
+ path: "/sys"
+{{- end }}
+{{- with .Values.extraVolumes }}
+{{- toYaml . | nindent 2 }}
+{{- end }}
+{{- end }}
diff --git a/charts/vector/templates/configmap.yaml b/charts/vector/templates/configmap.yaml
new file mode 100644
index 0000000..a4cebbe
--- /dev/null
+++ b/charts/vector/templates/configmap.yaml
@@ -0,0 +1,88 @@
+{{- if not .Values.existingConfigMaps }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+data:
+ {{- if .Values.customConfig }}
+ vector.yaml: |
+{{ tpl (toYaml .Values.customConfig) . | indent 4 }}
+ {{- else if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") }}
+ aggregator.yaml: |
+ data_dir: /vector-data-dir
+ api:
+ enabled: true
+ address: 127.0.0.1:8686
+ playground: false
+ sources:
+ datadog_agent:
+ address: 0.0.0.0:8282
+ type: datadog_agent
+ fluent:
+ address: 0.0.0.0:24224
+ type: fluent
+ internal_metrics:
+ type: internal_metrics
+ logstash:
+ address: 0.0.0.0:5044
+ type: logstash
+ splunk_hec:
+ address: 0.0.0.0:8080
+ type: splunk_hec
+ statsd:
+ address: 0.0.0.0:8125
+ mode: tcp
+ type: statsd
+ syslog:
+ address: 0.0.0.0:9000
+ mode: tcp
+ type: syslog
+ vector:
+ address: 0.0.0.0:6000
+ type: vector
+ version: "2"
+ sinks:
+ prom_exporter:
+ type: prometheus_exporter
+ inputs: [internal_metrics]
+ address: 0.0.0.0:9090
+ stdout:
+ type: console
+ inputs: [datadog_agent, fluent, logstash, splunk_hec, statsd, syslog, vector]
+ encoding:
+ codec: json
+ {{- else if (eq .Values.role "Agent") }}
+ agent.yaml: |
+ data_dir: /vector-data-dir
+ api:
+ enabled: true
+ address: 127.0.0.1:8686
+ playground: false
+ sources:
+ kubernetes_logs:
+ type: kubernetes_logs
+ host_metrics:
+ filesystem:
+ devices:
+ excludes: [binfmt_misc]
+ filesystems:
+ excludes: [binfmt_misc]
+ mountPoints:
+ excludes: ["*/proc/sys/fs/binfmt_misc"]
+ type: host_metrics
+ internal_metrics:
+ type: internal_metrics
+ sinks:
+ prom_exporter:
+ type: prometheus_exporter
+ inputs: [host_metrics, internal_metrics]
+ address: 0.0.0.0:9090
+ stdout:
+ type: console
+ inputs: [kubernetes_logs]
+ encoding:
+ codec: json
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/daemonset.yaml b/charts/vector/templates/daemonset.yaml
new file mode 100644
index 0000000..51cc017
--- /dev/null
+++ b/charts/vector/templates/daemonset.yaml
@@ -0,0 +1,40 @@
+{{- if (eq .Values.role "Agent") -}}
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "vector.selectorLabels" . | nindent 6 }}
+ {{- with .Values.updateStrategy }}
+ updateStrategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ template:
+ metadata:
+ annotations:
+ {{- if .Values.rollWorkload }}
+ {{- if .Values.existingConfigMaps }}
+ {{- range .Values.existingConfigMaps }}
+ {{- range $file, $contents := (lookup "v1" "ConfigMap" (print $.Release.Namespace) (print .)).data }}
+ checksum/{{ $file }}: {{ $contents | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "vector.selectorLabels" . | nindent 8 }}
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- include "vector.pod" . | nindent 6 }}
+{{- end }}
diff --git a/charts/vector/templates/deployment.yaml b/charts/vector/templates/deployment.yaml
new file mode 100644
index 0000000..0ff0981
--- /dev/null
+++ b/charts/vector/templates/deployment.yaml
@@ -0,0 +1,43 @@
+{{- if (eq .Values.role "Stateless-Aggregator") -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicas }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "vector.selectorLabels" . | nindent 6 }}
+ {{- with .Values.updateStrategy }}
+ strategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ template:
+ metadata:
+ annotations:
+ {{- if .Values.rollWorkload }}
+ {{- if .Values.existingConfigMaps }}
+ {{- range .Values.existingConfigMaps }}
+ {{- range $file, $contents := (lookup "v1" "ConfigMap" (print $.Release.Namespace) (print .)).data }}
+ checksum/{{ $file }}: {{ $contents | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "vector.selectorLabels" . | nindent 8 }}
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- include "vector.pod" . | nindent 6 }}
+{{- end }}
diff --git a/charts/vector/templates/haproxy/_helpers.tpl b/charts/vector/templates/haproxy/_helpers.tpl
new file mode 100644
index 0000000..98eed56
--- /dev/null
+++ b/charts/vector/templates/haproxy/_helpers.tpl
@@ -0,0 +1,51 @@
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "haproxy.fullname" -}}
+{{- printf "%s-haproxy" (include "vector.fullname" .) | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "haproxy.labels" -}}
+helm.sh/chart: {{ include "vector.chart" . }}
+{{ include "haproxy.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Values.haproxy.image.tag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "haproxy.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "vector.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+app.kubernetes.io/component: load-balancer
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "haproxy.serviceAccountName" -}}
+{{- if .Values.haproxy.serviceAccount.create }}
+{{- default (include "haproxy.fullname" .) .Values.haproxy.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.haproxy.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+Return the appropriate apiVersion for HPA autoscaling APIs.
+*/}}
+{{- define "autoscaling.apiVersion" -}}
+{{- if or (.Capabilities.APIVersions.Has "autoscaling/v2/HorizontalPodAutoscaler") (semverCompare ">=1.23" .Capabilities.KubeVersion.Version) -}}
+"autoscaling/v2"
+{{- else -}}
+"autoscaling/v2beta2"
+{{- end -}}
+{{- end -}}
diff --git a/charts/vector/templates/haproxy/configmap.yaml b/charts/vector/templates/haproxy/configmap.yaml
new file mode 100644
index 0000000..49d279a
--- /dev/null
+++ b/charts/vector/templates/haproxy/configmap.yaml
@@ -0,0 +1,128 @@
+{{- if and .Values.haproxy.enabled (not .Values.haproxy.existingConfigMap) }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "haproxy.fullname" . }}
+ labels:
+ {{- include "haproxy.labels" . | nindent 4 }}
+data:
+ haproxy.cfg: |
+ {{- if .Values.customConfig }}
+ {{ tpl .Values.haproxy.customConfig . | nindent 4 }}
+ {{- else }}
+ global
+ log stdout format raw local0
+ maxconn 4096
+ stats socket /tmp/haproxy
+ hard-stop-after {{ .Values.haproxy.terminationGracePeriodSeconds }}s
+
+ defaults
+ log global
+ option dontlognull
+ retries 3
+ option redispatch
+ option allbackups
+ timeout client 5s
+ timeout server 5s
+ timeout connect 5s
+
+ resolvers coredns
+ nameserver dns1 kube-dns.kube-system.svc.cluster.local:53
+ resolve_retries 3
+ timeout resolve 2s
+ timeout retry 1s
+ accepted_payload_size 8192
+ hold valid 10s
+ hold obsolete 60s
+
+ frontend stats
+ mode http
+ bind :::1024
+ option httplog
+ http-request use-service prometheus-exporter if { path /metrics }
+
+ frontend datadog-agent
+ mode http
+ bind :::8282
+ option httplog
+ default_backend datadog-agent
+
+ frontend fluent
+ mode tcp
+ bind :::24224
+ option tcplog
+ default_backend fluent
+
+ frontend logstash
+ mode tcp
+ bind :::5044
+ option tcplog
+ default_backend logstash
+
+ frontend splunk-hec
+ mode http
+ bind :::8080
+ option httplog
+ default_backend splunk-hec
+
+ frontend statsd
+ mode tcp
+ bind :::8125
+ option tcplog
+ default_backend statsd
+
+ frontend syslog
+ mode tcp
+ bind :::9000
+ option tcplog
+ default_backend syslog
+
+ frontend vector
+ mode http
+ bind :::6000 proto h2
+ option httplog
+ default_backend vector
+
+ backend datadog-agent
+ mode http
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _datadog-agent._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend fluent
+ mode tcp
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _fluent._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend logstash
+ mode tcp
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _logstash._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend splunk-hec
+ mode http
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _splunk-hec._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend statsd
+ mode tcp
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _statsd._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend syslog
+ mode tcp
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _syslog._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns check
+
+ backend vector
+ mode http
+ balance roundrobin
+ option tcp-check
+ server-template srv 10 _vector._tcp.{{ include "vector.fullname" $ }}-headless.{{ $.Release.Namespace }}.svc.cluster.local resolvers coredns proto h2 check
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/haproxy/deployment.yaml b/charts/vector/templates/haproxy/deployment.yaml
new file mode 100644
index 0000000..93c1c54
--- /dev/null
+++ b/charts/vector/templates/haproxy/deployment.yaml
@@ -0,0 +1,137 @@
+{{- if .Values.haproxy.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "haproxy.fullname" . }}
+ labels:
+ {{- include "haproxy.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.haproxy.autoscaling.enabled }}
+ replicas: {{ .Values.haproxy.replicas }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "haproxy.selectorLabels" . | nindent 6 }}
+ {{- with .Values.haproxy.strategy }}
+ strategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ template:
+ metadata:
+ annotations:
+ {{- if .Values.haproxy.rollWorkload }}
+ checksum/config: {{ include (print $.Template.BasePath "/haproxy/configmap.yaml") . | sha256sum }}
+ {{- end }}
+ {{- with .Values.haproxy.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "haproxy.selectorLabels" . | nindent 8 }}
+ {{- with .Values.haproxy.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.haproxy.image.pullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "haproxy.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.haproxy.podSecurityContext | nindent 8 }}
+ {{- with .Values.priorityClassName }}
+ priorityClassName: {{ . }}
+ {{- end }}
+ {{- with .Values.haproxy.initContainers }}
+ initContainers:
+ {{ toYaml . | indent 8 }}
+ {{- end }}
+ containers:
+ - name: haproxy
+ securityContext:
+ {{- toYaml .Values.haproxy.securityContext | nindent 12 }}
+ image: "{{ .Values.haproxy.image.repository }}:{{ .Values.haproxy.image.tag }}"
+ imagePullPolicy: {{ .Values.haproxy.image.pullPolicy }}
+ args:
+ - -f
+ - /usr/local/etc/haproxy/haproxy.cfg
+ ports:
+ {{- if or .Values.haproxy.containerPorts .Values.haproxy.existingConfigMap }}
+ {{- toYaml .Values.haproxy.containerPorts | nindent 12 }}
+ {{- else if .Values.customConfig }}
+ {{- include "vector.containerPorts" . | indent 12 }}
+ {{- else if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") }}
+ - name: datadog-agent
+ containerPort: 8282
+ protocol: TCP
+ - name: fluent
+ containerPort: 24224
+ protocol: TCP
+ - name: logstash
+ containerPort: 5044
+ protocol: TCP
+ - name: splunk-hec
+ containerPort: 8080
+ protocol: TCP
+ - name: statsd
+ containerPort: 8125
+ protocol: TCP
+ - name: syslog
+ containerPort: 9000
+ protocol: TCP
+ - name: vector
+ containerPort: 6000
+ protocol: TCP
+ - name: prom-exporter
+ containerPort: 9090
+ protocol: TCP
+ {{- else if (eq .Values.role "Agent") }}
+ - name: prom-exporter
+ containerPort: 9090
+ protocol: TCP
+ {{- end }}
+ {{- if not .Values.haproxy.customConfig }}
+ - name: stats
+ containerPort: 1024
+ protocol: TCP
+ {{- end }}
+ {{- with .Values.haproxy.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | trim | nindent 12 }}
+ {{- end }}
+ {{- with .Values.haproxy.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | trim | nindent 12 }}
+ {{- end }}
+ {{- with .Values.haproxy.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ - name: haproxy-config
+ mountPath: /usr/local/etc/haproxy
+ {{- with .Values.haproxy.extraVolumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.haproxy.extraContainers }}
+ {{ toYaml . | indent 8 }}
+ {{- end }}
+ volumes:
+ - name: haproxy-config
+ configMap:
+ name: {{ if .Values.haproxy.existingConfigMap }}{{ .Values.haproxy.existingConfigMap }}{{ else }}{{ template "haproxy.fullname" . }}{{ end }}
+ {{- with .Values.haproxy.extraVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.haproxy.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.haproxy.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.haproxy.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/haproxy/hpa.yaml b/charts/vector/templates/haproxy/hpa.yaml
new file mode 100644
index 0000000..5fbf42f
--- /dev/null
+++ b/charts/vector/templates/haproxy/hpa.yaml
@@ -0,0 +1,35 @@
+{{- if and .Values.haproxy.enabled .Values.haproxy.autoscaling.enabled }}
+apiVersion: {{ template "autoscaling.apiVersion" . }}
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "haproxy.fullname" . }}
+ labels:
+ {{- include "haproxy.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "haproxy.fullname" . }}
+ minReplicas: {{ .Values.haproxy.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.haproxy.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.haproxy.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.haproxy.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.haproxy.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.haproxy.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+ {{- with .Values.haproxy.autoscaling.customMetric -}}
+ {{ toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/haproxy/service.yaml b/charts/vector/templates/haproxy/service.yaml
new file mode 100644
index 0000000..3c65ddf
--- /dev/null
+++ b/charts/vector/templates/haproxy/service.yaml
@@ -0,0 +1,75 @@
+{{- if .Values.haproxy.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "haproxy.fullname" . }}
+ labels:
+ {{- include "haproxy.labels" . | nindent 4 }}
+ annotations:
+ {{- with .Values.haproxy.service.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+{{- if .Values.haproxy.service.externalTrafficPolicy }}
+ externalTrafficPolicy: {{ .Values.haproxy.service.externalTrafficPolicy }}
+{{- end }}
+{{- if .Values.haproxy.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.haproxy.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.haproxy.service.ipFamilyPolicy }}
+ ipFamilyPolicy: {{ .Values.haproxy.service.ipFamilyPolicy }}
+{{- end }}
+{{- if .Values.haproxy.service.ipFamilies }}
+{{- with .Values.haproxy.service.ipFamilies }}
+ ipFamilies:
+ {{- toYaml . | nindent 4 }}
+{{- end }}
+{{- end }}
+ ports:
+{{- if or .Values.haproxy.service.ports .Values.haproxy.existingConfigMap }}
+ {{- toYaml .Values.haproxy.service.ports | nindent 4 }}
+{{- else if .Values.customConfig }}
+ {{- include "vector.ports" . | indent 4 }}
+{{- else if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") }}
+ - name: datadog-agent
+ port: 8282
+ protocol: TCP
+ - name: fluent
+ port: 24224
+ protocol: TCP
+ - name: logstash
+ port: 5044
+ protocol: TCP
+ - name: splunk-hec
+ port: 8080
+ protocol: TCP
+ - name: statsd
+ port: 8125
+ protocol: TCP
+ - name: syslog
+ port: 9000
+ protocol: TCP
+ - name: vector
+ port: 6000
+ protocol: TCP
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+{{- else if (eq .Values.role "Agent") }}
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+{{- end }}
+{{- if not .Values.haproxy.customConfig }}
+ - name: stats
+ port: 1024
+ protocol: TCP
+{{- end }}
+ selector:
+ {{- include "haproxy.selectorLabels" . | nindent 4 }}
+ type: {{ .Values.haproxy.service.type }}
+ {{- with .Values.haproxy.service.topologyKeys }}
+ topologyKeys:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/haproxy/serviceaccount.yaml b/charts/vector/templates/haproxy/serviceaccount.yaml
new file mode 100644
index 0000000..979d201
--- /dev/null
+++ b/charts/vector/templates/haproxy/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if and .Values.haproxy.enabled .Values.haproxy.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "haproxy.serviceAccountName" . }}
+ labels:
+ {{- include "haproxy.labels" . | nindent 4 }}
+ {{- with .Values.haproxy.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.haproxy.serviceAccount.automountToken }}
+{{- end }}
diff --git a/charts/vector/templates/hpa.yaml b/charts/vector/templates/hpa.yaml
new file mode 100644
index 0000000..d9c44a6
--- /dev/null
+++ b/charts/vector/templates/hpa.yaml
@@ -0,0 +1,45 @@
+{{- if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") -}}
+{{- if .Values.autoscaling.enabled }}
+apiVersion: {{ template "autoscaling.apiVersion" . }}
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ {{- if (eq .Values.role "Aggregator") }}
+ kind: StatefulSet
+ {{- else if (eq .Values.role "Stateless-Aggregator") }}
+ kind: Deployment
+ {{- end }}
+ name: {{ include "vector.fullname" . }}
+ minReplicas: {{ .Values.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- with .Values.autoscaling.customMetric -}}
+ {{ toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .Values.autoscaling.behavior }}
+ behavior:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/vector/templates/ingress.yaml b/charts/vector/templates/ingress.yaml
new file mode 100644
index 0000000..c0135fd
--- /dev/null
+++ b/charts/vector/templates/ingress.yaml
@@ -0,0 +1,63 @@
+{{- if .Values.ingress.enabled -}}
+{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
+ {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
+ {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
+ {{- end }}
+{{- end }}
+{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1
+{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
+ ingressClassName: {{ .Values.ingress.className }}
+ {{- end }}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.ingress.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
+ pathType: {{ .pathType }}
+ {{- end }}
+ backend:
+ {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
+ service:
+ name: {{ if $.Values.haproxy.enabled }}{{ include "haproxy.fullname" $ }}{{ else }}{{ include "vector.fullname" $ }}{{ end }}
+ port:
+ {{- if .port.name }}
+ name: {{ .port.name }}
+ {{- else }}
+ number: {{ .port.number }}
+ {{- end }}
+ {{- else }}
+ serviceName: {{ if $.Values.haproxy.enabled }}{{ include "haproxy.fullname" $ }}{{ else }}{{ include "vector.fullname" $ }}{{ end }}
+ servicePort: {{ .port.number }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/pdb.yaml b/charts/vector/templates/pdb.yaml
new file mode 100644
index 0000000..01d45f7
--- /dev/null
+++ b/charts/vector/templates/pdb.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.podDisruptionBudget.enabled }}
+apiVersion: {{ template "policy.poddisruptionbudget.apiVersion" . }}
+kind: PodDisruptionBudget
+metadata:
+ name: {{ template "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+{{- with .Values.podDisruptionBudget.minAvailable }}
+ minAvailable: {{ . }}
+{{- end }}
+{{- with .Values.podDisruptionBudget.maxUnavailable }}
+ maxUnavailable: {{ . }}
+{{- end }}
+ selector:
+ matchLabels:
+ {{- include "vector.selectorLabels" . | nindent 6 }}
+{{- end }}
diff --git a/charts/vector/templates/podmonitor.yaml b/charts/vector/templates/podmonitor.yaml
new file mode 100644
index 0000000..f82ab37
--- /dev/null
+++ b/charts/vector/templates/podmonitor.yaml
@@ -0,0 +1,32 @@
+{{- if and .Values.podMonitor.enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }}
+apiVersion: monitoring.coreos.com/v1
+kind: PodMonitor
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- with .Values.podMonitor.additionalLabels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ jobLabel: {{ .Values.podMonitor.jobLabel }}
+ selector:
+ matchLabels:
+ {{- include "vector.selectorLabels" . | nindent 6 }}
+ namespaceSelector:
+ matchNames:
+ - {{ .Release.Namespace }}
+ podMetricsEndpoints:
+ - port: {{ .Values.podMonitor.port }}
+ path: {{ .Values.podMonitor.path }}
+ honorLabels: {{ .Values.podMonitor.honorLabels }}
+ honorTimestamps: {{ .Values.podMonitor.honorTimestamps }}
+ {{- with .Values.podMonitor.relabelings }}
+ relabelings:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.podMonitor.metricRelabelings }}
+ metricRelabelings:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/psp.yaml b/charts/vector/templates/psp.yaml
new file mode 100644
index 0000000..3c826bc
--- /dev/null
+++ b/charts/vector/templates/psp.yaml
@@ -0,0 +1,48 @@
+{{- if and .Values.psp.create (.Capabilities.APIVersions.Has "policy/v1beta1") }}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ privileged: false
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: false
+ requiredDropCapabilities:
+ - ALL
+ volumes:
+ - 'hostPath'
+ - 'configMap'
+ - 'emptyDir'
+ - 'secret'
+ - 'projected'
+ allowedHostPaths:
+ - pathPrefix: "/var/log"
+ readOnly: true
+ - pathPrefix: "/var/lib"
+ readOnly: true
+ - pathPrefix: {{ .Values.persistence.hostPath.path | quote }}
+ readOnly: false
+ - pathPrefix: "/sys"
+ readOnly: true
+ - pathPrefix: "/proc"
+ readOnly: true
+ hostNetwork: false
+ hostIPC: false
+ hostPID: false
+ runAsUser:
+ rule: 'RunAsAny'
+ seLinux:
+ rule: 'RunAsAny'
+ supplementalGroups:
+ rule: 'MustRunAs'
+ ranges:
+ - min: 1
+ max: 65535
+ fsGroup:
+ rule: 'MustRunAs'
+ ranges:
+ - min: 1
+ max: 65535
+{{- end }}
diff --git a/charts/vector/templates/rbac.yaml b/charts/vector/templates/rbac.yaml
new file mode 100644
index 0000000..6737587
--- /dev/null
+++ b/charts/vector/templates/rbac.yaml
@@ -0,0 +1,45 @@
+{{- if and .Values.rbac.create (eq .Values.role "Agent") -}}
+# Permissions to use Kubernetes API.
+# Requires that RBAC authorization is enabled.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+rules:
+ - apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - nodes
+ - pods
+ verbs:
+ - list
+ - watch
+{{- if and .Values.psp.create (.Capabilities.APIVersions.Has "policy/v1beta1") }}
+ - apiGroups:
+ - policy
+ resources:
+ - podsecuritypolicies
+ verbs:
+ - use
+ resourceNames:
+ - {{ include "vector.fullname" . }}
+{{- end }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "vector.fullname" . }}
+subjects:
+ - kind: ServiceAccount
+ name: {{ include "vector.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end }}
diff --git a/charts/vector/templates/secret.yaml b/charts/vector/templates/secret.yaml
new file mode 100644
index 0000000..e4367ff
--- /dev/null
+++ b/charts/vector/templates/secret.yaml
@@ -0,0 +1,13 @@
+{{- with .Values.secrets.generic }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "vector.fullname" $ }}
+ labels:
+ {{- include "vector.labels" $ | nindent 4 }}
+type: Opaque
+data:
+{{- range $key, $value := $.Values.secrets.generic }}
+ {{ $key }}: {{ $value | b64enc | quote }}
+{{- end }}
+{{- end }}
diff --git a/charts/vector/templates/service-headless.yaml b/charts/vector/templates/service-headless.yaml
new file mode 100644
index 0000000..f258563
--- /dev/null
+++ b/charts/vector/templates/service-headless.yaml
@@ -0,0 +1,129 @@
+{{/*
+TODO: Remove outer "if/elseif"
+*/}}
+{{- if .Values.serviceHeadless }}
+{{- if .Values.serviceHeadless.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "vector.fullname" . }}-headless
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+ annotations:
+ {{- with .Values.service.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ clusterIP: None
+{{- if .Values.service.ipFamilyPolicy }}
+ ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }}
+{{- end }}
+{{- if .Values.service.ipFamilies }}
+{{- with .Values.service.ipFamilies }}
+ ipFamilies:
+ {{- toYaml . | nindent 4 }}
+{{- end }}
+{{- end }}
+ ports:
+{{- if or .Values.service.ports .Values.existingConfigMaps }}
+ {{- toYaml .Values.service.ports | nindent 4 }}
+{{- else if .Values.customConfig }}
+ {{- include "vector.ports" . | indent 4 }}
+{{- else }}
+ - name: datadog-agent
+ port: 8282
+ protocol: TCP
+ - name: fluent
+ port: 24224
+ protocol: TCP
+ - name: logstash
+ port: 5044
+ protocol: TCP
+ - name: splunk-hec
+ port: 8080
+ protocol: TCP
+ - name: statsd
+ port: 8125
+ protocol: TCP
+ - name: syslog
+ port: 9000
+ protocol: TCP
+ - name: vector
+ port: 6000
+ protocol: TCP
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+ {{- end }}
+ selector:
+ {{- include "vector.selectorLabels" . | nindent 4 }}
+ type: ClusterIP
+ {{- with or .Values.service.topologyKeys }}
+ topologyKeys:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
+{{/*
+Allow for clean upgrade from 0.16.3 -> 0.17.0
+*/}}
+{{- else if .Values.service.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "vector.fullname" . }}-headless
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+ annotations:
+ {{- with .Values.service.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ clusterIP: None
+{{- if .Values.service.ipFamilyPolicy }}
+ ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }}
+{{- end }}
+{{- if .Values.service.ipFamilies }}
+{{- with .Values.service.ipFamilies }}
+ ipFamilies:
+ {{- toYaml . | nindent 4 }}
+{{- end }}
+{{- end }}
+ ports:
+{{- if or .Values.service.ports .Values.existingConfigMaps }}
+ {{- toYaml .Values.service.ports | nindent 4 }}
+{{- else if .Values.customConfig }}
+ {{- include "vector.ports" . | indent 4 }}
+{{- else }}
+ - name: datadog-agent
+ port: 8282
+ protocol: TCP
+ - name: fluent
+ port: 24224
+ protocol: TCP
+ - name: logstash
+ port: 5044
+ protocol: TCP
+ - name: splunk-hec
+ port: 8080
+ protocol: TCP
+ - name: statsd
+ port: 8125
+ protocol: TCP
+ - name: syslog
+ port: 9000
+ protocol: TCP
+ - name: vector
+ port: 6000
+ protocol: TCP
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+ {{- end }}
+ selector:
+ {{- include "vector.selectorLabels" . | nindent 4 }}
+ type: ClusterIP
+ {{- with .Values.service.topologyKeys }}
+ topologyKeys:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/service.yaml b/charts/vector/templates/service.yaml
new file mode 100644
index 0000000..cc1dbb7
--- /dev/null
+++ b/charts/vector/templates/service.yaml
@@ -0,0 +1,70 @@
+{{- if .Values.service.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+ annotations:
+ {{- with .Values.service.annotations }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+{{- if .Values.service.externalTrafficPolicy }}
+ externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }}
+{{- end }}
+{{- if .Values.service.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.service.ipFamilyPolicy }}
+ ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }}
+{{- end }}
+{{- if .Values.service.ipFamilies }}
+{{- with .Values.service.ipFamilies }}
+ ipFamilies:
+ {{- toYaml . | nindent 4 }}
+{{- end }}
+{{- end }}
+ ports:
+{{- if or .Values.service.ports .Values.existingConfigMaps }}
+ {{- toYaml .Values.service.ports | nindent 4 }}
+{{- else if .Values.customConfig }}
+ {{- include "vector.ports" . | indent 4 }}
+{{- else if or (eq .Values.role "Aggregator") (eq .Values.role "Stateless-Aggregator") }}
+ - name: datadog-agent
+ port: 8282
+ protocol: TCP
+ - name: fluent
+ port: 24224
+ protocol: TCP
+ - name: logstash
+ port: 5044
+ protocol: TCP
+ - name: splunk-hec
+ port: 8080
+ protocol: TCP
+ - name: statsd
+ port: 8125
+ protocol: TCP
+ - name: syslog
+ port: 9000
+ protocol: TCP
+ - name: vector
+ port: 6000
+ protocol: TCP
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+{{- else if (eq .Values.role "Agent") }}
+ - name: prom-exporter
+ port: 9090
+ protocol: TCP
+{{- end }}
+ selector:
+ {{- include "vector.selectorLabels" . | nindent 4 }}
+ type: {{ .Values.service.type }}
+ {{- with .Values.service.topologyKeys }}
+ topologyKeys:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/vector/templates/serviceaccount.yaml b/charts/vector/templates/serviceaccount.yaml
new file mode 100644
index 0000000..1103f0b
--- /dev/null
+++ b/charts/vector/templates/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "vector.serviceAccountName" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
+{{- end }}
diff --git a/charts/vector/templates/statefulset.yaml b/charts/vector/templates/statefulset.yaml
new file mode 100644
index 0000000..09db5c1
--- /dev/null
+++ b/charts/vector/templates/statefulset.yaml
@@ -0,0 +1,60 @@
+{{- if (eq .Values.role "Aggregator") -}}
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "vector.fullname" . }}
+ labels:
+ {{- include "vector.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.autoscaling.enabled }}
+ replicas: {{ .Values.replicas }}
+ {{- end }}
+ podManagementPolicy: {{ .Values.podManagementPolicy }}
+ selector:
+ matchLabels:
+ {{- include "vector.selectorLabels" . | nindent 6 }}
+ {{- with .Values.updateStrategy }}
+ updateStrategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ serviceName: {{ template "vector.fullname" . }}-headless
+ template:
+ metadata:
+ annotations:
+ {{- if .Values.rollWorkload }}
+ {{- if .Values.existingConfigMaps }}
+ {{- range .Values.existingConfigMaps }}
+ {{- range $file, $contents := (lookup "v1" "ConfigMap" (print $.Release.Namespace) (print .)).data }}
+ checksum/{{ $file }}: {{ $contents | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- else }}
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "vector.selectorLabels" . | nindent 8 }}
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- include "vector.pod" . | nindent 6 }}
+ volumeClaimTemplates:
+{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
+ - metadata:
+ name: data
+ spec:
+ accessModes: {{ .Values.persistence.accessModes }}
+ storageClassName: {{ .Values.persistence.storageClassName }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.size }}
+ {{- with .Values.persistence.selector }}
+ selector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/vector/values.yaml b/charts/vector/values.yaml
new file mode 100644
index 0000000..c31aa31
--- /dev/null
+++ b/charts/vector/values.yaml
@@ -0,0 +1,560 @@
+# Default values for Vector
+# See Vector helm documentation to learn more:
+# https://vector.dev/docs/setup/installation/package-managers/helm/
+
+# nameOverride -- Override the name of resources.
+nameOverride: ""
+
+# fullnameOverride -- Override the full name of resources.
+fullnameOverride: ""
+
+# role -- [Role](https://vector.dev/docs/setup/deployment/roles/) for this Vector instance, valid options are:
+# "Agent", "Aggregator", and "Stateless-Aggregator".
+
+# Each role is created with the following workloads:
+# Agent = DaemonSet
+# Aggregator = StatefulSet
+# Stateless-Aggregator = Deployment
+role: "Aggregator"
+
+# rollWorkload -- Add a checksum of the generated ConfigMap to workload annotations.
+rollWorkload: true
+
+# commonLabels -- Add additional labels to all created resources.
+commonLabels: {}
+
+# Define the Vector image to use.
+image:
+ # image.repository -- Override default registry and name for Vector's image.
+ repository: timberio/vector
+ # image.pullPolicy -- The [pullPolicy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) for
+ # Vector's image.
+ pullPolicy: IfNotPresent
+ # image.pullSecrets -- The [imagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod)
+ # to reference for the Vector Pods.
+ pullSecrets: []
+ # image.tag -- The tag to use for Vector's image.
+ # @default -- Derived from the Chart's appVersion.
+ tag: ""
+ # image.sha -- The SHA to use for Vector's image.
+ sha: ""
+
+# replicas -- Specify the number of Pods to create. Valid for the "Aggregator" and "Stateless-Aggregator" roles.
+replicas: 1
+
+# podManagementPolicy -- Specify the [podManagementPolicy](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies)
+# for the StatefulSet. Valid for the "Aggregator" role.
+podManagementPolicy: OrderedReady
+
+# Create a Secret resource for Vector to use.
+secrets:
+ # secrets.generic -- Each Key/Value will be added to the Secret's data key, each value should be raw and NOT base64
+ # encoded. Any secrets can be provided here. It's commonly used for credentials and other access related values.
+ # **NOTE: Don't commit unencrypted secrets to git!**
+ generic: {}
+ # my_variable: "my-secret-value"
+ # datadog_api_key: "api-key"
+ # awsAccessKeyId: "access-key"
+ # awsSecretAccessKey: "secret-access-key"
+
+autoscaling:
+ # autoscaling.enabled -- Create a [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
+ # for Vector. Valid for the "Aggregator" and "Stateless-Aggregator" roles.
+ enabled: false
+ # autoscaling.minReplicas -- Minimum replicas for Vector's HPA.
+ minReplicas: 1
+ # autoscaling.maxReplicas -- Maximum replicas for Vector's HPA.
+ maxReplicas: 10
+ # autoscaling.targetCPUUtilizationPercentage -- Target CPU utilization for Vector's HPA.
+ targetCPUUtilizationPercentage: 80
+ # autoscaling.targetMemoryUtilizationPercentage -- (int) Target memory utilization for Vector's HPA.
+ targetMemoryUtilizationPercentage:
+ # autoscaling.customMetric -- Target a custom metric for autoscaling.
+ customMetric: {}
+ # - type: Pods
+ # pods:
+ # metric:
+ # name: utilization
+ # target:
+ # type: AverageValue
+ # averageValue: 95
+ # autoscaling.behavior -- Configure separate scale-up and scale-down behaviors.
+ behavior: {}
+ # scaleDown:
+ # stabilizationWindowSeconds: 300
+
+podDisruptionBudget:
+ # podDisruptionBudget.enabled -- Enable a [PodDisruptionBudget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)
+ # for Vector.
+ enabled: false
+ # podDisruptionBudget.minAvailable -- The number of Pods that must still be available after an eviction.
+ minAvailable: 1
+ # podDisruptionBudget.maxUnavailable -- (int) The number of Pods that can be unavailable after an eviction.
+ maxUnavailable:
+
+rbac:
+ # rbac.create -- If true, create and use RBAC resources. Only valid for the "Agent" role.
+ create: true
+
+psp:
+ # psp.create -- If true, create a [PodSecurityPolicy](https://kubernetes.io/docs/concepts/security/pod-security-policy/)
+ # resource. PodSecurityPolicy is deprecated as of Kubernetes v1.21, and will be removed in v1.25. Intended for use
+ # with the "Agent" role.
+ create: false
+
+serviceAccount:
+ # serviceAccount.create -- If true, create a ServiceAccount for Vector.
+ create: true
+ # serviceAccount.annotations -- Annotations to add to Vector's ServiceAccount.
+ annotations: {}
+ # serviceAccount.name -- The name of the ServiceAccount to use. If not set and serviceAccount.create is true, a name
+ # is generated using the fullname template.
+ name:
+ # serviceAccount.automountToken -- Automount API credentials for Vector's ServiceAccount.
+ automountToken: true
+
+# podAnnotations -- Set annotations on Vector Pods.
+podAnnotations: {}
+
+# podLabels -- Set labels on Vector Pods.
+podLabels:
+ vector.dev/exclude: "true"
+
+# podPriorityClassName -- Set the [priorityClassName](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass)
+# on Vector Pods.
+podPriorityClassName: ""
+
+# podHostNetwork -- Configure hostNetwork on Vector Pods.
+podHostNetwork: false
+
+# podSecurityContext -- Allows you to overwrite the default [PodSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
+# for Vector Pods.
+podSecurityContext: {}
+
+# securityContext -- Specify securityContext on Vector containers.
+securityContext: {}
+
+# command -- Override Vector's default command.
+command: []
+
+# args -- Override Vector's default arguments.
+args:
+ - --config-dir
+ - "/etc/vector/"
+
+# env -- Set environment variables for Vector containers.
+env: []
+ # - name: MY_VARIABLE
+ # valueFrom:
+ # secretKeyRef:
+ # name: vector
+ # key: my_variable
+ # - name: AWS_ACCESS_KEY_ID
+ # valueFrom:
+ # secretKeyRef:
+ # name: vector
+ # key: awsAccessKeyId
+
+# envFrom -- Define environment variables from Secrets or ConfigMaps.
+envFrom: []
+ # - secretRef:
+ # name: vector
+
+# containerPorts -- Manually define Vector's containerPorts, overriding automated generation of containerPorts.
+containerPorts: []
+
+# resources -- Set Vector resource requests and limits.
+resources: {}
+ # requests:
+ # cpu: 200m
+ # memory: 256Mi
+ # limits:
+ # cpu: 200m
+ # memory: 256Mi
+
+# lifecycle -- Set lifecycle hooks for Vector containers.
+lifecycle: {}
+ # preStop:
+ # exec:
+ # command:
+ # - /bin/sleep
+ # - "10"
+
+# updateStrategy -- Customize the updateStrategy used to replace Vector Pods, this is also used for the
+# DeploymentStrategy for the "Stateless-Aggregators". Valid options depend on the chosen role.
+
+# Agent (DaemonSetUpdateStrategy): https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
+# Aggregator (StatefulSetUpdateStrategy): https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/stateful-set-v1/#StatefulSetSpec
+# Stateless-Aggregator (DeploymentStrategy): https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/
+updateStrategy: {}
+# type: RollingUpdate
+# rollingUpdate:
+# maxUnavailable: 1
+
+# terminationGracePeriodSeconds -- Override Vector's terminationGracePeriodSeconds.
+terminationGracePeriodSeconds: 60
+
+# nodeSelector -- Configure a [nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)
+# for Vector Pods.
+nodeSelector: {}
+
+# tolerations -- Configure Vector Pods to be scheduled on [tainted](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
+# nodes.
+tolerations: []
+
+# affinity -- Configure [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)
+# rules for Vector Pods.
+affinity: {}
+
+# topologySpreadConstraints -- Configure [topology spread constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)
+# for Vector Pods. Valid for the "Aggregator" and "Stateless-Aggregator" roles.
+topologySpreadConstraints: []
+
+# Configuration for Vector's Service.
+service:
+ # service.enabled -- If true, create and provide a Service resource for Vector.
+ enabled: true
+ # service.type -- Set the type for Vector's Service.
+ type: "ClusterIP"
+ # service.annotations -- Set annotations on Vector's Service.
+ annotations: {}
+ # service.topologyKeys -- Specify the [topologyKeys](https://kubernetes.io/docs/concepts/services-networking/service-topology/#using-service-topology)
+ # field on Vector's Service.
+ topologyKeys: []
+ # - "kubernetes.io/hostname"
+ # - "topology.kubernetes.io/zone"
+ # - "topology.kubernetes.io/region"
+ # - "*"
+ # service.ports -- Manually set the Service ports, overriding automated generation of Service ports.
+ ports: []
+ # service.externalTrafficPolicy -- Specify the [externalTrafficPolicy](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip).
+ externalTrafficPolicy: ""
+ # service.loadBalancerIP -- Specify the [loadBalancerIP](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).
+ loadBalancerIP: ""
+ # service.ipFamilyPolicy -- Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/).
+ ipFamilyPolicy: ""
+ # service.ipFamilies -- Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/).
+ ipFamilies: []
+
+# Configuration for Vector's Headless Service.
+serviceHeadless:
+ # serviceHeadless.enabled -- If true, create and provide a Headless Service resource for Vector.
+ enabled: true
+
+# Configuration for Vector's Ingress.
+ingress:
+ # ingress.enabled -- If true, create and use an Ingress resource.
+ enabled: false
+ # ingress.className -- Specify the [ingressClassName](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress),
+ # requires Kubernetes >= 1.18
+ className: ""
+ # ingress.annotations -- Set annotations on the Ingress.
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ # ingress.hosts -- Configure the hosts and paths for the Ingress.
+ hosts: []
+ # - host: chart-example.local
+ # paths:
+ # - path: /
+ # pathType: ImplementationSpecific
+ # # Specify the port name or number on the Service
+ # # Using name requires Kubernetes >=1.19
+ # port:
+ # name: ""
+ # number: ""
+ # ingress.tls -- Configure TLS for the Ingress.
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+# existingConfigMaps -- List of existing ConfigMaps for Vector's configuration instead of creating a new one. Requires
+# dataDir to be set. Additionally, containerPorts, service.ports, and serviceHeadless.ports should be specified based on
+# your supplied configuration. If set, this parameter takes precedence over customConfig and the chart's default configs.
+existingConfigMaps: []
+
+# dataDir -- Specify the path for Vector's data, only used when existingConfigMaps are used.
+dataDir: ""
+
+# customConfig -- Override Vector's default configs, if used **all** options need to be specified. This section supports
+# using helm templates to populate dynamic values. See Vector's [configuration documentation](https://vector.dev/docs/reference/configuration/)
+# for all options.
+customConfig: {}
+ # data_dir: /vector-data-dir
+ # api:
+ # enabled: true
+ # address: 127.0.0.1:8686
+ # playground: false
+ # sources:
+ # vector:
+ # address: 0.0.0.0:6000
+ # type: vector
+ # version: "2"
+ # sinks:
+ # stdout:
+ # type: console
+ # inputs: [vector]
+ # encoding:
+ # codec: json
+
+# extraVolumes -- Additional Volumes to use with Vector Pods.
+extraVolumes: []
+
+# extraVolumeMounts -- Additional Volume to mount into Vector Containers.
+extraVolumeMounts: []
+
+# initContainers -- Init Containers to be added to the Vector Pods.
+initContainers: []
+
+# extraContainers -- Extra Containers to be added to the Vector Pods.
+extraContainers: []
+
+# Configuration for Vector's data persistence.
+persistence:
+ # persistence.enabled -- If true, create and use PersistentVolumeClaims.
+ enabled: false
+ # persistence.existingClaim -- Name of an existing PersistentVolumeClaim to use. Valid for the "Aggregator" role.
+ existingClaim: ""
+ # persistence.storageClassName -- Specifies the storageClassName for PersistentVolumeClaims. Valid for the
+ # "Aggregator" role.
+ # storageClassName: default
+
+ # persistence.accessModes -- Specifies the accessModes for PersistentVolumeClaims. Valid for the "Aggregator" role.
+ accessModes:
+ - ReadWriteOnce
+ # persistence.size -- Specifies the size of PersistentVolumeClaims. Valid for the "Aggregator" role.
+ size: 10Gi
+ # persistence.finalizers -- Specifies the finalizers of PersistentVolumeClaims. Valid for the "Aggregator" role.
+ finalizers:
+ - kubernetes.io/pvc-protection
+ # persistence.selectors -- Specifies the selectors for PersistentVolumeClaims. Valid for the "Aggregator" role.
+ selectors: {}
+
+ hostPath:
+ # persistence.hostPath.path -- Override path used for hostPath persistence. Valid for the "Agent" role, persistence
+ # is always used for the "Agent" role.
+ path: "/var/lib/vector"
+
+# dnsPolicy -- Specify the [dnsPolicy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy)
+# for Vector Pods.
+dnsPolicy: ClusterFirst
+
+# dnsConfig -- Specify the [dnsConfig](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config)
+# options for Vector Pods.
+dnsConfig: {}
+ # nameservers:
+ # - 1.2.3.4
+ # searches:
+ # - ns1.svc.cluster-domain.example
+ # - my.dns.search.suffix
+ # options:
+ # - name: ndots
+ # value: "2"
+ # - name: edns0
+
+# livenessProbe -- Override default liveness probe settings. If customConfig is used, requires customConfig.api.enabled
+# to be set to true.
+livenessProbe: {}
+ # httpGet:
+ # path: /health
+ # port: api
+
+# readinessProbe -- Override default readiness probe settings. If customConfig is used,
+# requires customConfig.api.enabled to be set to true.
+readinessProbe: {}
+ # httpGet:
+ # path: /health
+ # port: api
+
+# Configure a PodMonitor for Vector, requires the PodMonitor CRD to be installed.
+podMonitor:
+ # podMonitor.enabled -- If true, create a PodMonitor for Vector.
+ enabled: false
+ # podMonitor.jobLabel -- Override the label to retrieve the job name from.
+ jobLabel: app.kubernetes.io/name
+ # podMonitor.port -- Override the port to scrape.
+ port: prom-exporter
+ # podMonitor.path -- Override the path to scrape.
+ path: /metrics
+ # podMonitor.relabelings -- [RelabelConfigs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config)
+ # to apply to samples before scraping.
+ relabelings: []
+ # podMonitor.metricRelabelings -- [MetricRelabelConfigs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs)
+ # to apply to samples before ingestion.
+ metricRelabelings: []
+ # podMonitor.additionalLabels -- Adds additional labels to the PodMonitor.
+ additionalLabels: {}
+ # podMonitor.honorLabels -- If true, honor_labels is set to true in the [scrape config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config).
+ honorLabels: false
+ # podMonitor.honorTimestamps -- If true, honor_timestamps is set to true in the [scrape config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config).
+ honorTimestamps: true
+
+# Optional built-in HAProxy load.
+haproxy:
+ # haproxy.enabled -- If true, create a HAProxy load balancer.
+ enabled: false
+
+ # Define the HAProxy image to use.
+ image:
+ # haproxy.image.repository -- Override default registry and name for HAProxy.
+ repository: haproxytech/haproxy-alpine
+ # haproxy.image.pullPolicy -- HAProxy image pullPolicy.
+ pullPolicy: IfNotPresent
+ # haproxy.image.pullSecrets -- The [imagePullSecrets](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod)
+ # to reference for the HAProxy Pods.
+ pullSecrets: []
+ # haproxy.image.tag -- The tag to use for HAProxy's image.
+ tag: "2.4.17"
+
+ # haproxy.rollWorkload -- Add a checksum of the generated ConfigMap to the HAProxy Deployment.
+ rollWorkload: true
+
+ # haproxy.replicas -- Set the number of HAProxy Pods to create.
+ replicas: 1
+
+ serviceAccount:
+ # haproxy.serviceAccount.create -- If true, create a HAProxy ServiceAccount.
+ create: true
+ # haproxy.serviceAccount.annotations -- Annotations to add to the HAProxy ServiceAccount.
+ annotations: {}
+ # haproxy.serviceAccount.name -- The name of the HAProxy ServiceAccount to use. If not set and create is true, a
+ # name is generated using the fullname template.
+ name:
+ # haproxy.serviceAccount.automountToken -- Automount API credentials for the HAProxy ServiceAccount.
+ automountToken: true
+
+ # haproxy.strategy -- Customize the [strategy](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/)
+ # used to replace HAProxy Pods.
+ strategy: {}
+ # rollingUpdate:
+ # maxSurge: 25%
+ # maxUnavailable: 25%
+ # type: RollingUpdate
+
+ # haproxy.terminationGracePeriodSeconds -- Override HAProxy's terminationGracePeriodSeconds.
+ terminationGracePeriodSeconds: 60
+
+ # haproxy.podAnnotations -- Set annotations on HAProxy Pods.
+ podAnnotations: {}
+
+ # haproxy.podLabels -- Set labels on HAProxy Pods.
+ podLabels: {}
+
+ # haproxy.podPriorityClassName -- Set the priorityClassName on HAProxy Pods.
+ podPriorityClassName: ""
+
+ # haproxy.podSecurityContext -- Allows you to overwrite the default PodSecurityContext for HAProxy.
+ podSecurityContext: {}
+ # fsGroup: 2000
+
+ # haproxy.securityContext -- Specify securityContext on HAProxy containers.
+ securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+ # haproxy.containerPorts -- Manually define HAProxy's containerPorts, overrides automated generation of containerPorts.
+ containerPorts: []
+
+ # HAProxy's Service configuration.
+ service:
+ # haproxy.service.type -- Set type of HAProxy's Service.
+ type: ClusterIP
+ # haproxy.service.annotations -- Set annotations on HAProxy's Service.
+ annotations: {}
+ # haproxy.service.topologyKeys -- Specify the [topologyKeys](https://kubernetes.io/docs/concepts/services-networking/service-topology/#using-service-topology)
+ # field on HAProxy's Service spec.
+ topologyKeys: []
+ # - "kubernetes.io/hostname"
+ # - "topology.kubernetes.io/zone"
+ # - "topology.kubernetes.io/region"
+ # - "*"
+ # haproxy.service.ports -- Manually set HAPRoxy's Service ports, overrides automated generation of Service ports.
+ ports: []
+ # haproxy.service.externalTrafficPolicy -- Specify the [externalTrafficPolicy](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip).
+ externalTrafficPolicy: ""
+ # haproxy.service.loadBalancerIP -- Specify the [loadBalancerIP](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).
+ loadBalancerIP: ""
+ # haproxy.service.ipFamilyPolicy -- Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/).
+ ipFamilyPolicy: ""
+ # haproxy.service.ipFamilies -- Configure [IPv4/IPv6 dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/).
+ ipFamilies: []
+
+ # haproxy.existingConfigMap -- Use this existing ConfigMap for HAProxy's configuration instead of creating a new one.
+ # Additionally, haproxy.containerPorts and haproxy.service.ports should be specified based on your supplied
+ # configuration. If set, this parameter takes precedence over customConfig and the chart's default configs.
+ existingConfigMap: ""
+
+ # haproxy.customConfig -- Override HAProxy's default configs, if used **all** options need to be specified.
+ # This parameter supports using Helm templates to insert values dynamically. By default, this chart will parse
+ # Vector's configuration from customConfig to generate HAProxy's config, which can be overwritten with
+ # haproxy.customConfig.
+ customConfig: ""
+
+ # haproxy.extraVolumes -- Additional Volumes to use with HAProxy Pods.
+ extraVolumes: []
+
+ # haproxy.extraVolumeMounts -- Additional Volume to mount into HAProxy Containers.
+ extraVolumeMounts: []
+
+ # haproxy.initContainers -- Init Containers to be added to the HAProxy Pods.
+ initContainers: []
+
+ # haproxy.extraContainers -- Extra Containers to be added to the HAProxy Pods.
+ extraContainers: []
+
+ autoscaling:
+ # haproxy.autoscaling.enabled -- Create a HorizontalPodAutoscaler for HAProxy.
+ enabled: false
+ # haproxy.autoscaling.minReplicas -- Minimum replicas for HAProxy's HPA.
+ minReplicas: 1
+ # haproxy.autoscaling.maxReplicas -- Maximum replicas for HAProxy's HPA.
+ maxReplicas: 10
+ # haproxy.autoscaling.targetCPUUtilizationPercentage -- Target CPU utilization for HAProxy's HPA.
+ targetCPUUtilizationPercentage: 80
+ # haproxy.autoscaling.targetMemoryUtilizationPercentage -- (int) Target memory utilization for HAProxy's HPA.
+ targetMemoryUtilizationPercentage:
+ # haproxy.autoscaling.customMetric -- Target a custom metric for autoscaling.
+ customMetric: {}
+ # - type: Pods
+ # pods:
+ # metric:
+ # name: utilization
+ # target:
+ # type: AverageValue
+ # averageValue: 95
+
+ # haproxy.resources -- Set HAProxy resource requests and limits.
+ resources: {}
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+ # haproxy.livenessProbe -- Override default HAProxy liveness probe settings.
+ livenessProbe:
+ tcpSocket:
+ port: 1024
+
+ # haproxy.readinessProbe -- Override default HAProxy readiness probe settings.
+ readinessProbe:
+ tcpSocket:
+ port: 1024
+
+ # haproxy.nodeSelector -- Configure a [nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)
+ # for HAProxy Pods
+ nodeSelector: {}
+
+ # haproxy.tolerations -- Configure HAProxy Pods to be scheduled on [tainted](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
+ # nodes.
+ tolerations: []
+
+ # haproxy.affinity -- Configure [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)
+ # rules for HAProxy Pods.
+ affinity: {}
diff --git a/hack/sync-charts.sh b/hack/sync-charts.sh
index 9f4ce57..cbffa42 100755
--- a/hack/sync-charts.sh
+++ b/hack/sync-charts.sh
@@ -42,6 +42,14 @@
curl -sL https://github.com/prometheus-community/helm-charts/releases/download/kube-prometheus-stack-${KUBE_PROMETHEUS_STACK_VERSION}/kube-prometheus-stack-${KUBE_PROMETHEUS_STACK_VERSION}.tgz \
| tar -xz -C ${ATMOSPHERE}/charts
+LOKI_VERSION=4.6.1
+curl -sL https://github.com/grafana/helm-charts/releases/download/helm-loki-${LOKI_VERSION}/loki-${LOKI_VERSION}.tgz \
+ | tar -xz -C ${ATMOSPHERE}/charts
+
+VECTOR_VERSION=0.19.0
+curl -sL https://github.com/vectordotdev/helm-charts/releases/download/vector-${VECTOR_VERSION}/vector-${VECTOR_VERSION}.tgz \
+ | tar -xz -C ${ATMOSPHERE}/charts
+
PROMETHEUS_PUSHGATEWAY_VERSION=1.16.0
curl -sL https://github.com/prometheus-community/helm-charts/releases/download/prometheus-pushgateway-${PROMETHEUS_PUSHGATEWAY_VERSION}/prometheus-pushgateway-${PROMETHEUS_PUSHGATEWAY_VERSION}.tgz \
| tar -xz -C ${ATMOSPHERE}/charts
diff --git a/playbooks/openstack.yml b/playbooks/openstack.yml
index 25a7913..e53f4f6 100644
--- a/playbooks/openstack.yml
+++ b/playbooks/openstack.yml
@@ -47,6 +47,14 @@
tags:
- kube-prometheus-stack
+ - role: loki
+ tags:
+ - loki
+
+ - role: vector
+ tags:
+ - vector
+
- role: prometheus_ethtool_exporter
tags:
- prometheus-ethtool-exporter
diff --git a/roles/defaults/defaults/main.yml b/roles/defaults/defaults/main.yml
index f89c8bd..49c2963 100644
--- a/roles/defaults/defaults/main.yml
+++ b/roles/defaults/defaults/main.yml
@@ -164,3 +164,4 @@
senlin_health_manager: quay.io/vexxhost/senlin:zed
skopeo: quay.io/skopeo/stable:latest
tempest_run_tests: us-docker.pkg.dev/vexxhost-infra/openstack/tempest:30.1.0-4
+ vector: docker.io/timberio/vector:0.27.0-debian
diff --git a/roles/kube_prometheus_stack/README.md b/roles/kube_prometheus_stack/README.md
index 517a7b5..82b1d7c 100644
--- a/roles/kube_prometheus_stack/README.md
+++ b/roles/kube_prometheus_stack/README.md
@@ -3,13 +3,23 @@
## Exposing data
There are a few ways to expose both the monitoring services to view the health
-and the metrics of the cluster.
+and the metrics and logs of the cluster.
### Port forwarding
The easiest way to expose the monitoring services is to use port forwarding
using the built-in `kubectl` command.
+#### Grafana
+
+```bash
+kubectl -n monitoring port-forward svc/kube-prometheus-stack-grafana 3000
+```
+
+Once you run the command above, you'll be able to open `http://localhost:3000`
+on your local system and view the Grafana UI. The default login is `admin` and
+the password is `prom-operator`.
+
#### Prometheus
```bash
diff --git a/roles/kube_prometheus_stack/vars/main.yml b/roles/kube_prometheus_stack/vars/main.yml
index ba9ee9b..fd76e18 100644
--- a/roles/kube_prometheus_stack/vars/main.yml
+++ b/roles/kube_prometheus_stack/vars/main.yml
@@ -37,6 +37,13 @@
image:
repository: "{{ atmosphere_images['grafana_sidecar'] | vexxhost.atmosphere.docker_image('name') }}"
tag: "{{ atmosphere_images['grafana_sidecar'] | vexxhost.atmosphere.docker_image('tag') }}"
+ additionalDataSources:
+ - name: Loki
+ type: loki
+ access: proxy
+ url: http://loki-gateway
+ version: 1
+ editable: false
serviceMonitor:
relabelings: *relabelings_instance_to_pod_name
nodeSelector: *node_selector
diff --git a/roles/loki/README.md b/roles/loki/README.md
new file mode 100644
index 0000000..bd1a676
--- /dev/null
+++ b/roles/loki/README.md
@@ -0,0 +1,4 @@
+# `loki`
+
+This role installs and configures a simple instance of Loki that uses a
+persistent volume to store the logs.
diff --git a/roles/loki/defaults/main.yml b/roles/loki/defaults/main.yml
new file mode 100644
index 0000000..0dd48ad
--- /dev/null
+++ b/roles/loki/defaults/main.yml
@@ -0,0 +1,20 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+loki_helm_release_name: loki
+loki_helm_chart_path: "{{ role_path }}/../../charts/loki/"
+loki_helm_chart_ref: /usr/local/src/loki
+
+loki_helm_release_namespace: monitoring
+loki_helm_values: {}
diff --git a/roles/loki/meta/main.yml b/roles/loki/meta/main.yml
new file mode 100644
index 0000000..ad1eade
--- /dev/null
+++ b/roles/loki/meta/main.yml
@@ -0,0 +1,31 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+galaxy_info:
+ author: VEXXHOST, Inc.
+ description: Install Loki inside Kubernetes
+ license: Apache-2.0
+ min_ansible_version: 5.5.0
+ standalone: false
+ platforms:
+ - name: Ubuntu
+ versions:
+ - focal
+
+dependencies:
+ - role: defaults
+ - role: upload_helm_chart
+ vars:
+ upload_helm_chart_src: "{{ loki_helm_chart_path }}"
+ upload_helm_chart_dest: "{{ loki_helm_chart_ref }}"
diff --git a/roles/loki/tasks/main.yml b/roles/loki/tasks/main.yml
new file mode 100644
index 0000000..cead7b4
--- /dev/null
+++ b/roles/loki/tasks/main.yml
@@ -0,0 +1,23 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+- name: Deploy Helm chart
+ run_once: true
+ kubernetes.core.helm:
+ name: "{{ loki_helm_release_name }}"
+ chart_ref: "{{ loki_helm_chart_ref }}"
+ release_namespace: "{{ loki_helm_release_namespace }}"
+ create_namespace: true
+ kubeconfig: /etc/kubernetes/admin.conf
+ values: "{{ _loki_helm_values | combine(loki_helm_values, recursive=True) }}"
diff --git a/roles/loki/vars/main.yml b/roles/loki/vars/main.yml
new file mode 100644
index 0000000..799d867
--- /dev/null
+++ b/roles/loki/vars/main.yml
@@ -0,0 +1,37 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+_loki_helm_values:
+ # TODO :image
+ loki:
+ auth_enabled: false
+ commonConfig:
+ replication_factor: 1
+ storage:
+ type: filesystem
+ test:
+ enabled: false
+ monitoring:
+ selfMonitoring:
+ enabled: false
+ grafanaAgent:
+ installOperator: false
+ lokiCanary:
+ enabled: false
+ singleBinary:
+ replicas: 1
+ nodeSelector:
+ openstack-control-plane: enabled
+ persistence:
+ size: 256Gi
diff --git a/roles/vector/README.md b/roles/vector/README.md
new file mode 100644
index 0000000..bf8efe4
--- /dev/null
+++ b/roles/vector/README.md
@@ -0,0 +1,5 @@
+# `vector`
+
+This role installs and configures [Vector](https://vector.dev/) to collect all
+logs from the hosts and send them to a central location, which is configured
+to be the built-in Loki instance.
diff --git a/roles/vector/defaults/main.yml b/roles/vector/defaults/main.yml
new file mode 100644
index 0000000..3b40ed0
--- /dev/null
+++ b/roles/vector/defaults/main.yml
@@ -0,0 +1,20 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+vector_helm_release_name: vector
+vector_helm_chart_path: "{{ role_path }}/../../charts/vector/"
+vector_helm_chart_ref: /usr/local/src/vector
+
+vector_helm_release_namespace: monitoring
+vector_helm_values: {}
diff --git a/roles/vector/meta/main.yml b/roles/vector/meta/main.yml
new file mode 100644
index 0000000..dc98e57
--- /dev/null
+++ b/roles/vector/meta/main.yml
@@ -0,0 +1,31 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+galaxy_info:
+ author: VEXXHOST, Inc.
+ description: Install Vector inside Kubernetes
+ license: Apache-2.0
+ min_ansible_version: 5.5.0
+ standalone: false
+ platforms:
+ - name: Ubuntu
+ versions:
+ - focal
+
+dependencies:
+ - role: defaults
+ - role: upload_helm_chart
+ vars:
+ upload_helm_chart_src: "{{ vector_helm_chart_path }}"
+ upload_helm_chart_dest: "{{ vector_helm_chart_ref }}"
diff --git a/roles/vector/tasks/main.yml b/roles/vector/tasks/main.yml
new file mode 100644
index 0000000..ec5eb59
--- /dev/null
+++ b/roles/vector/tasks/main.yml
@@ -0,0 +1,23 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+- name: Deploy Helm chart
+ run_once: true
+ kubernetes.core.helm:
+ name: "{{ vector_helm_release_name }}"
+ chart_ref: "{{ vector_helm_chart_ref }}"
+ release_namespace: "{{ vector_helm_release_namespace }}"
+ create_namespace: true
+ kubeconfig: /etc/kubernetes/admin.conf
+ values: "{{ _vector_helm_values | combine(vector_helm_values, recursive=True) }}"
diff --git a/roles/vector/vars/main.yml b/roles/vector/vars/main.yml
new file mode 100644
index 0000000..c603166
--- /dev/null
+++ b/roles/vector/vars/main.yml
@@ -0,0 +1,66 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+_vector_helm_values:
+ role: Agent
+ image:
+ repository: "{{ atmosphere_images['vector'] | vexxhost.atmosphere.docker_image('path') }}"
+ tag: "{{ atmosphere_images['vector'] | vexxhost.atmosphere.docker_image('tag') }}"
+ service:
+ enabled: false
+ customConfig:
+ data_dir: /vector-data-dir
+ sources:
+ journald:
+ type: journald
+ kubernetes_logs:
+ type: kubernetes_logs
+ sinks:
+ loki_kubernetes_logs:
+ type: loki
+ endpoint: http://loki-gateway
+ inputs: [kubernetes_logs]
+ encoding:
+ codec: text
+ labels:
+ source_type: '{% raw %}{{ print "{{ source_type }}" }}{% endraw %}'
+ node: '{% raw %}{{ print "{{ kubernetes.pod_node_name }}" }}{% endraw %}'
+ pod_namespace: '{% raw %}{{ print "{{ kubernetes.pod_namespace }}" }}{% endraw %}'
+ pod_uid: '{% raw %}{{ print "{{ kubernetes.pod_uid }}" }}{% endraw %}'
+ pod_name: '{% raw %}{{ print "{{ kubernetes.pod_name }}" }}{% endraw %}'
+ pod_ip: '{% raw %}{{ print "{{ kubernetes.pod_ip }}" }}{% endraw %}'
+ pod_label_*: '{% raw %}{{ print "{{ kubernetes.pod_labels }}" }}{% endraw %}'
+ container_name: '{% raw %}{{ print "{{ kubernetes.container_name }}" }}{% endraw %}'
+ container_image: '{% raw %}{{ print "{{ kubernetes.container_image }}" }}{% endraw %}'
+ stream: '{% raw %}{{ print "{{ kubernetes.stream }}" }}{% endraw %}'
+ loki_journald:
+ type: loki
+ endpoint: http://loki-gateway
+ inputs: [journald]
+ encoding:
+ codec: text
+ labels:
+ source_type: '{% raw %}{{ print "{{ source_type }}" }}{% endraw %}'
+ node: '{% raw %}{{ print "{{ host }}" }}{% endraw %}'
+ unit: '{% raw %}{{ print "{{ _SYSTEMD_UNIT }}" }}{% endraw %}'
+ stream: '{% raw %}{{ print "{{ _TRANSPORT }}" }}{% endraw %}'
+ extraVolumes:
+ - name: etc-machineid
+ hostPath:
+ path: /etc/machine-id
+ type: File
+ extraVolumeMounts:
+ - name: etc-machineid
+ mountPath: /etc/machine-id
+ readOnly: true