Grafana Loki Installation
Grafana Loki is a Logs Aggregation for LGTM Observability Stack
Prerequisites
Section titled “Prerequisites”Kubernetes Cluster
Section titled “Kubernetes Cluster”Grafana Loki will be installed on 🟢 Management Kubernetes Cluster
- 📥Ingress Service provided as Kubernetes Ingress Class (
IngressClass) - 🛡️TLS Certificate for Grafana Loki provided as Kubernetes Secret
- Grafana Loki will be exposed as HTTPS with Kubernetes Ingress.
Application Dependencies
Section titled “Application Dependencies”- 📦S3 API-compatible Object Storage ; For Logs Storage
- 🪣S3 Buckets: A Unit of Logical Storage with 🌏Region specified.
- Grafana Loki uses 2 separated buckets.
- Logs Storage (Chunks)
- Ruler Component
- Grafana Loki uses 2 separated buckets.
- 🔑Credentials to Access S3 Bucket: Access Key, Secret Key.
- Create/Gather a Dedicated Access Key/Secret Key for Grafana Loki to access to its buckets.
- 🪣S3 Buckets: A Unit of Logical Storage with 🌏Region specified.
Complete Prerequisites
Section titled “Complete Prerequisites”Kubernetes Cluster
Section titled “Kubernetes Cluster”Prepare Shell Variables
Section titled “Prepare Shell Variables”Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.
-
Connect to
🟢 ManagementKubernetes Cluster ; i.e w/ Kubeconfig FileEnsure you have defined and loaded your Global Shell Variables as described in Shell Variables.
Terminal window source $HOME/opstella-installation/shell-values/kubernetes/management_cluster.vars.shsource $HOME/opstella-installation/shell-values/tools/observability.vars.shTerminal window export KUBECONFIG="$HOME/opstella-installation/kubeconfigs/management_cluster.yaml" -
Set
🟢 ManagementKubernetes Cluster InformationEnsure
GRAFANA_LOKI_DOMAIN,K8S_INTERNAL_DOMAIN,K8S_INGRESSCLASS_NAME,K8S_STORAGECLASS_NAME,K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAMEare defined as per the Shell Variables guide. -
Create Kubernetes Secret for 🛡️ TLS Certificate for Grafana Loki in Namespace
observability-system.Kubernetes Ingress for Grafana Loki will associate TLS Certificate with Kubernetes Secret named
wildcard-${BASE_DOMAIN}-tls.export K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME="wildcard-${BASE_DOMAIN}-tls"Create one using from
.crtand.keyfile.Terminal window kubectl create secret tls $K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME \--cert=/path/to/cert/file --key=/path/to/key/file \--namespace observability-system💡 Should return
secret/wildcard-${BASE_DOMAIN}-tls createdmessage.
Application Dependencies
Section titled “Application Dependencies”S3 API-compatible Object Storage
Section titled “S3 API-compatible Object Storage”Set S3 API-compatible Object Storage Information for Grafana Loki.
-
Set S3 Connection with Domain
export GRAFANA_LOKI_S3_DOMAIN="http://seaweedfs-s3.apps-supporting-services.svc:9000" -
Set 🪣S3 Buckets
Grafana Loki uses 2 separated buckets.
-
Logs Storage (Chunks) named
grafana-loki-chunksexport GRAFANA_LOKI_S3_CHUNKS_BUCKET_NAME="grafana-loki-chunks" -
Ruler Component named
grafana-loki-rulerexport GRAFANA_LOKI_S3_RULER_BUCKET_NAME="grafana-loki-ruler"
-
-
Set 🌏S3 Region
export GRAFANA_LOKI_S3_BUCKET_REGION="us-east-1" -
Set 🔑Credentials to Access S3 Bucket
Access Key
export GRAFANA_LOKI_S3_ACCESS_KEY="grafana-loki"Secret Key
export GRAFANA_LOKI_S3_ACCESS_SECRET="${SEAWEEDFS_HA_S3_GRAFANA_LOKI_PASSWORD}"
Pre-Installation
Section titled “Pre-Installation”Grafana Loki Preparation
Section titled “Grafana Loki Preparation”-
Set Grafana Loki Entrypoint Domain
export GRAFANA_LOKI_DOMAIN="loki.${BASE_DOMAIN}" -
Create Helm Values Configuration: Fundamental Configurations
Terminal window cat <<EOF > $HOME/opstella-installation/helm-values/grafana-loki-full-values.yamlglobal:## -- Definitions to set up nginx resolver (nginx gateway that proxied within microservices)## OPSTELLA_CUSTOMIZE/RKE2: Defaults was 'kube-dns'/Change for RKE2# -- Definitions to set up nginx resolver# -- configures DNS service namednsService: ${K8S_INTERNAL_DNS_SERVICE}# -- configures DNS service namespacednsNamespace: "kube-system"# -- configures cluster domain ("cluster.local" by default)clusterDomain: "${K8S_INTERNAL_DOMAIN}"## OPSTELLA_CUSTOMIZE: Disable Built-in MinIO (it's not intended for Production uses!)minio:enabled: false# -- Ingress configuration Use either this ingress or the gateway, but not both at once.# If you enable this, make sure to disable the gateway.# You'll need to supply authn configuration for your ingress controller.ingress:enabled: trueingressClassName: ${K8S_INGRESSCLASS_NAME}hosts:- ${GRAFANA_LOKI_DOMAIN}tls:- hosts:- ${GRAFANA_LOKI_DOMAIN}secretName: ${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}## Gateway and Ingress## By default this chart will deploy a Nginx container to act as a gateway which handles routing of traffic# and can also do auth.## If you would prefer you can optionally disable this and enable using k8s ingress to do the incoming routing.## Configuration for the gatewaygateway:# -- Specifies whether the gateway should be enabledenabled: falseread:## TODO: OPSTELLA_CUSTOMIZE/TEMP: Disable Persistence until we can measure the workloadpersistence:# -- Enable volume claims in pod specvolumeClaimsEnabled: falsewrite:## TODO: OPSTELLA_CUSTOMIZE/TEMP: Disable Persistence until we can measure the workloadpersistence:# -- Enable volume claims in pod specvolumeClaimsEnabled: falsebackend:## TODO: OPSTELLA_CUSTOMIZE/TEMP: Disable Persistence until we can measure the workloadpersistence:# -- Enable volume claims in pod specvolumeClaimsEnabled: false######################################################################################################################## OPSTELLA_NOTE: Common Settings across Deployment Modes### --- ##### OPSTELLA_NOTE: chunksCache/resultsCache shared across SimpleScalable/Distributed## TODO: OPSTELLA_CUSTOMIZE: Disable Chunks Cache for WHY?chunksCache:# -- Specifies whether memcached based chunks-cache should be enabledenabled: false## TODO: OPSTELLA_CUSTOMIZE: Disable Result Cache for WHY?resultsCache:# -- Specifies whether memcached based results-cache should be enabledenabled: false### --- ###loki:## OPSTELLA_CUSTOMIZE: Utilize S3(-compatible) Object Storage By Defaultstorage:type: s3bucketNames:# Loki requires a bucket for chunks and the ruler. GEL requires a third bucket for the admin API.# Please provide these values if you are using object storage.chunks: ${GRAFANA_LOKI_S3_CHUNKS_BUCKET_NAME}ruler: ${GRAFANA_LOKI_S3_RULER_BUCKET_NAME}s3:endpoint: ${GRAFANA_LOKI_S3_DOMAIN}region: ${GRAFANA_LOKI_S3_BUCKET_REGION}accessKeyId: ${GRAFANA_LOKI_S3_ACCESS_KEY}secretAccessKey: ${GRAFANA_LOKI_S3_ACCESS_SECRET}s3ForcePathStyle: true ## OPSTELLA_CUSTOMIZEschemaConfig:configs:- from: 2024-04-01store: tsdbobject_store: s3schema: v13index:prefix: index_period: 24h## OPSTELLA_CUSTOMIZE: SecurityContext# -- The SecurityContext for Loki podspodSecurityContext:fsGroup: 10001# -- The SecurityContext for Loki containerscontainerSecurityContext:runAsUser: 10001runAsGroup: 10001runAsNonRoot: trueprivileged: falseallowPrivilegeEscalation: falsecapabilities:drop: ["ALL"]seccompProfile:type: RuntimeDefaultreadOnlyRootFilesystem: trueEOF -
Create Helm Values Configuration: Loki in Distributed Deployment Modes
Terminal window cat <<EOF > $HOME/opstella-installation/helm-values/grafana-loki-distributed-mode-full-values.yaml## OPSTELLA_CUSTOMIZE: Use Microservices Deployment to be Default for OpstelladeploymentMode: Distributed######################################################################################################################ingester:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 3## OPSTELLA_CUSTOMIZE: Disable zone awareness for On-Premise EnvironmentzoneAwareReplication:# -- Enable zone awareness.enabled: false## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for ingester pods. Ignored if zoneAwareReplication is enabled.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: ingesterapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnamequerier:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 3maxUnavailable: 2## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for querier pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: querierapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnamequeryFrontend:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 2maxUnavailable: 1## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for query-frontend pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: query-frontendapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnamequeryScheduler:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 2## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for query-scheduler pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: query-schedulerapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnamedistributor:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 3maxUnavailable: 2## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for distributor pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: distributorapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnamecompactor:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 1## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for compactor pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: compactorapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostnameindexGateway:## CHART/MODE-Distributed: Grafana Recommeded No. of Component Replicas/maxUnavailablereplicas: 2maxUnavailable: 1## OPSTELLA_CUSTOMIZE: When install LGTM altogether within the same namespace; default podAntiAffinity from Helm Chart would conflict each other,## need **additional label** for Kubernetes Scheduler to be factored# -- Affinity for index-gateway pods.# @default -- Hard node anti-affinityaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchLabels:app.kubernetes.io/component: index-gatewayapp.kubernetes.io/name: lokitopologyKey: kubernetes.io/hostname### --- #### CHART: Disable Optional Experimental ComponentsbloomCompactor:replicas: 0bloomBuilder:replicas: 0bloomGateway:replicas: 0### --- ###### --- ##### CHART/MODE-Distributed: Disable other deployment modesbackend:replicas: 0read:replicas: 0write:replicas: 0singleBinary:replicas: 0### --- ###### --- ##### CHART/MODE-Distributed: Loki Configuration by Grafana Recommendationsloki:ingester:chunk_encoding: snappytracing:enabled: truequerier:# Default is 4, if you have enough memory and CPU you can increase, reduce if OOMingmax_concurrent: 4### --- ###EOF
Helm Chart Preparation
Section titled “Helm Chart Preparation”-
Add Grafana Helm Repository
Terminal window helm repo add grafana https://grafana.github.io/helm-chartshelm repo update
Installation
Section titled “Installation”-
Install Grafana Loki
-
Install a Helm Release with specific Helm Chart Version
--version 6.28.0(App Version: 3.4.2)Terminal window helm install grafana-loki grafana/loki --version 6.28.0 \--namespace observability-system \-f $HOME/opstella-installation/helm-values/grafana-loki-full-values.yaml \-f $HOME/opstella-installation/helm-values/grafana-loki-distributed-mode-full-values.yaml
-
Post-Installation
Section titled “Post-Installation”Grafana Loki Testing
Section titled “Grafana Loki Testing”-
Get Pods Status
Terminal window kubectl get pods -n observability-system💡 Grafana Loki (Distributed Deployment Mode Components) Pods should be
RunningNAME READY STATUS RESTARTS AGE... (deducted)grafana-loki-compactor-0 1/1 Running 0 Xdgrafana-loki-distributor-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-distributor-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-distributor-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-index-gateway-0 1/1 Running 0 Xdgrafana-loki-index-gateway-1 1/1 Running 0 Xdgrafana-loki-ingester-0 1/1 Running 0 Xdgrafana-loki-ingester-0 1/1 Running 0 Xdgrafana-loki-ingester-0 1/1 Running 0 Xdgrafana-loki-querier-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-querier-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-querier-XXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-query-frontend-XXXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-query-frontend-XXXXXXXX-YYYYY 1/1 Running 0 Xdgrafana-loki-query-scheduler-XXXXXXXX-YYYYY 1/1 Running 0 Xdloki-canary-XXXXX 1/1 Running 0 Xdloki-canary-XXXXX 1/1 Running 0 Xdloki-canary-XXXXX 1/1 Running 0 Xdloki-canary-XXXXX 1/1 Running 0 Xdloki-canary-XXXXX 1/1 Running 0 Xd
Finished?
Use the below navigation to proceed