diff --git a/charts/fluent-bit/.helmignore b/charts/fluent-bit/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/charts/fluent-bit/.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/fluent-bit/Chart.yaml b/charts/fluent-bit/Chart.yaml new file mode 100644 index 0000000000..be48db1998 --- /dev/null +++ b/charts/fluent-bit/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: "v1" +name: fluent-bit +version: 0.4.0 +appVersion: v1.6.0 +kubeVersion: "^1.10.0-0" +description: "Uses fluent-bit Loki go plugin for gathering logs and sending them to Loki" +home: https://grafana.com/loki +icon: https://github.com/grafana/loki/raw/master/docs/logo.png +sources: +- https://github.com/grafana/loki +maintainers: +- name: Loki Maintainers + email: lokiproject@googlegroups.com +engine: gotpl diff --git a/charts/fluent-bit/README.md b/charts/fluent-bit/README.md new file mode 100644 index 0000000000..35c957df1c --- /dev/null +++ b/charts/fluent-bit/README.md @@ -0,0 +1,122 @@ +# Fluent Bit Loki chart + +This chart install the Fluent Bit application to ship logs to Loki. It defines daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## 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 + +> If you don't have `Helm` installed locally, or `Tiller` installed in your Kubernetes cluster, read the [Using Helm](https://docs.helm.sh/using_helm/) documentation to get started. +To install the chart with the release name `my-release` using our helm repository: + +```bash +helm repo add grafana https://grafana.github.io/helm-charts +helm upgrade --install my-release grafana/fluent-bit \ + --set loki.serviceName=loki.default.svc.cluster.local +``` + +If you deploy Loki with a custom namespace or service name, you must change the value above for `loki.serviceName` to the appropriate value. + +The command deploys Fluent Bit on the Kubernetes cluster with the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +To configure the chart to send to [Grafana Cloud](https://grafana.com/products/cloud) use: + +```bash +helm upgrade --install my-release grafana/fluent-bit \ + --set loki.serviceName=logs-us-west1.grafana.net,loki.servicePort=80,loki.serviceScheme=https \ + --set loki.user=2830,loki.password=1234 +``` + +> **Tip**: List all releases using `helm list` + +To install a custom tag use the following command: + +```bash +helm upgrade --install my-release grafana/fluent-bit \ + --set image.tag= +``` + +The full list of available tags on [docker hub](https://cloud.docker.com/u/grafana/repository/docker/grafana/fluent-bit-plugin-loki). + +Alternatively you can install the full [Loki stack](../loki-stack) (Loki + Fluent Bit) using: + +```bash +helm upgrade --install my-release grafana/loki-stack \ + --set fluent-bit.enabled=true,promtail.enabled=false +``` + +This will automatically configured the `loki.serviceName` configuration field to the newly created Loki instance. + +## RBAC + +By default, `rbac.create` is set to true. This enable RBAC support in Fluent Bit and must be true if RBAC is enabled in your cluster. + +The chart will take care of creating the required service accounts and roles for Fluent Bit. + +If you have RBAC disabled, or to put it another way, ABAC enabled, you should set this value to `false`. + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```bash +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following tables lists the configurable parameters of the Fluent Bit chart and their default values. + +For more details, read the [Fluent Bit documentation](../../../cmd/fluent-bit/README.md) + +| Parameter | Description | Default | +|--------------------------|----------------------------------------------------------------------------------------------------|----------------------------------| +| `loki.serviceName` | The address of the Loki service. | `"${RELEASE}-loki"` | +| `loki.servicePort` | The port of the Loki service. | `3100` | +| `loki.serviceScheme` | The scheme of the Loki service. | `http` | +| `loki.user` | The http basic auth username to access the Loki service. | | +| `loki.password` | The http basic auth password to access the Loki service. | | +| `config.port` | the Fluent Bit port to listen. (This is mainly used to serve metrics) | `2020` | +| `config.tenantID` | The tenantID used by default to push logs to Loki | `''` | +| `config.batchWait` | Time to wait before send a log batch to Loki, full or not. (unit: secs) | `1` | +| `config.batchSize` | Log batch size to send a log batch to Loki. (unit: bytes) | `10240` (10KiB) | +| `config.loglevel` | the Fluent Bit log level (debug,info,warn,error). | `warn` | +| `config.lineFormat` | The line format to use to send a record (json/key_value) | `json` | +| `config.k8sLoggingParser`| Allow Kubernetes Pods to suggest a pre-defined Parser. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/filter/kubernetes#kubernetes-annotations). | `Off` | +| `config.removeKeys` | The list of key to remove from each record | `[removeKeys,stream]` | +| `config.labels` | A set of labels to send for every log | `'{job="fluent-bit"}'` | +| `config.autoKubernetesLabels` | If set to true, it will add all Kubernetes labels to Loki labels | `false` | +| `config.labelMap` | Mapping of labels from a record. See [Fluent Bit documentation](../../../cmd/fluent-bit/README.md) | | +| `config.parsers` | Definition of extras fluent bit parsers. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/filter/parser). The format is a sequence of mappings where each key is the same as the one in the [PARSER] section of parsers.conf file | `[]` | +| `config.extraOutputs` | Definition of extras fluent bit outputs. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/pipeline/outputs/). The format is a sequence of mappings where each key is the same as the one in the [OUTPUT] | `[]` | +| `affinity` | [affinity][affinity] settings for pod assignment | `{}` | +| `annotations` | Annotations to add to Kubernetes resources. | `{}` | +| `deploymentStrategy` | The deployment strategy to use with the daemonset | `RollingUpdate` | +| `image.repository` | The Fluent Bit docker image repository | `grafana/fluent-bit-plugin-loki` | +| `image.tag` | The Fluent Bit docker image tag | `0.1` | +| `image.pullPolicy` | The Fluent Bit docker image pull policy | `IfNotPresent` | +| `nodeSelector` | Fluent Bit [node labels][nodeSelector] for pod assignment | `{}` | +| `podLabels` | additional Fluent Bit pod labels | `{}` | +| `podAnnotations` | additional Fluent Bit pod annotations | `Prometheus discovery` | +| `rbac.create` | Activate support for RBAC | `true` | +| `resources` | Resource requests/limit | | +| `tolerations` | [Toleration][toleration] labels for pod assignment | `no schedule on master nodes` | +| `volumes` | [Volume]([volumes]) to mount | `host containers log` | +| `volumeMounts` | Volume mount mapping | | +| `serviceMonitor.enabled` | Create a [Prometheus Operator](operator) serviceMonitor resource for Fluent Bit | `false` | + + +[toleration]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[nodeSelector]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +[volumes]: https://kubernetes.io/docs/concepts/storage/volumes/ +[operator]: https://github.com/coreos/prometheus-operator diff --git a/charts/fluent-bit/templates/NOTES.txt b/charts/fluent-bit/templates/NOTES.txt new file mode 100644 index 0000000000..bbb70770b8 --- /dev/null +++ b/charts/fluent-bit/templates/NOTES.txt @@ -0,0 +1,3 @@ +Verify the application is working by running these commands: + kubectl --namespace {{ .Release.Namespace }} port-forward daemonset/{{ include "fluent-bit-loki.fullname" . }} {{ .Values.config.port }} + curl http://127.0.0.1:{{ .Values.config.port }}/api/v1/metrics/prometheus diff --git a/charts/fluent-bit/templates/_helpers.tpl b/charts/fluent-bit/templates/_helpers.tpl new file mode 100644 index 0000000000..ddbbe85a1f --- /dev/null +++ b/charts/fluent-bit/templates/_helpers.tpl @@ -0,0 +1,66 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "fluent-bit-loki.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 "fluent-bit-loki.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 "fluent-bit-loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "fluent-bit-loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "fluent-bit-loki.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{- define "helm-toolkit.utils.joinListWithComma" -}} +{{- $local := dict "first" true -}} +{{- range $k, $v := . -}}{{- if not $local.first -}},{{- end -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} +{{- end -}} diff --git a/charts/fluent-bit/templates/clusterrole.yaml b/charts/fluent-bit/templates/clusterrole.yaml new file mode 100644 index 0000000000..6b1a27c2fe --- /dev/null +++ b/charts/fluent-bit/templates/clusterrole.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrole +rules: +- apiGroups: [""] # "" indicates the core API group + resources: + - namespaces + - pods + verbs: ["get", "watch", "list"] +{{- end }} diff --git a/charts/fluent-bit/templates/clusterrolebinding.yaml b/charts/fluent-bit/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..f825c97bf6 --- /dev/null +++ b/charts/fluent-bit/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrolebinding + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ template "fluent-bit-loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrole + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/fluent-bit/templates/configmap.yaml b/charts/fluent-bit/templates/configmap.yaml new file mode 100644 index 0000000000..3022647906 --- /dev/null +++ b/charts/fluent-bit/templates/configmap.yaml @@ -0,0 +1,72 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + fluent-bit.conf: |- + [SERVICE] + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_PORT {{ .Values.config.port }} + Flush 1 + Daemon Off + Log_Level {{ .Values.config.loglevel }} + Parsers_File parsers.conf + [INPUT] + Name tail + Tag kube.* + Path /var/log/containers/*.log + Parser docker + DB /run/fluent-bit/flb_kube.db + Mem_Buf_Limit 5MB + [FILTER] + Name kubernetes + Match kube.* + Kube_URL https://kubernetes.default.svc:443 + Merge_Log On + K8S-Logging.Parser {{ .Values.config.k8sLoggingParser }} + [Output] + Name loki + Match * + {{- if and .Values.loki.user .Values.loki.password }} + Url {{ .Values.loki.serviceScheme }}://{{ .Values.loki.user }}:{{ .Values.loki.password }}@{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}{{ .Values.loki.servicePath }} + {{- else }} + Url {{ .Values.loki.serviceScheme }}://{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}{{ .Values.loki.servicePath }} + {{- end }} + TenantID {{ .Values.config.tenantID }} + BatchWait {{ .Values.config.batchWait }} + BatchSize {{ .Values.config.batchSize }} + Labels {{ .Values.config.labels }} + RemoveKeys {{ include "helm-toolkit.utils.joinListWithComma" .Values.config.removeKeys }} + AutoKubernetesLabels {{ .Values.config.autoKubernetesLabels }} + LabelMapPath /fluent-bit/etc/labelmap.json + LineFormat {{ .Values.config.lineFormat }} + LogLevel {{ .Values.config.loglevel }} + {{- range $extraOutput := .Values.config.extraOutputs }} + [OUTPUT] + {{- range $key,$value := $extraOutput }} + {{ $key }} {{ $value }} + {{- end }} + {{- end }} + parsers.conf: |- + [PARSER] + Name docker + Format json + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + {{- range $parser:= .Values.config.parsers }} + [PARSER] + {{- range $key,$value := $parser }} + {{ $key }} {{ $value }} + {{- end }} + {{- end }} + + labelmap.json: |- + {{- .Values.config.labelMap | toPrettyJson | nindent 4}} + diff --git a/charts/fluent-bit/templates/daemonset.yaml b/charts/fluent-bit/templates/daemonset.yaml new file mode 100644 index 0000000000..6652c29646 --- /dev/null +++ b/charts/fluent-bit/templates/daemonset.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + {{- toYaml .Values.annotations | nindent 4 }} +spec: + selector: + matchLabels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} + updateStrategy: + type: {{ .Values.deploymentStrategy }} + {{- if ne .Values.deploymentStrategy "RollingUpdate" }} + rollingUpdate: null + {{- end }} + template: + metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "fluent-bit-loki.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + containers: + - name: fluent-bit-loki + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: config + mountPath: /fluent-bit/etc + - name: run + mountPath: /run/fluent-bit + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - containerPort: {{ .Values.config.port }} + name: http-metrics + resources: + {{- toYaml .Values.resources | nindent 12 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + terminationGracePeriodSeconds: 10 + volumes: + - name: config + configMap: + name: {{ template "fluent-bit-loki.fullname" . }} + - name: run + hostPath: + path: /run/fluent-bit + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/fluent-bit/templates/podsecuritypolicy.yaml b/charts/fluent-bit/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..a38514e679 --- /dev/null +++ b/charts/fluent-bit/templates/podsecuritypolicy.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'secret' + - 'configMap' + - 'hostPath' + - 'projected' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL +{{- end }} diff --git a/charts/fluent-bit/templates/role.yaml b/charts/fluent-bit/templates/role.yaml new file mode 100644 index 0000000000..036c2889a7 --- /dev/null +++ b/charts/fluent-bit/templates/role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.rbac.pspEnabled }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "fluent-bit-loki.fullname" . }}] +{{- end }} +{{- end }} diff --git a/charts/fluent-bit/templates/rolebinding.yaml b/charts/fluent-bit/templates/rolebinding.yaml new file mode 100644 index 0000000000..90315e85c1 --- /dev/null +++ b/charts/fluent-bit/templates/rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "fluent-bit-loki.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "fluent-bit-loki.serviceAccountName" . }} +{{- end }} diff --git a/charts/fluent-bit/templates/service-headless.yaml b/charts/fluent-bit/templates/service-headless.yaml new file mode 100644 index 0000000000..332d1063d1 --- /dev/null +++ b/charts/fluent-bit/templates/service-headless.yaml @@ -0,0 +1,22 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "fluent-bit-loki.fullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + clusterIP: None + ports: + - port: {{ .Values.config.port }} + protocol: TCP + name: http-metrics + targetPort: http-metrics + selector: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/charts/fluent-bit/templates/serviceaccount.yaml b/charts/fluent-bit/templates/serviceaccount.yaml new file mode 100644 index 0000000000..7933b61e97 --- /dev/null +++ b/charts/fluent-bit/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "fluent-bit-loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/fluent-bit/templates/servicemonitor.yaml b/charts/fluent-bit/templates/servicemonitor.yaml new file mode 100644 index 0000000000..162f96018f --- /dev/null +++ b/charts/fluent-bit/templates/servicemonitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} + {{- if .Values.serviceMonitor.annotations }} + annotations: +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + endpoints: + - port: http-metrics + path: /api/v1/metrics/prometheus + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} +{{- end }} diff --git a/charts/fluent-bit/values.yaml b/charts/fluent-bit/values.yaml new file mode 100644 index 0000000000..dd099f8d86 --- /dev/null +++ b/charts/fluent-bit/values.yaml @@ -0,0 +1,118 @@ +--- +loki: + serviceName: "" # Defaults to "${RELEASE}-loki" if not set + servicePort: 3100 + serviceScheme: http + servicePath: /api/prom/push + # user: user + # password: pass +config: + port: 2020 + tenantID: '""' + batchWait: 1 + batchSize: 1048576 + loglevel: warn + lineFormat: json + k8sLoggingParser: "Off" + removeKeys: + - kubernetes + - stream + autoKubernetesLabels: false + labels: '{job="fluent-bit"}' + labelMap: + kubernetes: + namespace_name: namespace + labels: + app: app + release: release + host: node + container_name: container + pod_name: instance + stream: stream + # parsers: # Allow to define custom parsers. The key here is the same as the one in the [PARSER] section of parsers.conf file. + # - Name: json + # Format: json + # Time_Key: time + # Time_Format: "%d/%b/%Y:%H:%M:%S %z" + + # extraOutputs: # Allow to define extra outputs in addition to the one automatically created + # - Name: stdout + # Format: json + # json_date_format: time + +affinity: {} + +annotations: {} + +deploymentStrategy: RollingUpdate + +image: + repository: grafana/fluent-bit-plugin-loki + tag: 1.6.0-amd64 + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be present in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + # pullSecrets: + # - myRegistrKeySecretName + +nameOverride: fluent-bit-loki + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} + +## Pod Labels +podLabels: {} + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "2020" + prometheus.io/path: /api/v1/metrics/prometheus + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +rbac: + create: true + pspEnabled: true + +resources: + limits: + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + +serviceAccount: + create: true + name: + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: +- key: node-role.kubernetes.io/master + effect: NoSchedule + +# Extra volumes to scrape logs from +volumes: +- name: varlog + hostPath: + path: /var/log +- name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + +volumeMounts: +- name: varlog + mountPath: /var/log +- name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + +serviceMonitor: + enabled: false + interval: "" + additionalLabels: {} + annotations: {} + # scrapeTimeout: 10s diff --git a/charts/loki-stack/.helmignore b/charts/loki-stack/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/charts/loki-stack/.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-stack/Chart.yaml b/charts/loki-stack/Chart.yaml new file mode 100644 index 0000000000..00e770b6d1 --- /dev/null +++ b/charts/loki-stack/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: "v1" +name: loki-stack +version: 0.42.0 +appVersion: v1.6.0 +kubeVersion: "^1.10.0-0" +description: "Loki: like Prometheus, but for logs." +home: https://grafana.com/loki +icon: https://github.com/grafana/loki/raw/master/docs/logo.png +sources: +- https://github.com/grafana/loki +maintainers: +- name: Loki Maintainers + email: lokiproject@googlegroups.com +engine: gotpl diff --git a/charts/loki-stack/README.md b/charts/loki-stack/README.md new file mode 100644 index 0000000000..41bd9147cf --- /dev/null +++ b/charts/loki-stack/README.md @@ -0,0 +1,61 @@ +# Loki-Stack Helm Chart + +## Prerequisites + +Make sure you have Helm [installed](https://helm.sh/docs/using_helm/#installing-helm) installed. + +## 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._ + +## Deploy Loki and Promtail to your cluster + +### Deploy with default config + +```bash +helm upgrade --install loki grafana/loki-stack +``` + +### Deploy in a custom namespace + +```bash +helm upgrade --install loki --namespace=loki-stack grafana/loki-stack +``` + +### Deploy with custom config + +```bash +helm upgrade --install loki grafana/loki-stack --set "key1=val1,key2=val2,..." +``` + +## Deploy Loki and Fluent Bit to your cluster + +```bash +helm upgrade --install loki loki/loki-stack \ + --set fluent-bit.enabled=true,promtail.enabled=false +``` + +## Deploy Grafana to your cluster + +The chart loki-stack contains a pre-configured Grafana, simply use `--set grafana.enabled=true` + +To get the admin password for the Grafana pod, run the following command: + +```bash +kubectl get secret --namespace loki-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo +``` + +To access the Grafana UI, run the following command: + +```bash +kubectl port-forward --namespace service/loki-grafana 3000:80 +``` + +Navigate to and login with `admin` and the password output above. +Then follow the [instructions for adding the loki datasource](/docs/getting-started/grafana.md), using the URL `http://loki:3100/`. + diff --git a/charts/loki-stack/requirements.yaml b/charts/loki-stack/requirements.yaml new file mode 100644 index 0000000000..aa0d0d6ebc --- /dev/null +++ b/charts/loki-stack/requirements.yaml @@ -0,0 +1,29 @@ +dependencies: +- name: "loki" + condition: loki.enabled + repository: "file://../loki" + version: "^0.32.0" +- name: "promtail" + condition: promtail.enabled + repository: "file://../promtail" + version: "^0.26.0" +- name: "fluent-bit" + condition: fluent-bit.enabled + repository: "file://../fluent-bit" + version: "^0.4.0" +- name: "grafana" + condition: grafana.enabled + version: "~3.8.15" + repository: "https://kubernetes-charts.storage.googleapis.com/" +- name: "prometheus" + condition: prometheus.enabled + version: "~9.3.0" + repository: "https://kubernetes-charts.storage.googleapis.com/" +- name: "filebeat" + condition: filebeat.enabled + version: "~7.8.0" + repository: "https://helm.elastic.co" +- name: "logstash" + condition: logstash.enabled + version: "~2.4.0" + repository: "https://kubernetes-charts.storage.googleapis.com/" diff --git a/charts/loki-stack/templates/NOTES.txt b/charts/loki-stack/templates/NOTES.txt new file mode 100644 index 0000000000..d9cdccbeed --- /dev/null +++ b/charts/loki-stack/templates/NOTES.txt @@ -0,0 +1,3 @@ +The Loki stack has been deployed to your cluster. Loki can now be added as a datasource in Grafana. + +See http://docs.grafana.org/features/datasources/loki/ for more detail. diff --git a/charts/loki-stack/templates/_helpers.tpl b/charts/loki-stack/templates/_helpers.tpl new file mode 100644 index 0000000000..1cb7269e80 --- /dev/null +++ b/charts/loki-stack/templates/_helpers.tpl @@ -0,0 +1,58 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "loki-stack.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 "loki-stack.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 "loki-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Override the naming defined by the prometheus chart. +Added as a fix for https://github.com/grafana/loki/issues/1169 +*/}} +{{- define "prometheus.fullname" -}} +{{- printf "%s-%s" .Release.Name "prometheus-server" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/loki-stack/templates/datasources.yaml b/charts/loki-stack/templates/datasources.yaml new file mode 100644 index 0000000000..29e2f4f33a --- /dev/null +++ b/charts/loki-stack/templates/datasources.yaml @@ -0,0 +1,31 @@ +{{- if .Values.grafana.sidecar.datasources.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "loki-stack.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + grafana_datasource: "1" +data: + loki-stack-datasource.yaml: |- + apiVersion: 1 + datasources: +{{- if .Values.loki.enabled }} + - name: Loki + type: loki + access: proxy + url: http://{{(include "loki.serviceName" .)}}:{{ .Values.loki.service.port }} + version: 1 +{{- end }} +{{- if .Values.prometheus.enabled }} + - name: Prometheus + type: prometheus + access: proxy + url: http://{{ include "prometheus.fullname" .}}:{{ .Values.prometheus.server.service.servicePort }}{{ .Values.prometheus.server.prefixURL }} + version: 1 +{{- end }} +{{- end }} diff --git a/charts/loki-stack/templates/tests/loki-test-configmap.yaml b/charts/loki-stack/templates/tests/loki-test-configmap.yaml new file mode 100644 index 0000000000..3e53cfde12 --- /dev/null +++ b/charts/loki-stack/templates/tests/loki-test-configmap.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "loki-stack.fullname" . }}-test + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + test.sh: | + #!/usr/bin/env bash + + LOKI_URI="http://${LOKI_SERVICE}:${LOKI_PORT}" + + function setup() { + apk add -u curl jq + until (curl -s ${LOKI_URI}/api/prom/label/app/values | jq -e '.values[] | select(. == "loki")'); do + sleep 1 + done + } + + @test "Has labels" { + curl -s ${LOKI_URI}/api/prom/label | \ + jq -e '.values[] | select(. == "app")' + } + + @test "Query log entry" { + curl -sG ${LOKI_URI}/api/prom/query?limit=10 --data-urlencode 'query={app="loki"}' | \ + jq -e '.streams[].entries | length >= 1' + } + + @test "Push log entry legacy" { + local timestamp=$(date -Iseconds -u | sed 's/UTC/.000000000+00:00/') + local data=$(jq -n --arg timestamp "${timestamp}" '{"streams": [{"labels": "{app=\"loki-test\"}", "entries": [{"ts": $timestamp, "line": "foobar"}]}]}') + + curl -s -X POST -H "Content-Type: application/json" ${LOKI_URI}/api/prom/push -d "${data}" + + curl -sG ${LOKI_URI}/api/prom/query?limit=1 --data-urlencode 'query={app="loki-test"}' | \ + jq -e '.streams[].entries[].line == "foobar"' + } + + @test "Push log entry" { + local timestamp=$(date +%s000000000) + local data=$(jq -n --arg timestamp "${timestamp}" '{"streams": [{"stream": {"app": "loki-test"}, "values": [[$timestamp, "foobar"]]}]}') + + curl -s -X POST -H "Content-Type: application/json" ${LOKI_URI}/loki/api/v1/push -d "${data}" + + curl -sG ${LOKI_URI}/api/prom/query?limit=1 --data-urlencode 'query={app="loki-test"}' | \ + jq -e '.streams[].entries[].line == "foobar"' + } + diff --git a/charts/loki-stack/templates/tests/loki-test-pod.yaml b/charts/loki-stack/templates/tests/loki-test-pod.yaml new file mode 100644 index 0000000000..a153a05df9 --- /dev/null +++ b/charts/loki-stack/templates/tests/loki-test-pod.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + "helm.sh/hook": test-success + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + name: {{ template "loki-stack.fullname" . }}-test +spec: + containers: + - name: test + image: bats/bats:v1.1.0 + args: + - /var/lib/loki/test.sh + env: + - name: LOKI_SERVICE + value: {{ template "loki.serviceName" . }} + - name: LOKI_PORT + value: "{{ .Values.loki.service.port }}" + volumeMounts: + - name: tests + mountPath: /var/lib/loki + restartPolicy: Never + volumes: + - name: tests + configMap: + name: {{ template "loki-stack.fullname" . }}-test diff --git a/charts/loki-stack/values.yaml b/charts/loki-stack/values.yaml new file mode 100644 index 0000000000..4fc181b226 --- /dev/null +++ b/charts/loki-stack/values.yaml @@ -0,0 +1,70 @@ +loki: + enabled: true + +promtail: + enabled: true + +fluent-bit: + enabled: false + +grafana: + enabled: false + sidecar: + datasources: + enabled: true + image: + tag: 6.7.0 + +prometheus: + enabled: false + +filebeat: + enabled: false + filebeatConfig: + filebeat.yml: | + # logging.level: debug + filebeat.inputs: + - type: container + paths: + - /var/log/containers/*.log + processors: + - add_kubernetes_metadata: + host: ${NODE_NAME} + matchers: + - logs_path: + logs_path: "/var/log/containers/" + output.logstash: + hosts: ["logstash-loki:5044"] + +logstash: + enabled: false + image: + repository: grafana/logstash-output-loki + tag: 1.0.1 + filters: + main: |- + filter { + if [kubernetes] { + mutate { + add_field => { + "container_name" => "%{[kubernetes][container][name]}" + "namespace" => "%{[kubernetes][namespace]}" + "pod" => "%{[kubernetes][pod][name]}" + } + replace => { "host" => "%{[kubernetes][node][name]}"} + } + } + mutate { + remove_field => ["tags"] + } + } + outputs: + main: |- + output { + loki { + url => "http://loki:3100/loki/api/v1/push" + #username => "test" + #password => "test" + } + # stdout { codec => rubydebug } + } diff --git a/charts/loki/.helmignore b/charts/loki/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/charts/loki/.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/Chart.yaml b/charts/loki/Chart.yaml new file mode 100644 index 0000000000..e663acd7f0 --- /dev/null +++ b/charts/loki/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: "v1" +name: loki +version: 0.32.0 +appVersion: v1.6.0 +kubeVersion: "^1.10.0-0" +description: "Loki: like Prometheus, but for logs." +home: https://grafana.com/loki +icon: https://github.com/grafana/loki/raw/master/docs/logo.png +sources: + - https://github.com/grafana/loki +maintainers: + - name: Loki Maintainers + email: lokiproject@googlegroups.com +engine: gotpl diff --git a/charts/loki/README.md b/charts/loki/README.md new file mode 100644 index 0000000000..4eeda3c689 --- /dev/null +++ b/charts/loki/README.md @@ -0,0 +1,60 @@ +# Loki Helm Chart + +## Prerequisites + +Make sure you have Helm [installed](https://helm.sh/docs/using_helm/#installing-helm). + +## 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._ + + +## Deploy Loki only + +```bash +helm upgrade --install loki grafana/loki +``` + +## Run Loki behind https ingress + +If Loki and Promtail are deployed on different clusters you can add an Ingress in front of Loki. +By adding a certificate you create an https endpoint. For extra security enable basic authentication on the Ingress. + +In Promtail set the following values to communicate with https and basic auth + +```yaml +loki: + serviceScheme: https + user: user + password: pass +``` + +Sample helm template for ingress: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: +annotations: + kubernetes.io/ingress.class: {{ .Values.ingress.class }} + ingress.kubernetes.io/auth-type: "basic" + ingress.kubernetes.io/auth-secret: {{ .Values.ingress.basic.secret }} +name: loki +spec: +rules: +- host: {{ .Values.ingress.host }} + http: + paths: + - backend: + serviceName: loki + servicePort: 3100 +tls: +- secretName: {{ .Values.ingress.cert }} + hosts: + - {{ .Values.ingress.host }} +``` diff --git a/charts/loki/templates/NOTES.txt b/charts/loki/templates/NOTES.txt new file mode 100644 index 0000000000..abe023a700 --- /dev/null +++ b/charts/loki/templates/NOTES.txt @@ -0,0 +1,3 @@ +Verify the application is working by running these commands: + kubectl --namespace {{ .Release.Namespace }} port-forward service/{{ include "loki.fullname" . }} {{ .Values.service.port }} + curl http://127.0.0.1:{{ .Values.service.port }}/api/prom/label diff --git a/charts/loki/templates/_helpers.tpl b/charts/loki/templates/_helpers.tpl new file mode 100644 index 0000000000..5e12a470f1 --- /dev/null +++ b/charts/loki/templates/_helpers.tpl @@ -0,0 +1,61 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "loki.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 "loki.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 "loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "loki.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the app name of loki clients. Defaults to the same logic as "loki.fullname", and default client expects "promtail". +*/}} +{{- define "client.name" -}} +{{- if .Values.client.name -}} +{{- .Values.client.name -}} +{{- else if .Values.client.fullnameOverride -}} +{{- .Values.client.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "promtail" .Values.client.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/ingress.yaml b/charts/loki/templates/ingress.yaml new file mode 100644 index 0000000000..f68cda8ea5 --- /dev/null +++ b/charts/loki/templates/ingress.yaml @@ -0,0 +1,45 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "loki.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- 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: {{ . }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/networkpolicy.yaml b/charts/loki/templates/networkpolicy.yaml new file mode 100644 index 0000000000..5d73832296 --- /dev/null +++ b/charts/loki/templates/networkpolicy.yaml @@ -0,0 +1,26 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + name: {{ template "loki.fullname" . }} + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app: {{ template "client.name" . }} + release: {{ .Release.Name }} + - ports: + - port: {{ .Values.service.port }} +{{- end }} diff --git a/charts/loki/templates/pdb.yaml b/charts/loki/templates/pdb.yaml new file mode 100644 index 0000000000..c64ad507ed --- /dev/null +++ b/charts/loki/templates/pdb.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget -}} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + chart: {{ template "loki.chart" . }} +spec: + selector: + matchLabels: + app: {{ template "loki.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/charts/loki/templates/podsecuritypolicy.yaml b/charts/loki/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..ce1c1c109a --- /dev/null +++ b/charts/loki/templates/podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "loki.fullname" . }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'persistentVolumeClaim' + - 'secret' + - 'projected' + - 'downwardAPI' + 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/role.yaml b/charts/loki/templates/role.yaml new file mode 100644 index 0000000000..b7bfb29d68 --- /dev/null +++ b/charts/loki/templates/role.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.rbac.pspEnabled }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "loki.fullname" . }}] +{{- end }} +{{- end }} + diff --git a/charts/loki/templates/rolebinding.yaml b/charts/loki/templates/rolebinding.yaml new file mode 100644 index 0000000000..41fc5039fe --- /dev/null +++ b/charts/loki/templates/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "loki.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "loki.serviceAccountName" . }} +{{- end }} + diff --git a/charts/loki/templates/secret.yaml b/charts/loki/templates/secret.yaml new file mode 100644 index 0000000000..40d50c8ee8 --- /dev/null +++ b/charts/loki/templates/secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + loki.yaml: {{ tpl (toYaml .Values.config) . | b64enc}} diff --git a/charts/loki/templates/service-headless.yaml b/charts/loki/templates/service-headless.yaml new file mode 100644 index 0000000000..644f527625 --- /dev/null +++ b/charts/loki/templates/service-headless.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "loki.fullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + variant: headless +spec: + clusterIP: None + ports: + - port: {{ .Values.service.port }} + protocol: TCP + name: http-metrics + targetPort: http-metrics +{{- if .Values.extraPorts }} +{{ toYaml .Values.extraPorts | indent 4}} +{{- end }} + selector: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} diff --git a/charts/loki/templates/service.yaml b/charts/loki/templates/service.yaml new file mode 100644 index 0000000000..2eb419c02f --- /dev/null +++ b/charts/loki/templates/service.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + type: {{ .Values.service.type }} +{{- if (and (eq .Values.service.type "ClusterIP") (not (empty .Values.service.clusterIP))) }} + clusterIP: {{ .Values.service.clusterIP }} +{{- end }} +{{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} +{{- end }} +{{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - port: {{ .Values.service.port }} + protocol: TCP + name: http-metrics + targetPort: http-metrics +{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} +{{- if .Values.extraPorts }} +{{ toYaml .Values.extraPorts | indent 4}} +{{- end }} + selector: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} diff --git a/charts/loki/templates/serviceaccount.yaml b/charts/loki/templates/serviceaccount.yaml new file mode 100644 index 0000000000..ccbad8d926 --- /dev/null +++ b/charts/loki/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} + name: {{ template "loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} + diff --git a/charts/loki/templates/servicemonitor.yaml b/charts/loki/templates/servicemonitor.yaml new file mode 100644 index 0000000000..f3b4abe532 --- /dev/null +++ b/charts/loki/templates/servicemonitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "loki.fullname" . }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} + {{- if .Values.serviceMonitor.annotations }} + annotations: +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app: {{ template "loki.name" . }} + release: {{ .Release.Name | quote }} + variant: headless + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + endpoints: + - port: http-metrics + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/statefulset.yaml b/charts/loki/templates/statefulset.yaml new file mode 100644 index 0000000000..a993cc9349 --- /dev/null +++ b/charts/loki/templates/statefulset.yaml @@ -0,0 +1,131 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + {{- toYaml .Values.annotations | nindent 4 }} +spec: + podManagementPolicy: {{ .Values.podManagementPolicy }} + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} + serviceName: {{ template "loki.fullname" . }}-headless + updateStrategy: + {{- toYaml .Values.updateStrategy | nindent 4 }} + template: + metadata: + labels: + app: {{ template "loki.name" . }} + name: {{ template "loki.name" . }} + release: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.securityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.initContainers | nindent 8 }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-config.file=/etc/loki/loki.yaml" + {{- range $key, $value := .Values.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + {{- if .Values.extraVolumeMounts }} + {{ toYaml .Values.extraVolumeMounts | nindent 12}} + {{- end }} + - name: config + mountPath: /etc/loki + - name: storage + mountPath: "/data" + subPath: {{ .Values.persistence.subPath }} + ports: + - name: http-metrics + containerPort: {{ .Values.config.server.http_listen_port }} + protocol: TCP + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + readOnlyRootFilesystem: true + env: + {{- if .Values.env }} + {{- toYaml .Values.env | nindent 12 }} + {{- end }} + {{- if .Values.tracing.jaegerAgentHost }} + - name: JAEGER_AGENT_HOST + value: "{{ .Values.tracing.jaegerAgentHost }}" + {{- end }} +{{- if .Values.extraContainers }} +{{ toYaml .Values.extraContainers | indent 8}} +{{- end }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + volumes: + - name: config + secret: + secretName: {{ template "loki.fullname" . }} +{{- if .Values.extraVolumes }} +{{ toYaml .Values.extraVolumes | indent 8}} +{{- end }} + {{- if not .Values.persistence.enabled }} + - name: storage + emptyDir: {} + {{- else if .Values.persistence.existingClaim }} + - name: storage + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim }} + {{- else }} + volumeClaimTemplates: + - metadata: + name: storage + annotations: + {{- toYaml .Values.persistence.annotations | nindent 8 }} + spec: + accessModes: + {{- toYaml .Values.persistence.accessModes | nindent 8 }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- if .Values.persistence.selector }} + selector: + {{- toYaml .Values.persistence.selector | nindent 8 }} + {{- end }} + {{- end }} diff --git a/charts/loki/values.yaml b/charts/loki/values.yaml new file mode 100644 index 0000000000..3b6806eaed --- /dev/null +++ b/charts/loki/values.yaml @@ -0,0 +1,244 @@ +image: + repository: grafana/loki + tag: 1.6.0 + pullPolicy: IfNotPresent + + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +## Affinity for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} +# podAntiAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# - labelSelector: +# matchExpressions: +# - key: app +# operator: In +# values: +# - loki +# topologyKey: "kubernetes.io/hostname" + +## StatefulSet annotations +annotations: {} + +# enable tracing for debug, need install jaeger and specify right jaeger_agent_host +tracing: + jaegerAgentHost: + +config: + auth_enabled: false + ingester: + chunk_idle_period: 3m + chunk_block_size: 262144 + chunk_retain_period: 1m + max_transfer_retries: 0 + lifecycler: + ring: + kvstore: + store: inmemory + replication_factor: 1 + + ## Different ring configs can be used. E.g. Consul + # ring: + # store: consul + # replication_factor: 1 + # consul: + # host: "consul:8500" + # prefix: "" + # http_client_timeout: "20s" + # consistent_reads: true + limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 168h + schema_config: + configs: + - from: 2018-04-15 + store: boltdb + object_store: filesystem + schema: v9 + index: + prefix: index_ + period: 168h + server: + http_listen_port: 3100 + storage_config: + boltdb: + directory: /data/loki/index + filesystem: + directory: /data/loki/chunks + chunk_store_config: + max_look_back_period: 0s + table_manager: + retention_deletes_enabled: false + retention_period: 0s + +## Additional Loki container arguments, e.g. log level (debug, info, warn, error) +extraArgs: {} + # log.level: debug + +livenessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +networkPolicy: + enabled: false + +## The app name of loki clients +client: {} + # name: + +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} + +## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ +## If you set enabled as "True", you need : +## - create a pv which above 10Gi and has same namespace with loki +## - keep storageClassName same with below setting +persistence: + enabled: false + accessModes: + - ReadWriteOnce + size: 10Gi + annotations: {} + # selector: + # matchLabels: + # app.kubernetes.io/name: loki + # subPath: "" + # existingClaim: + +## Pod Labels +podLabels: {} + +## Pod Annotations +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "http-metrics" + +podManagementPolicy: OrderedReady + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +rbac: + create: true + pspEnabled: true + +readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + +replicas: 1 + +resources: {} +# limits: +# cpu: 200m +# memory: 256Mi +# requests: +# cpu: 100m +# memory: 128Mi + +securityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + +service: + type: ClusterIP + nodePort: + port: 3100 + annotations: {} + labels: {} + +serviceAccount: + create: true + name: + annotations: {} + +terminationGracePeriodSeconds: 4800 + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# The values to set in the PodDisruptionBudget spec +# If not set then a PodDisruptionBudget will not be created +podDisruptionBudget: {} +# minAvailable: 1 +# maxUnavailable: 1 + +updateStrategy: + type: RollingUpdate + +serviceMonitor: + enabled: false + interval: "" + additionalLabels: {} + annotations: {} + # scrapeTimeout: 10s + +initContainers: [] +## Init containers to be added to the loki pod. +# - name: my-init-container +# image: busybox:latest +# command: ['sh', '-c', 'echo hello'] + +extraContainers: [] +## Additional containers to be added to the loki pod. +# - name: reverse-proxy +# image: angelbarrera92/basic-auth-reverse-proxy:dev +# args: +# - "serve" +# - "--upstream=http://localhost:3100" +# - "--auth-config=/etc/reverse-proxy-conf/authn.yaml" +# ports: +# - name: http +# containerPort: 11811 +# protocol: TCP +# volumeMounts: +# - name: reverse-proxy-auth-config +# mountPath: /etc/reverse-proxy-conf + + +extraVolumes: [] +## Additional volumes to the loki pod. +# - name: reverse-proxy-auth-config +# secret: +# secretName: reverse-proxy-auth-config + +## Extra volume mounts that will be added to the loki container +extraVolumeMounts: [] + +extraPorts: [] +## Additional ports to the loki services. Useful to expose extra container ports. +# - port: 11811 +# protocol: TCP +# name: http +# targetPort: http + +# Extra env variables to pass to the loki container +env: [] diff --git a/charts/promtail/.helmignore b/charts/promtail/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/charts/promtail/.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/promtail/Chart.yaml b/charts/promtail/Chart.yaml new file mode 100644 index 0000000000..b4a50591d8 --- /dev/null +++ b/charts/promtail/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: "v1" +name: promtail +version: 0.26.0 +appVersion: v1.6.0 +kubeVersion: "^1.10.0-0" +description: "Responsible for gathering logs and sending them to Loki" +home: https://grafana.com/loki +icon: https://github.com/grafana/loki/raw/master/docs/logo.png +sources: +- https://github.com/grafana/loki +maintainers: +- name: Loki Maintainers + email: lokiproject@googlegroups.com +engine: gotpl diff --git a/charts/promtail/README.md b/charts/promtail/README.md new file mode 100644 index 0000000000..ed977aceba --- /dev/null +++ b/charts/promtail/README.md @@ -0,0 +1,90 @@ +# Promtail Helm Chart + +## 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._ + +## Deploy Promtail only + +```bash +helm upgrade --install promtail grafana/promtail --set "loki.serviceName=loki" +``` + +## Run Loki behind https ingress + +If Loki and Promtail are deployed on different clusters you can add an Ingress in front of Loki. +By adding a certificate you create an https endpoint. For extra security enable basic authentication on the Ingress. + +In Promtail set the following values to communicate with https and basic auth + +```yaml +loki: + serviceScheme: https + user: user + password: pass +``` + +## Run promtail with syslog support + +In order to receive and process syslog message into promtail, the following changes will be necessary: + +* Review the [promtail syslog-receiver configuration documentation](/docs/clients/promtail/scraping.md#syslog-receiver) + +* Configure the promtail helm chart with the syslog configuration added to the `extraScrapeConfigs` section and associated service definition to listen for syslog messages. For example: + +```yaml +extraScrapeConfigs: + - job_name: syslog + syslog: + listen_address: 0.0.0.0:1514 + labels: + job: "syslog" + relabel_configs: + - source_labels: ['__syslog_message_hostname'] + target_label: 'host' +syslogService: + enabled: true + type: LoadBalancer + port: 1514 +``` + +## Run promtail with systemd-journal support + +In order to receive and process syslog message into promtail, the following changes will be necessary: + +* Review the [promtail systemd-journal configuration documentation](/docs/clients/promtail/scraping.md#journal-scraping-linux-only) + +* Configure the promtail helm chart with the systemd-journal configuration added to the `extraScrapeConfigs` section and volume mounts for the promtail pods to access the log files. For example: + +```yaml +# Add additional scrape config +extraScrapeConfigs: + - job_name: journal + journal: + path: /var/log/journal + max_age: 12h + labels: + job: systemd-journal + relabel_configs: + - source_labels: ['__journal__systemd_unit'] + target_label: 'unit' + - source_labels: ['__journal__hostname'] + target_label: 'hostname' + +# Mount journal directory into promtail pods +extraVolumes: + - name: journal + hostPath: + path: /var/log/journal + +extraVolumeMounts: + - name: journal + mountPath: /var/log/journal + readOnly: true +``` + diff --git a/charts/promtail/templates/NOTES.txt b/charts/promtail/templates/NOTES.txt new file mode 100644 index 0000000000..4d8a1a50d4 --- /dev/null +++ b/charts/promtail/templates/NOTES.txt @@ -0,0 +1,3 @@ +Verify the application is working by running these commands: + kubectl --namespace {{ .Release.Namespace }} port-forward daemonset/{{ include "promtail.fullname" . }} {{ .Values.config.server.http_listen_port }} + curl http://127.0.0.1:{{ .Values.config.server.http_listen_port }}/metrics diff --git a/charts/promtail/templates/_helpers.tpl b/charts/promtail/templates/_helpers.tpl new file mode 100644 index 0000000000..9298bcbc90 --- /dev/null +++ b/charts/promtail/templates/_helpers.tpl @@ -0,0 +1,61 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "promtail.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 "promtail.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 "promtail.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "promtail.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "promtail.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/promtail/templates/clusterrole.yaml b/charts/promtail/templates/clusterrole.yaml new file mode 100644 index 0000000000..b872041b7a --- /dev/null +++ b/charts/promtail/templates/clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + name: {{ template "promtail.fullname" . }}-clusterrole +rules: +- apiGroups: [""] # "" indicates the core API group + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + verbs: ["get", "watch", "list"] +{{- end }} diff --git a/charts/promtail/templates/clusterrolebinding.yaml b/charts/promtail/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..2b73945722 --- /dev/null +++ b/charts/promtail/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "promtail.fullname" . }}-clusterrolebinding + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ template "promtail.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "promtail.fullname" . }}-clusterrole + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/promtail/templates/configmap.yaml b/charts/promtail/templates/configmap.yaml new file mode 100644 index 0000000000..58eb9bd496 --- /dev/null +++ b/charts/promtail/templates/configmap.yaml @@ -0,0 +1,267 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + promtail.yaml: | + {{- toYaml .Values.config | nindent 4 }} + scrape_configs: + {{- if .Values.scrapeConfigs }} + {{- toYaml .Values.scrapeConfigs | nindent 4 }} + {{- else }} + - job_name: kubernetes-pods-name + pipeline_stages: + {{- toYaml .Values.pipelineStages | nindent 8 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_label_name + target_label: __service__ + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: drop + regex: '' + source_labels: + - __service__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + - job_name: kubernetes-pods-app + pipeline_stages: + {{- toYaml .Values.pipelineStages | nindent 8 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: drop + regex: .+ + source_labels: + - __meta_kubernetes_pod_label_name + - source_labels: + - __meta_kubernetes_pod_label_app + target_label: __service__ + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: drop + regex: '' + source_labels: + - __service__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + - job_name: kubernetes-pods-direct-controllers + pipeline_stages: + {{- toYaml .Values.pipelineStages | nindent 8 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: drop + regex: .+ + separator: '' + source_labels: + - __meta_kubernetes_pod_label_name + - __meta_kubernetes_pod_label_app + - action: drop + regex: '[0-9a-z-.]+-[0-9a-f]{8,10}' + source_labels: + - __meta_kubernetes_pod_controller_name + - source_labels: + - __meta_kubernetes_pod_controller_name + target_label: __service__ + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: drop + regex: '' + source_labels: + - __service__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + - job_name: kubernetes-pods-indirect-controller + pipeline_stages: + {{- toYaml .Values.pipelineStages | nindent 8 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: drop + regex: .+ + separator: '' + source_labels: + - __meta_kubernetes_pod_label_name + - __meta_kubernetes_pod_label_app + - action: keep + regex: '[0-9a-z-.]+-[0-9a-f]{8,10}' + source_labels: + - __meta_kubernetes_pod_controller_name + - action: replace + regex: '([0-9a-z-.]+)-[0-9a-f]{8,10}' + source_labels: + - __meta_kubernetes_pod_controller_name + target_label: __service__ + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: drop + regex: '' + source_labels: + - __service__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + - job_name: kubernetes-pods-static + pipeline_stages: + {{- toYaml .Values.pipelineStages | nindent 8 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: drop + regex: '' + source_labels: + - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror + - action: replace + source_labels: + - __meta_kubernetes_pod_label_component + target_label: __service__ + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: __host__ + - action: drop + regex: '' + source_labels: + - __service__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + - __service__ + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror + - __meta_kubernetes_pod_container_name + target_label: __path__ + {{- end }} + {{- if .Values.extraScrapeConfigs }} + {{- toYaml .Values.extraScrapeConfigs | nindent 4 }} + {{- end }} diff --git a/charts/promtail/templates/daemonset.yaml b/charts/promtail/templates/daemonset.yaml new file mode 100644 index 0000000000..2a22e154db --- /dev/null +++ b/charts/promtail/templates/daemonset.yaml @@ -0,0 +1,129 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + {{- toYaml .Values.annotations | nindent 4 }} +spec: + selector: + matchLabels: + app: {{ template "promtail.name" . }} + release: {{ .Release.Name }} + updateStrategy: + {{- toYaml .Values.deploymentStrategy | nindent 4 }} + template: + metadata: + labels: + app: {{ template "promtail.name" . }} + release: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "promtail.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.initContainer.enabled }} + initContainers: + - name: init + image: busybox + command: + - sh + - -c + - sysctl -w fs.inotify.max_user_instances={{ .Values.initContainer.fsInotifyMaxUserInstances }} + securityContext: + privileged: true + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + containers: + - name: promtail + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-config.file=/etc/promtail/promtail.yaml" + {{- if not (or .Values.config.client.url .Values.config.clients) }} + {{- if and .Values.loki.user .Values.loki.password }} + - "-client.url={{ .Values.loki.serviceScheme }}://{{ .Values.loki.user }}:{{ .Values.loki.password }}@{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}/loki/api/v1/push" + {{- else }} + - "-client.url={{ .Values.loki.serviceScheme }}://{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}/loki/api/v1/push" + {{- end }} + {{- end }} + {{- if .Values.extraCommandlineArgs }} + {{- range .Values.extraCommandlineArgs }} + - {{ . | quote }} + {{- end }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/promtail + - name: run + mountPath: /run/promtail + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- with .Values.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + ports: + - containerPort: {{ .Values.config.server.http_listen_port }} + name: http-metrics + {{- if .Values.syslogService.enabled }} + - containerPort: {{ .Values.syslogService.port }} + name: syslog + {{- end }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- if .Values.livenessProbe }} + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.readinessProbe }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + volumes: + - name: config + configMap: + name: {{ template "promtail.fullname" . }} + - name: run + hostPath: + path: /run/promtail + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/promtail/templates/podsecuritypolicy.yaml b/charts/promtail/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000000..56643cb5b0 --- /dev/null +++ b/charts/promtail/templates/podsecuritypolicy.yaml @@ -0,0 +1,13 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "promtail.fullname" . }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + {{- toYaml .Values.podSecurityPolicy | nindent 2 }} +{{- end }} diff --git a/charts/promtail/templates/role.yaml b/charts/promtail/templates/role.yaml new file mode 100644 index 0000000000..1f55b1deae --- /dev/null +++ b/charts/promtail/templates/role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.rbac.pspEnabled }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "promtail.fullname" . }}] +{{- end }} +{{- end }} diff --git a/charts/promtail/templates/rolebinding.yaml b/charts/promtail/templates/rolebinding.yaml new file mode 100644 index 0000000000..a035c19f8d --- /dev/null +++ b/charts/promtail/templates/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "promtail.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "promtail.serviceAccountName" . }} +{{- end }} + diff --git a/charts/promtail/templates/service-headless.yaml b/charts/promtail/templates/service-headless.yaml new file mode 100644 index 0000000000..f5f52365aa --- /dev/null +++ b/charts/promtail/templates/service-headless.yaml @@ -0,0 +1,22 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "promtail.fullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + clusterIP: None + ports: + - port: {{ .Values.config.server.http_listen_port }} + protocol: TCP + name: http-metrics + targetPort: http-metrics + selector: + app: {{ template "promtail.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/charts/promtail/templates/service-syslog.yaml b/charts/promtail/templates/service-syslog.yaml new file mode 100644 index 0000000000..247ebdfae7 --- /dev/null +++ b/charts/promtail/templates/service-syslog.yaml @@ -0,0 +1,50 @@ +{{- if .Values.syslogService.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "promtail.fullname" . }}-syslog + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.syslogService.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .Values.syslogService.annotations | nindent 4 }} +spec: + type: {{ .Values.syslogService.type }} + {{- if .Values.syslogService.clusterIP }} + clusterIP: {{ .Values.syslogService.clusterIP }} + {{end}} + {{- if .Values.syslogService.loadBalancerIP }} + loadBalancerIP: {{ .Values.syslogService.loadBalancerIP }} + {{- end }} + {{- if .Values.syslogService.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.syslogService.loadBalancerSourceRanges | indent 4 }} + {{- end -}} + {{- if .Values.syslogService.externalIPs }} + externalIPs: +{{ toYaml .Values.syslogService.externalIPs | indent 4 }} + {{- end }} + {{- if .Values.syslogService.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.syslogService.externalTrafficPolicy }} + {{- end }} + ports: + - port: {{ .Values.syslogService.port }} + protocol: TCP + name: syslog + targetPort: syslog +{{- if (and (eq .Values.syslogService.type "NodePort") (not (empty .Values.syslogService.nodePort))) }} + nodePort: {{ .Values.syslogService.nodePort }} +{{- end }} +{{- if .Values.extraPorts }} +{{ toYaml .Values.extraPorts | indent 4}} +{{- end }} + selector: + app: {{ template "promtail.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/charts/promtail/templates/serviceaccount.yaml b/charts/promtail/templates/serviceaccount.yaml new file mode 100644 index 0000000000..9181d98a25 --- /dev/null +++ b/charts/promtail/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "promtail.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} + diff --git a/charts/promtail/templates/servicemonitor.yaml b/charts/promtail/templates/servicemonitor.yaml new file mode 100644 index 0000000000..7b2d3bef6d --- /dev/null +++ b/charts/promtail/templates/servicemonitor.yaml @@ -0,0 +1,34 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "promtail.fullname" . }} + labels: + app: {{ template "promtail.name" . }} + chart: {{ template "promtail.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} + {{- if .Values.serviceMonitor.annotations }} + annotations: +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app: {{ template "promtail.name" . }} + release: {{ .Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + endpoints: + - port: http-metrics + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} +{{- end }} diff --git a/charts/promtail/values.yaml b/charts/promtail/values.yaml new file mode 100644 index 0000000000..20933b2b5b --- /dev/null +++ b/charts/promtail/values.yaml @@ -0,0 +1,219 @@ +## Affinity for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +annotations: {} + +# The update strategy to apply to the DaemonSet +## +deploymentStrategy: {} +# rollingUpdate: +# maxUnavailable: 1 +# type: RollingUpdate + +initContainer: + enabled: false + fsInotifyMaxUserInstances: 128 + +image: + repository: grafana/promtail + tag: 1.6.0 + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +livenessProbe: {} + +loki: + serviceName: "" # Defaults to "${RELEASE}-loki" if not set + servicePort: 3100 + serviceScheme: http + # user: user + # password: pass + +nameOverride: promtail + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} + +pipelineStages: +- docker: {} + +## Pod Labels +podLabels: {} + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "http-metrics" + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +rbac: + create: true + pspEnabled: true + +podSecurityPolicy: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'secret' + - 'configMap' + - 'hostPath' + - 'projected' + - 'downwardAPI' + - 'emptyDir' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL + +readinessProbe: + failureThreshold: 5 + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +resources: {} +# limits: +# cpu: 200m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +# Custom scrape_configs to override the default ones in the configmap +scrapeConfigs: [] + +# Custom scrape_configs together with the default ones in the configmap +extraScrapeConfigs: [] + +securityContext: + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsUser: 0 + +serviceAccount: + create: true + name: + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: +- key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + +# Extra volumes to scrape logs from +volumes: +- name: docker + hostPath: + path: /var/lib/docker/containers +- name: pods + hostPath: + path: /var/log/pods + +# Custom volumes together with the default ones +extraVolumes: [] + +volumeMounts: +- name: docker + mountPath: /var/lib/docker/containers + readOnly: true +- name: pods + mountPath: /var/log/pods + readOnly: true + +# Custom volumeMounts together with the default ones +extraVolumeMounts: [] + +# Add extra Commandline args while starting up promtail. +# more info : https://github.com/grafana/loki/pull/1530 + +extraCommandlineArgs: [] +# example: +# extraCommandlineArgs: +# - -client.external-labels=hostname=$(HOSTNAME) + +config: + client: + # Maximum wait period before sending batch + batchwait: 1s + # Maximum batch size to accrue before sending, unit is byte + batchsize: 1048576 + + # Maximum time to wait for server to respond to a request + timeout: 10s + + backoff_config: + # Initial backoff time between retries + min_period: 500ms + # Maximum backoff time between retries + max_period: 5m + # Maximum number of retries when sending batches, 0 means infinite retries + max_retries: 10 + + # The labels to add to any time series or alerts when communicating with loki + external_labels: {} + + server: + http_listen_port: 3101 + + positions: + filename: /run/promtail/positions.yaml + target_config: + # Period to resync directories being watched and files being tailed + sync_period: 10s + +serviceMonitor: + enabled: false + interval: "" + additionalLabels: {} + annotations: {} + # scrapeTimeout: 10s + +# Extra env variables to pass to the promtail container +env: [] + +# enable and configure if using the syslog scrape config +syslogService: + enabled: false + type: ClusterIP + port: 1514 + # externalIPs: [] + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + ## Provide any additional annotations which may be required. This can be used to + ## set the LoadBalancer service type to internal only. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + annotations: {} + labels: {} + ## Use loadBalancerIP to request a specific static IP, + ## otherwise leave blank + ## + loadBalancerIP: + # loadBalancerSourceRanges: [] + ## Set the externalTrafficPolicy in the Service to either Cluster or Local + # externalTrafficPolicy: Cluster diff --git a/ct.yaml b/ct.yaml index c0770cd561..0000a1ab44 100644 --- a/ct.yaml +++ b/ct.yaml @@ -3,4 +3,7 @@ remote: origin target-branch: main chart-dirs: - charts +chart-repos: + - elastic=https://helm.elastic.co/ helm-extra-args: --timeout 600s +validate-maintainers: false