Loki Helm: add sidecar to find loki rules in configmaps and secrets (#9399)

**Disclaimer: this work has been done by @Jeinhaus in the [legacy
repo](https://github.com/grafana/helm-charts/pull/1625), I have simply
migrated here and tested it in our own infrastructure**

--- 

**What this PR does / why we need it**:

This PR adds a sidecar to the loki chart that queries the Kubernetes API
to find Configmaps and/or Secrets that contain loki rules, similar to
the way the grafana chart does it for dashboards, plugins or sources.


**Special notes for your reviewer**:

**Checklist**
- [X] Reviewed the
[`CONTRIBUTING.md`](https://github.com/grafana/loki/blob/main/CONTRIBUTING.md)
guide (**required**)
- [X] Documentation added
- [ ] ~Tests updated~
- [x] `CHANGELOG.md` updated
- [ ] ~Changes that require user attention or interaction to upgrade are
documented in `docs/sources/upgrading/_index.md`~

*`CHANGELOG.md` updated*: I have not update the CHANGELOG as I can see
that it hasn't been updated since the start of version 5. As this been
automated now? Or should I had the change logs somewhere else? Or
perhaps simply format my commit in a certain way so it gets generated?
Apologies if this was documented somewhere and I missed it.

---------

Co-authored-by: Julian Einhaus <julianeinhaus@gmx.de>
Co-authored-by: bwlkr <billynwalker@gmail.com>
Co-authored-by: Michel Hollands <42814411+MichelHollands@users.noreply.github.com>
pull/10510/head helm-loki-5.19.0
Antoine Colombier 2 years ago committed by GitHub
parent cc1b0dbc24
commit c0f96a34eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 198
      docs/sources/setup/install/helm/reference.md
  2. 4
      production/helm/loki/CHANGELOG.md
  3. 2
      production/helm/loki/Chart.yaml
  4. 2
      production/helm/loki/README.md
  5. 20
      production/helm/loki/templates/backend/clusterrole.yaml
  6. 24
      production/helm/loki/templates/backend/clusterrolebinding.yaml
  7. 80
      production/helm/loki/templates/backend/statefulset-backend.yaml
  8. 5
      production/helm/loki/templates/role.yaml
  9. 61
      production/helm/loki/values.yaml

@ -3040,6 +3040,15 @@ false
<td><pre lang="json">
{}
</pre>
</td>
</tr>
<tr>
<td>rbac.namespaced</td>
<td>bool</td>
<td>Whether to install RBAC in the namespace only or cluster-wide. Useful if you want to watch ConfigMap globally.</td>
<td><pre lang="json">
false
</pre>
</td>
</tr>
<tr>
@ -3445,6 +3454,195 @@ true
<td><pre lang="json">
null
</pre>
</td>
</tr>
<tr>
<td>sidecar.enableUniqueFilenames</td>
<td>bool</td>
<td>Ensure that rule files aren't conflicting and being overwritten by prefixing their name with the namespace they are defined in.</td>
<td><pre lang="json">
false
</pre>
</td>
</tr>
<tr>
<td>sidecar.image.pullPolicy</td>
<td>string</td>
<td>Docker image pull policy</td>
<td><pre lang="json">
"IfNotPresent"
</pre>
</td>
</tr>
<tr>
<td>sidecar.image.repository</td>
<td>string</td>
<td>The Docker registry and image for the k8s sidecar</td>
<td><pre lang="json">
"kiwigrid/k8s-sidecar"
</pre>
</td>
</tr>
<tr>
<td>sidecar.image.sha</td>
<td>string</td>
<td>Docker image sha. If empty, no sha will be used</td>
<td><pre lang="json">
""
</pre>
</td>
</tr>
<tr>
<td>sidecar.image.tag</td>
<td>string</td>
<td>Docker image tag</td>
<td><pre lang="json">
"1.24.3"
</pre>
</td>
</tr>
<tr>
<td>sidecar.livenessProbe</td>
<td>object</td>
<td>Liveness probe definition. Probe is disabled on the sidecar by default.</td>
<td><pre lang="json">
{}
</pre>
</td>
</tr>
<tr>
<td>sidecar.readinessProbe</td>
<td>object</td>
<td>Readiness probe definition. Probe is disabled on the sidecar by default.</td>
<td><pre lang="json">
{}
</pre>
</td>
</tr>
<tr>
<td>sidecar.resources</td>
<td>object</td>
<td>Resource requests and limits for the sidecar</td>
<td><pre lang="json">
{}
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.enabled</td>
<td>bool</td>
<td>Whether or not to create a sidecar to ingest rule from specific ConfigMaps and/or Secrets.</td>
<td><pre lang="json">
true
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.folder</td>
<td>string</td>
<td>Folder into which the rules will be placed.</td>
<td><pre lang="json">
"/rules"
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.label</td>
<td>string</td>
<td>Label that the configmaps/secrets with rules will be marked with.</td>
<td><pre lang="json">
"loki_rule"
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.labelValue</td>
<td>string</td>
<td>Label value that the configmaps/secrets with rules will be set to.</td>
<td><pre lang="json">
""
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.logLevel</td>
<td>string</td>
<td>Log level of the sidecar container.</td>
<td><pre lang="json">
"INFO"
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.resource</td>
<td>string</td>
<td>Search in configmap, secret, or both.</td>
<td><pre lang="json">
"both"
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.script</td>
<td>string</td>
<td>Absolute path to the shell script to execute after a configmap or secret has been reloaded.</td>
<td><pre lang="json">
null
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.searchNamespace</td>
<td>string</td>
<td>Comma separated list of namespaces. If specified, the sidecar will search for config-maps/secrets inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify 'ALL' to search in all namespaces.</td>
<td><pre lang="json">
null
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.watchClientTimeout</td>
<td>int</td>
<td>WatchClientTimeout: is a client-side timeout, configuring your local socket. If you have a network outage dropping all packets with no RST/FIN, this is how long your client waits before realizing & dropping the connection. Defaults to 66sec.</td>
<td><pre lang="json">
60
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.watchMethod</td>
<td>string</td>
<td>Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH request, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds.</td>
<td><pre lang="json">
"WATCH"
</pre>
</td>
</tr>
<tr>
<td>sidecar.rules.watchServerTimeout</td>
<td>int</td>
<td>WatchServerTimeout: request to the server, asking it to cleanly close the connection after that. defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S.</td>
<td><pre lang="json">
60
</pre>
</td>
</tr>
<tr>
<td>sidecar.securityContext</td>
<td>object</td>
<td>The SecurityContext for the sidecar.</td>
<td><pre lang="json">
{}
</pre>
</td>
</tr>
<tr>
<td>sidecar.skipTlsVerify</td>
<td>bool</td>
<td>Set to true to skip tls verification for kube api calls.</td>
<td><pre lang="json">
false
</pre>
</td>
</tr>
<tr>

@ -13,6 +13,10 @@ Entries should include a reference to the pull request that introduced the chang
[//]: # (<AUTOMATED_UPDATES_LOCATOR> : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.)
## 5.19.0
- [FEATURE] Add optional sidecard to load rules from ConfigMaps and Secrets.
## 5.18.1
- [ENHANCEMENT] #8627 Add service labels and annotations for all services.

@ -3,7 +3,7 @@ name: loki
description: Helm chart for Grafana Loki in simple, scalable mode
type: application
appVersion: 2.9.0
version: 5.18.1
version: 5.19.0
home: https://grafana.github.io/helm-charts
sources:
- https://github.com/grafana/loki

@ -1,6 +1,6 @@
# loki
![Version: 5.18.1](https://img.shields.io/badge/Version-5.18.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.9.0](https://img.shields.io/badge/AppVersion-2.9.0-informational?style=flat-square)
![Version: 5.19.0](https://img.shields.io/badge/Version-5.19.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.9.0](https://img.shields.io/badge/AppVersion-2.9.0-informational?style=flat-square)
Helm chart for Grafana Loki in simple, scalable mode

@ -0,0 +1,20 @@
{{- if and (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }}
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
{{- include "loki.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
name: {{ template "loki.fullname" . }}-clusterrole
{{- if .Values.sidecar.rules.enabled }}
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["configmaps", "secrets"]
verbs: ["get", "watch", "list"]
{{- else }}
rules: []
{{- end }}
{{- end }}

@ -0,0 +1,24 @@
{{- if and (not .Values.rbac.namespaced) }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "loki.fullname" . }}-clusterrolebinding
labels:
{{- include "loki.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
subjects:
- kind: ServiceAccount
name: {{ template "loki.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
{{- if (not .Values.rbac.useExistingRole) }}
name: {{ template "loki.fullname" . }}-clusterrole
{{- else }}
name: {{ .Values.rbac.useExistingRole }}
{{- end }}
apiGroup: rbac.authorization.k8s.io
{{- end -}}

@ -80,6 +80,73 @@ spec:
{{- end }}
{{- end }}
containers:
{{- if .Values.sidecar.rules.enabled }}
- name: loki-sc-rules
{{- if .Values.sidecar.image.sha }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}"
{{- else }}
image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }}
env:
- name: METHOD
value: {{ .Values.sidecar.rules.watchMethod }}
- name: LABEL
value: "{{ .Values.sidecar.rules.label }}"
{{- if .Values.sidecar.rules.labelValue }}
- name: LABEL_VALUE
value: {{ quote .Values.sidecar.rules.labelValue }}
{{- end }}
- name: FOLDER
value: "{{ .Values.sidecar.rules.folder }}"
- name: RESOURCE
value: {{ quote .Values.sidecar.rules.resource }}
{{- if .Values.sidecar.enableUniqueFilenames }}
- name: UNIQUE_FILENAMES
value: "{{ .Values.sidecar.enableUniqueFilenames }}"
{{- end }}
{{- if .Values.sidecar.rules.searchNamespace }}
- name: NAMESPACE
value: "{{ .Values.sidecar.rules.searchNamespace | join "," }}"
{{- end }}
{{- if .Values.sidecar.skipTlsVerify }}
- name: SKIP_TLS_VERIFY
value: "{{ .Values.sidecar.skipTlsVerify }}"
{{- end }}
{{- if .Values.sidecar.rules.script }}
- name: SCRIPT
value: "{{ .Values.sidecar.rules.script }}"
{{- end }}
{{- if .Values.sidecar.rules.watchServerTimeout }}
- name: WATCH_SERVER_TIMEOUT
value: "{{ .Values.sidecar.rules.watchServerTimeout }}"
{{- end }}
{{- if .Values.sidecar.rules.watchClientTimeout }}
- name: WATCH_CLIENT_TIMEOUT
value: "{{ .Values.sidecar.rules.watchClientTimeout }}"
{{- end }}
{{- if .Values.sidecar.rules.logLevel }}
- name: LOG_LEVEL
value: "{{ .Values.sidecar.rules.logLevel }}"
{{- end }}
{{- if .Values.sidecar.livenessProbe }}
livenessProbe:
{{ toYaml .Values.livenessProbe | indent 6 }}
{{- end }}
{{- if .Values.sidecar.readinessProbe }}
readinessProbe:
{{ toYaml .Values.readinessProbe | indent 6 }}
{{- end }}
resources:
{{ toYaml .Values.sidecar.resources | indent 6 }}
{{- if .Values.sidecar.securityContext }}
securityContext:
{{- toYaml .Values.sidecar.securityContext | nindent 6 }}
{{- end }}
volumeMounts:
- name: sc-rules-volume
mountPath: {{ .Values.sidecar.rules.folder | quote }}
{{- end}}
- name: loki
image: {{ include "loki.image" . }}
imagePullPolicy: {{ .Values.loki.image.pullPolicy }}
@ -125,6 +192,10 @@ spec:
- name: license
mountPath: /etc/loki/license
{{- end}}
{{- if .Values.sidecar.rules.enabled }}
- name: sc-rules-volume
mountPath: {{ .Values.sidecar.rules.folder | quote }}
{{- end}}
{{- with .Values.backend.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
@ -168,6 +239,15 @@ spec:
secretName: enterprise-logs-license
{{- end }}
{{- end }}
{{- if .Values.sidecar.rules.enabled }}
- name: sc-rules-volume
{{- if .Values.sidecar.rules.sizeLimit }}
emptyDir:
sizeLimit: {{ .Values.sidecar.rules.sizeLimit }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end -}}
{{- with .Values.backend.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}

@ -27,5 +27,10 @@ rules:
- use
resourceNames:
- {{ include "loki.name" . }}
{{- if and .Values.rbac.namespaced .Values.sidecar.rules.enabled }}
- apiGroups: [""] # "" indicates the core API group
resources: ["configmaps", "secrets"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- end }}
{{- end }}

@ -504,6 +504,8 @@ rbac:
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
# -- Whether to install RBAC in the namespace only or cluster-wide. Useful if you want to watch ConfigMap globally.
namespaced: false
# -- Section for configuring optional Helm test
test:
enabled: true
@ -1487,3 +1489,62 @@ extraObjects: []
# category: logs
# annotations:
# message: "loki has encountered errors"
sidecar:
image:
# -- The Docker registry and image for the k8s sidecar
repository: kiwigrid/k8s-sidecar
# -- Docker image tag
tag: 1.24.3
# -- Docker image sha. If empty, no sha will be used
sha: ""
# -- Docker image pull policy
pullPolicy: IfNotPresent
# -- Resource requests and limits for the sidecar
resources: {}
# limits:
# cpu: 100m
# memory: 100Mi
# requests:
# cpu: 50m
# memory: 50Mi
# -- The SecurityContext for the sidecar.
securityContext: {}
# -- Set to true to skip tls verification for kube api calls.
skipTlsVerify: false
# -- Ensure that rule files aren't conflicting and being overwritten by prefixing their name with the namespace they are defined in.
enableUniqueFilenames: false
# -- Readiness probe definition. Probe is disabled on the sidecar by default.
readinessProbe: {}
# -- Liveness probe definition. Probe is disabled on the sidecar by default.
livenessProbe: {}
rules:
# -- Whether or not to create a sidecar to ingest rule from specific ConfigMaps and/or Secrets.
enabled: true
# -- Label that the configmaps/secrets with rules will be marked with.
label: loki_rule
# -- Label value that the configmaps/secrets with rules will be set to.
labelValue: ""
# -- Folder into which the rules will be placed.
folder: /rules
# -- Comma separated list of namespaces. If specified, the sidecar will search for config-maps/secrets inside these namespaces.
# Otherwise the namespace in which the sidecar is running will be used.
# It's also possible to specify 'ALL' to search in all namespaces.
searchNamespace: null
# -- Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH request, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds.
watchMethod: WATCH
# -- Search in configmap, secret, or both.
resource: both
# -- Absolute path to the shell script to execute after a configmap or secret has been reloaded.
script: null
# -- WatchServerTimeout: request to the server, asking it to cleanly close the connection after that.
# defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S.
watchServerTimeout: 60
#
# -- WatchClientTimeout: is a client-side timeout, configuring your local socket.
# If you have a network outage dropping all packets with no RST/FIN,
# this is how long your client waits before realizing & dropping the connection.
# Defaults to 66sec.
watchClientTimeout: 60
# -- Log level of the sidecar container.
logLevel: INFO

Loading…
Cancel
Save