diff --git a/charts/fluentd-elasticsearch/Chart.yaml b/charts/fluentd-elasticsearch/Chart.yaml new file mode 100644 index 00000000..31402c2e --- /dev/null +++ b/charts/fluentd-elasticsearch/Chart.yaml @@ -0,0 +1,21 @@ +name: fluentd-elasticsearch +version: 2.1.0 +appVersion: 2.3.2 +home: https://www.fluentd.org/ +description: A Fluentd Helm chart for Kubernetes with Elasticsearch output +icon: https://raw.githubusercontent.com/fluent/fluentd-docs/master/public/logo/Fluentd_square.png +keywords: +- fluentd +- elasticsearch +- multiline +- detect-exceptions +- logging +sources: +- https://github.com/kubernetes/charts/stable/fluentd-elasticsearch +- https://github.com/fluent/fluentd-kubernetes-daemonset +- https://github.com/GoogleCloudPlatform/fluent-plugin-detect-exceptions +- https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/fluentd-elasticsearch/fluentd-es-image +maintainers: +- name: monotek + email: monotek23@gmail.com +engine: gotpl diff --git a/charts/fluentd-elasticsearch/OWNERS b/charts/fluentd-elasticsearch/OWNERS new file mode 100644 index 00000000..d2be9eee --- /dev/null +++ b/charts/fluentd-elasticsearch/OWNERS @@ -0,0 +1,6 @@ +approvers: +- axdotl +- monotek +reviewers: +- axdotl +- monotek diff --git a/charts/fluentd-elasticsearch/README.md b/charts/fluentd-elasticsearch/README.md new file mode 100644 index 00000000..b1a81b1a --- /dev/null +++ b/charts/fluentd-elasticsearch/README.md @@ -0,0 +1,95 @@ +# Fluentd Elasticsearch + +* Installs [Fluentd](https://www.fluentd.org/) log forwarder. + +## TL;DR; + +```console +$ helm install stable/fluentd-elasticsearch +``` + +## Introduction + +This chart bootstraps a [Fluentd](https://www.fluentd.org/) daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. +It's meant to be a drop in replacement for fluentd-gcp on GKE which sends logs to Google's Stackdriver service, but can also be used in other places where logging to ElasticSearch is required. +The used Docker image also contains Google's detect exceptions (for Java multiline stacktraces), Prometheus exporter, Kubernetes metadata filter & Systemd plugins. + +## Prerequisites + +- Kubernetes 1.8+ with Beta APIs enabled + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm install --name my-release stable/fluentd-elasticsearch +``` + +The command deploys fluentd-elasticsearch on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the Fluentd elasticsearch chart and their default values. + + +| Parameter | Description | Default | +| ---------------------------------- | ------------------------------------------ | ---------------------------------------------------------- | +| `annotations` | Optional daemonset annotations | `NULL` | +| `configMaps` | Fluentd configmaps | `default conf files` | +| `elasticsearch.host` | Elasticsearch Host | `elasticsearch-client` | +| `elasticsearch.port` | Elasticsearch Port | `9200` | +| `elasticsearch.logstash_prefix` | Elasticsearch Logstash prefix | `logstash` | +| `elasticsearch.buffer_chunk_limit` | Elasticsearch buffer chunk limit | `2M` | +| `elasticsearch.buffer_queue_limit` | Elasticsearch buffer queue limit | `8` | +| `elasticsearch.scheme` | Elasticsearch scheme setting | `http` | +| `env` | List of environment variables that are added to the fluentd pods | `{}` | +| `extraVolumeMounts` | Mount an extra volume, required to mount ssl certificates when elasticsearch has tls enabled | | +| `extraVolume` | Extra volume | | +| `image.repository` | Image | `gcr.io/google-containers/fluentd-elasticsearch` | +| `image.tag` | Image tag | `v2.3.2` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `livenessProbe.enabled` | Whether to enable livenessProbe | `true` | +| `nodeSelector` | Optional daemonset nodeSelector | `{}` | +| `podSecurityPolicy.annotations` | Specify pod annotations in the pod security policy | `{}` | +| `podSecurityPolicy.enabled` | Specify if a pod security policy must be created | `false` | +| `rbac.create` | RBAC | `true` | +| `resources.limits.cpu` | CPU limit | `100m` | +| `resources.limits.memory` | Memory limit | `500Mi` | +| `resources.requests.cpu` | CPU request | `100m` | +| `resources.requests.memory` | Memory request | `200Mi` | +| `service` | Service definition | `{}` | +| `service.type` | Service type (ClusterIP/NodePort) | Not Set | +| `service.ports` | List of service ports dict [{name:...}...] | Not Set | +| `service.ports[].name` | One of service ports name | Not Set | +| `service.ports[].port` | Service port | Not Set | +| `service.ports[].nodePort` | NodePort port (when service.type is NodePort) | Not Set | +| `service.ports[].protocol` | Service protocol(optional, can be TCP/UDP) | Not Set | +| `serviceAccount.create` | Specifies whether a service account should be created.| `true` | +| `serviceAccount.name` | Name of the service account. | | +| `tolerations` | Optional daemonset tolerations | `{}` | +| `updateStrategy` | Optional daemonset update strategy | `type: RollingUpdate` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install --name my-release \ + stable/fluentd-elasticsearch +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install --name my-release -f values.yaml stable/fluentd-elasticsearch +``` diff --git a/charts/fluentd-elasticsearch/templates/NOTES.txt b/charts/fluentd-elasticsearch/templates/NOTES.txt new file mode 100644 index 00000000..977bc106 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/NOTES.txt @@ -0,0 +1,24 @@ +1. To verify that Fluentd has started, run: + + kubectl --namespace={{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "fluentd-elasticsearch.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" + +THIS APPLICATION CAPTURES ALL CONSOLE OUTPUT AND FORWARDS IT TO elasticsearch . Anything that might be identifying, +including things like IP addresses, container images, and object names will NOT be anonymized. + +{{- if .Values.service }} +2. Get the application URL by running these commands: +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "fluentd-elasticsearch.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ include "fluentd-elasticsearch.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "fluentd-elasticsearch.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "fluentd-elasticsearch.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/_helpers.tpl b/charts/fluentd-elasticsearch/templates/_helpers.tpl new file mode 100644 index 00000000..96fc5bc7 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/_helpers.tpl @@ -0,0 +1,42 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "fluentd-elasticsearch.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 "fluentd-elasticsearch.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 "fluentd-elasticsearch.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "fluentd-elasticsearch.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "fluentd-elasticsearch.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/fluentd-elasticsearch/templates/clusterrole.yaml b/charts/fluentd-elasticsearch/templates/clusterrole.yaml new file mode 100644 index 00000000..34e3569b --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/clusterrole.yaml @@ -0,0 +1,23 @@ +{{- if .Values.rbac.create -}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +rules: +- apiGroups: + - "" + resources: + - "namespaces" + - "pods" + verbs: + - "get" + - "watch" + - "list" +{{- end -}} diff --git a/charts/fluentd-elasticsearch/templates/clusterrolebinding.yaml b/charts/fluentd-elasticsearch/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..d5d28b47 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create -}} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +subjects: +- kind: ServiceAccount + name: {{ template "fluentd-elasticsearch.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "fluentd-elasticsearch.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/charts/fluentd-elasticsearch/templates/configmap.yaml b/charts/fluentd-elasticsearch/templates/configmap.yaml new file mode 100644 index 00000000..6f26f83a --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/configmap.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +data: +{{- range $key, $value := .Values.configMaps }} + {{ $key }}: |- +{{ $value | indent 4 }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/daemonset.yaml b/charts/fluentd-elasticsearch/templates/daemonset.yaml new file mode 100644 index 00000000..ea4fa521 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/daemonset.yaml @@ -0,0 +1,150 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +spec: + updateStrategy: +{{ toYaml .Values.updateStrategy | indent 4 }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + # This annotation ensures that fluentd does not get evicted if the node + # supports critical pod annotation based priority scheme. + # Note that this does not guarantee admission on the nodes (#40573). + annotations: + scheduler.alpha.kubernetes.io/critical-pod: '' + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +{{- if .Values.annotations }} +{{ toYaml .Values.annotations | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ template "fluentd-elasticsearch.fullname" . }} + containers: + - name: {{ template "fluentd-elasticsearch.fullname" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + env: + - name: FLUENTD_ARGS + value: --no-supervisor -q + - name: OUTPUT_HOST + value: {{ .Values.elasticsearch.host | quote }} + - name: OUTPUT_PORT + value: {{ .Values.elasticsearch.port | quote }} + - name: LOGSTASH_PREFIX + value: {{ .Values.elasticsearch.logstash_prefix | quote }} + - name: OUTPUT_SCHEME + value: {{ .Values.elasticsearch.scheme | quote }} + - name: OUTPUT_BUFFER_CHUNK_LIMIT + value: {{ .Values.elasticsearch.buffer_chunk_limit | quote }} + - name: OUTPUT_BUFFER_QUEUE_LIMIT + value: {{ .Values.elasticsearch.buffer_queue_limit | quote }} + {{- if .Values.env }} + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + - name: libsystemddir + mountPath: /host/lib + readOnly: true + - name: config-volume + mountPath: /etc/fluent/config.d +{{- if .Values.extraVolumeMounts }} +{{ toYaml .Values.extraVolumeMounts | indent 8 }} +{{- end }} + ports: +{{- range $port := .Values.service.ports }} + - name: {{ $port.name }} + containerPort: {{ $port.port }} +{{- if $port.protocol }} + protocol: {{ $port.protocol }} +{{- end }} +{{- end }} +{{- if .Values.livenessProbe.enabled }} + # Liveness probe is aimed to help in situarions where fluentd + # silently hangs for no apparent reasons until manual restart. + # The idea of this probe is that if fluentd is not queueing or + # flushing chunks for 5 minutes, something is not right. If + # you want to change the fluentd configuration, reducing amount of + # logs fluentd collects, consider changing the threshold or turning + # liveness probe off completely. + livenessProbe: + initialDelaySeconds: 600 + periodSeconds: 60 + exec: + command: + - '/bin/sh' + - '-c' + - > + LIVENESS_THRESHOLD_SECONDS=${LIVENESS_THRESHOLD_SECONDS:-300}; + STUCK_THRESHOLD_SECONDS=${LIVENESS_THRESHOLD_SECONDS:-900}; + if [ ! -e /var/log/fluentd-buffers ]; + then + exit 1; + fi; + touch -d "${STUCK_THRESHOLD_SECONDS} seconds ago" /tmp/marker-stuck; + if [[ -z "$(find /var/log/fluentd-buffers -type f -newer /tmp/marker-stuck -print -quit)" ]]; + then + rm -rf /var/log/fluentd-buffers; + exit 1; + fi; + touch -d "${LIVENESS_THRESHOLD_SECONDS} seconds ago" /tmp/marker-liveness; + if [[ -z "$(find /var/log/fluentd-buffers -type f -newer /tmp/marker-liveness -print -quit)" ]]; + then + exit 1; + fi; +{{- end }} + terminationGracePeriodSeconds: 30 + volumes: + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + # It is needed to copy systemd library to decompress journals + - name: libsystemddir + hostPath: + path: /usr/lib64 + - name: config-volume + configMap: + name: {{ template "fluentd-elasticsearch.fullname" . }} +{{- if .Values.extraVolumes }} +{{ toYaml .Values.extraVolumes | indent 6 }} +{{- end }} +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 6 }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/pod-security-policy.yaml b/charts/fluentd-elasticsearch/templates/pod-security-policy.yaml new file mode 100644 index 00000000..2a74cad5 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/pod-security-policy.yaml @@ -0,0 +1,52 @@ +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: extensions/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile + annotations: +{{- if .Values.podSecurityPolicy.annotations }} +{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: true + volumes: + - 'configMap' + - 'emptyDir' + - 'hostPath' + - 'secret' + allowedHostPaths: + - pathPrefix: /var/log + readOnly: false + - pathPrefix: /var/lib/docker/containers + readOnly: true + - pathPrefix: /usr/lib64 + readOnly: true + hostNetwork: false + hostPID: false + hostIPC: false + runAsUser: + rule: 'RunAsAny' + runAsGroup: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + hostPorts: + - min: 1 + max: 65535 +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/role.yaml b/charts/fluentd-elasticsearch/templates/role.yaml new file mode 100644 index 00000000..57ea3ddb --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "fluentd-elasticsearch.fullname" . }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/rolebinding.yaml b/charts/fluentd-elasticsearch/templates/rolebinding.yaml new file mode 100644 index 00000000..29a341d8 --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/rolebinding.yaml @@ -0,0 +1,22 @@ + +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +roleRef: + kind: Role + name: {{ template "fluentd-elasticsearch.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "fluentd-elasticsearch.fullname" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/templates/service-account.yaml b/charts/fluentd-elasticsearch/templates/service-account.yaml new file mode 100644 index 00000000..91ace19b --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/service-account.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +{{- end -}} diff --git a/charts/fluentd-elasticsearch/templates/service.yaml b/charts/fluentd-elasticsearch/templates/service.yaml new file mode 100644 index 00000000..a0fb53bb --- /dev/null +++ b/charts/fluentd-elasticsearch/templates/service.yaml @@ -0,0 +1,30 @@ +{{- if .Values.service }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "fluentd-elasticsearch.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + helm.sh/chart: {{ include "fluentd-elasticsearch.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile +spec: + type: {{ .Values.service.type }} + ports: + {{- range $port := .Values.service.ports }} + - name: {{ $port.name }} + port: {{ $port.port }} + targetPort: {{ $port.port }} + {{- if $port.nodePort }} + nodePort: {{ $port.nodePort }} + {{- end }} + {{- if $port.protocol }} + protocol: {{ $port.protocol }} + {{- end }} + {{- end }} + selector: + app.kubernetes.io/name: {{ include "fluentd-elasticsearch.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/fluentd-elasticsearch/values.yaml b/charts/fluentd-elasticsearch/values.yaml new file mode 100644 index 00000000..bc662416 --- /dev/null +++ b/charts/fluentd-elasticsearch/values.yaml @@ -0,0 +1,480 @@ +image: + repository: gcr.io/google-containers/fluentd-elasticsearch +## Specify an imagePullPolicy (Required) +## It's recommended to change this to 'Always' if the image tag is 'latest' +## ref: http://kubernetes.io/docs/user-guide/images/#updating-images + tag: v2.3.2 + pullPolicy: IfNotPresent + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: {} + # limits: + # cpu: 100m + # memory: 500Mi + # requests: + # cpu: 100m + # memory: 200Mi + +elasticsearch: + host: 'elasticsearch-client' + port: 9200 + buffer_chunk_limit: 2M + buffer_queue_limit: 8 + logstash_prefix: 'logstash' + scheme: 'http' + +# If you want to add custom environment variables, use the env dict +# You can then reference these in your config file e.g.: +# user "#{ENV['OUTPUT_USER']}" +env: + # OUTPUT_USER: my_user + +rbac: + create: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + +## Specify if a Pod Security Policy for node-exporter must be created +## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + enabled: false + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + +livenessProbe: + enabled: true + +annotations: {} + # prometheus.io/scrape: "true" + # prometheus.io/port: "24231" + +## DaemonSet update strategy +## Ref: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/ +updateStrategy: + type: RollingUpdate + +tolerations: {} + # - key: node-role.kubernetes.io/master + # operator: Exists + # effect: NoSchedule + +nodeSelector: {} + +service: {} + # type: ClusterIP + # ports: + # - name: "monitor-agent" + # port: 24231 + +configMaps: + system.conf: |- + + root_dir /tmp/fluentd-buffers/ + + containers.input.conf: |- + # This configuration file for Fluentd / td-agent is used + # to watch changes to Docker log files. The kubelet creates symlinks that + # capture the pod name, namespace, container name & Docker container ID + # to the docker logs for pods in the /var/log/containers directory on the host. + # If running this fluentd configuration in a Docker container, the /var/log + # directory should be mounted in the container. + # + # These logs are then submitted to Elasticsearch which assumes the + # installation of the fluent-plugin-elasticsearch & the + # fluent-plugin-kubernetes_metadata_filter plugins. + # See https://github.com/uken/fluent-plugin-elasticsearch & + # https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter for + # more information about the plugins. + # + # Example + # ======= + # A line in the Docker log file might look like this JSON: + # + # {"log":"2014/09/25 21:15:03 Got request with path wombat\n", + # "stream":"stderr", + # "time":"2014-09-25T21:15:03.499185026Z"} + # + # The time_format specification below makes sure we properly + # parse the time format produced by Docker. This will be + # submitted to Elasticsearch and should appear like: + # $ curl 'http://elasticsearch-logging:9200/_search?pretty' + # ... + # { + # "_index" : "logstash-2014.09.25", + # "_type" : "fluentd", + # "_id" : "VBrbor2QTuGpsQyTCdfzqA", + # "_score" : 1.0, + # "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n", + # "stream":"stderr","tag":"docker.container.all", + # "@timestamp":"2014-09-25T22:45:50+00:00"} + # }, + # ... + # + # The Kubernetes fluentd plugin is used to write the Kubernetes metadata to the log + # record & add labels to the log record if properly configured. This enables users + # to filter & search logs on any metadata. + # For example a Docker container's logs might be in the directory: + # + # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b + # + # and in the file: + # + # 997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log + # + # where 997599971ee6... is the Docker ID of the running container. + # The Kubernetes kubelet makes a symbolic link to this file on the host machine + # in the /var/log/containers directory which includes the pod name and the Kubernetes + # container name: + # + # synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # -> + # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log + # + # The /var/log directory on the host is mapped to the /var/log directory in the container + # running this instance of Fluentd and we end up collecting the file: + # + # /var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # This results in the tag: + # + # var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # The Kubernetes fluentd plugin is used to extract the namespace, pod name & container name + # which are added to the log message as a kubernetes field object & the Docker container ID + # is also added under the docker field object. + # The final tag is: + # + # kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # And the final log record look like: + # + # { + # "log":"2014/09/25 21:15:03 Got request with path wombat\n", + # "stream":"stderr", + # "time":"2014-09-25T21:15:03.499185026Z", + # "kubernetes": { + # "namespace": "default", + # "pod_name": "synthetic-logger-0.25lps-pod", + # "container_name": "synth-lgr" + # }, + # "docker": { + # "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b" + # } + # } + # + # This makes it easier for users to search for logs by pod name or by + # the name of the Kubernetes container regardless of how many times the + # Kubernetes pod has been restarted (resulting in a several Docker container IDs). + # Json Log Example: + # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"} + # CRI Log Example: + # 2016-02-17T00:04:05.931087621Z stdout F [info:2016-02-16T16:04:05.930-08:00] Some log text here + + @id fluentd-containers.log + @type tail + path /var/log/containers/*.log + pos_file /var/log/fluentd-containers.log.pos + time_format %Y-%m-%dT%H:%M:%S.%NZ + tag raw.kubernetes.* + format json + read_from_head true + + # Detect exceptions in the log output and forward them as one log entry. + + @id raw.kubernetes + @type detect_exceptions + remove_tag_prefix raw + message log + stream stream + multiline_flush_interval 5 + max_bytes 500000 + max_lines 1000 + + system.input.conf: |- + # Example: + # 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081 + + @id minion + @type tail + format /^(?