Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ jobs:
- name: Deploy Prometheus operator
run: ./dev/scripts/setup-prometheus.sh deploy

- name: Deploy Loki and Promtail
run: ./dev/scripts/setup-loki-kind.sh deploy

- name: Build MCP image and load into kind
run: |
./mvnw package -pl common,metrics-prometheus,loki-log-provider,strimzi-mcp \
Expand Down
38 changes: 38 additions & 0 deletions dev/manifests/loki-kind/alloy-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: alloy-config
namespace: logging
data:
config.alloy: |
discovery.kubernetes "pods" {
role = "pod"
}

discovery.relabel "pods" {
targets = discovery.kubernetes.pods.targets

rule {
source_labels = ["__meta_kubernetes_namespace"]
target_label = "namespace"
}
rule {
source_labels = ["__meta_kubernetes_pod_name"]
target_label = "pod"
}
rule {
source_labels = ["__meta_kubernetes_pod_container_name"]
target_label = "container"
}
}

loki.source.kubernetes "pods" {
targets = discovery.relabel.pods.output
forward_to = [loki.write.default.receiver]
}

loki.write "default" {
endpoint {
url = "http://loki.logging.svc.cluster.local:3100/loki/api/v1/push"
}
}
79 changes: 79 additions & 0 deletions dev/manifests/loki-kind/alloy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: alloy
namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: alloy
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/proxy", "nodes/metrics", "services", "endpoints", "pods", "pods/log"]
verbs: ["get", "watch", "list"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: alloy
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: alloy
subjects:
- kind: ServiceAccount
name: alloy
namespace: logging
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: alloy
namespace: logging
labels:
app: alloy
spec:
replicas: 1
selector:
matchLabels:
app: alloy
template:
metadata:
labels:
app: alloy
spec:
serviceAccountName: alloy
containers:
- name: alloy
image: grafana/alloy:v1.8.3
args:
- run
- /etc/alloy/config.alloy
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/tmp/alloy
ports:
- name: http
containerPort: 12345
readinessProbe:
httpGet:
path: /-/ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
volumeMounts:
- name: config
mountPath: /etc/alloy
volumes:
- name: config
configMap:
name: alloy-config
8 changes: 8 additions & 0 deletions dev/manifests/loki-kind/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- loki-config.yaml
- loki.yaml
- alloy-config.yaml
- alloy.yaml
40 changes: 40 additions & 0 deletions dev/manifests/loki-kind/loki-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: loki-config
namespace: logging
data:
loki.yaml: |
auth_enabled: false

server:
http_listen_port: 3100

common:
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
replication_factor: 1
path_prefix: /loki

schema_config:
configs:
- from: "2024-01-01"
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h

storage_config:
filesystem:
directory: /loki/chunks

limits_config:
reject_old_samples: false
allow_structured_metadata: true

compactor:
working_directory: /loki/compactor
64 changes: 64 additions & 0 deletions dev/manifests/loki-kind/loki.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: loki
namespace: logging
labels:
app: loki
spec:
replicas: 1
selector:
matchLabels:
app: loki
template:
metadata:
labels:
app: loki
spec:
containers:
- name: loki
image: mirror.gcr.io/grafana/loki:3.7.3
args:
- -config.file=/etc/loki/loki.yaml
ports:
- name: http
containerPort: 3100
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 512Mi
volumeMounts:
- name: config
mountPath: /etc/loki
- name: data
mountPath: /loki
volumes:
- name: config
configMap:
name: loki-config
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: loki
namespace: logging
labels:
app: loki
spec:
type: ClusterIP
ports:
- name: http
port: 3100
targetPort: http
selector:
app: loki
4 changes: 4 additions & 0 deletions dev/manifests/loki-kind/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: logging
100 changes: 100 additions & 0 deletions dev/scripts/setup-loki-kind.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/bin/bash

# Deploy or tear down standalone Loki + Alloy for log collection in kind.
# Deploys Loki in monolithic mode with filesystem storage and Grafana Alloy
# for Kubernetes pod log collection via the Kubernetes API.
#
# Usage:
# ./setup-loki-kind.sh deploy - Deploy Loki + Alloy
# ./setup-loki-kind.sh teardown - Remove everything
# ./setup-loki-kind.sh help - Show usage

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOKI_KIND_DIR="$SCRIPT_DIR/../manifests/loki-kind"
LOGGING_NS="logging"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO] $1${NC}"; }
log_success() { echo -e "${GREEN}[OK] $1${NC}"; }
log_error() { echo -e "${RED}[ERROR] $1${NC}"; }

check_kubectl() {
if ! command -v kubectl &> /dev/null; then
log_error "kubectl is not installed."
exit 1
fi
if ! kubectl cluster-info &> /dev/null; then
log_error "Cannot connect to Kubernetes cluster. Check your kubeconfig."
exit 1
fi
log_success "kubectl connected to cluster"
}

deploy() {
check_kubectl

log_info "Deploying Loki and Alloy..."
kubectl apply -k "$LOKI_KIND_DIR"

log_info "Waiting for Loki to be ready..."
kubectl wait --for=condition=Available \
deployment/loki \
-n "$LOGGING_NS" \
--timeout=120s
log_success "Loki is ready"

log_info "Waiting for Alloy to be ready..."
kubectl wait --for=condition=Available \
deployment/alloy \
-n "$LOGGING_NS" \
--timeout=120s
log_success "Alloy is ready"

log_success "Loki + Alloy deployed successfully"
log_info "In-cluster URL: http://loki.logging.svc.cluster.local:3100"
}

teardown() {
check_kubectl

log_info "Removing Loki and Alloy..."
kubectl delete -k "$LOKI_KIND_DIR" --ignore-not-found

log_success "Loki teardown complete"
}

show_help() {
echo "Usage: $(basename "$0") <command>"
echo ""
echo "Commands:"
echo " deploy - Deploy Loki and Alloy for log collection"
echo " teardown - Remove Loki and Alloy"
echo " help - Show this help message"
}

# Main
COMMAND="${1:-help}"

case "$COMMAND" in
deploy)
deploy
;;
teardown)
teardown
;;
help|--help|-h)
show_help
;;
*)
log_error "Unknown command: $COMMAND"
show_help
exit 1
;;
esac
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public final class Environment {
/** Prometheus auth mode override ({@code none}, {@code sa-token}, {@code basic}). Auto-detected if not set. */
public static final String PROMETHEUS_AUTH_MODE = ENV_VARIABLES.getOrDefault("PROMETHEUS_AUTH_MODE", null);

/** Loki URL override. When set, skips auto-discovery of Loki services. */
public static final String LOKI_URL = ENV_VARIABLES.getOrDefault("LOKI_URL", null);

/** Loki auth mode override ({@code none}, {@code sa-token}, {@code bearer-token}). Auto-detected if not set. */
public static final String LOKI_AUTH_MODE = ENV_VARIABLES.getOrDefault("LOKI_AUTH_MODE", null);

private Environment() {
}
}
Loading