Logging and Monitoring
ESS Pro integrates with industry standard Kubernetes logging and monitoring systems.
It does not deploy its own monitoring stack, rather it makes it easy to integrate into existing monitoring stacks via the Prometheus Operator ServiceMonitor (or other compatible implementations).
By default, the ESS Pro Helm chart detects the presence of ServiceMonitors in the cluster and constructs appropriate instances for each backend component.
Example Monitoring Stack
To demonstrate the logging and monitoring capabilities an example stack is documented below. This is not a production ready stack.
Loki for storing logs
Loki is a log aggregation system.
An example Loki stack can be installed in the cluster as follows:
-
Create
loki.yml:--- loki: commonConfig: replication_factor: 1 schemaConfig: configs: - from: 2024-04-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h storage: type: 'filesystem' deploymentMode: Monolithic singleBinary: replicas: 1 read: replicas: 0 write: replicas: 0 backend: replicas: 0 -
Install Loki:
helm upgrade -i --create-namespace -n loki loki oci://ghcr.io/grafana-community/helm-charts/loki -f loki.yml
Loki is now available for logs to be shipped to and logs to be queried from
Alloy for shipping logs
Alloy is used to collect logs from the Kubernetes Pods and ship them to Loki.
An example setup of Alloy can be installed in the cluster as follows:
-
Create
alloy.ymlalloy: configMap: content: |- logging { level = "info" format = "logfmt" } loki.write "default" { endpoint { url = "http://loki-gateway.loki.svc.cluster.local./loki/api/v1/push" tenant_id = "default" } } discovery.kubernetes "pod" { role = "pod" selectors { role = "pod" field = "spec.nodeName=" + coalesce(sys.env("HOSTNAME"), constants.hostname) } } discovery.relabel "pod_logs" { targets = discovery.kubernetes.pod.targets // Label creation - "namespace" field from "__meta_kubernetes_namespace" rule { source_labels = ["__meta_kubernetes_namespace"] action = "replace" target_label = "namespace" } // Label creation - "pod" field from "__meta_kubernetes_pod_name" rule { source_labels = ["__meta_kubernetes_pod_name"] action = "replace" target_label = "pod" } // Label creation - "container" field from "__meta_kubernetes_pod_container_name" rule { source_labels = ["__meta_kubernetes_pod_container_name"] action = "replace" target_label = "container" } // Label creation - "app" field from "__meta_kubernetes_pod_label_app_kubernetes_io_name" rule { source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"] action = "replace" target_label = "app" } // Label creation - "job" field from "__meta_kubernetes_namespace" and "__meta_kubernetes_pod_container_name" // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name rule { source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"] action = "replace" target_label = "job" separator = "/" replacement = "$1" } // Label creation - "__path__" field from "__meta_kubernetes_pod_uid" and "__meta_kubernetes_pod_container_name" // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log rule { source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"] action = "replace" target_label = "__path__" separator = "/" replacement = "/var/log/pods/*$1/*.log" } } // loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API. loki.source.kubernetes "pod_logs" { targets = discovery.relabel.pod_logs.output forward_to = [loki.write.default.receiver] } -
Add the Helm repository:
helm repo add grafana https://grafana.github.io/helm-charts - Install Alloy:
helm upgrade -i --create-namespace -n alloy alloy grafana/alloy -f alloy.yml
Alloy will now start reading logs from all Pods in the cluster and shipping them to Loki.
Prometheus Operator and Grafana
The kube-prometheus-stack provides an installation of the Prometheus Operator and Grafana for the cluster.
This installs components to scrape metrics from ServiceMonitors in cluster, store them and expose them through Grafana.
An example setup can be installed in the cluster as follows:
-
Create
monitoring.yml--- grafana: ingress: enabled: true annotations: cert-manager.io/cluster-issuer: letsencrypt-prod hosts: - grafana.<server name> tls: - secretName: grafana hosts: - grafana.<server name> datasources: loki.yaml: apiVersion: 1 datasources: - name: Loki url: http://loki-gateway.loki.svc.cluster.local. type: 'loki' jsonData: httpHeaderName1: 'X-Scope-OrgID' secureJsonData: httpHeaderValue1: "default" prometheus: prometheusSpec: serviceMonitorSelectorNilUsesHelmValues: false storageSpec: volumeClaimTemplate: spec: resources: requests: storage: 10Gi- Replace
grafana.<server name>with an appropriate DNS entry that points at your server's IP letsencrypt-prodis theClusterIssuercreated in the ESS Pro setup instructions but can be adjusted as appropriate
- Replace
-
Install the stack:
helm upgrade -i --create-namespace -n monitoring monitoring oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack -f monitoring.yml - Obtain the Grafana admin password:
kubectl --namespace monitoring get secrets monitoring-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo - Login to Grafana at
https://grafana.<server name>usingadminas the username and the password obtained above
The Grafana instance will have a set of dashboards for health of the cluster. Additional dashboards can be added, for example:
Arbitrary metrics and logs can be viewing using the "Explore" tab.