vibecarbon 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/carbon/.env.example +3 -2
- package/carbon/DEVELOPMENT.md +18 -3
- package/carbon/PRODUCTION.md +1 -1
- package/carbon/content/docs/cli.mdx +3 -3
- package/carbon/content/docs/deployment.mdx +1 -1
- package/carbon/content/docs/development.mdx +1 -1
- package/carbon/content/docs/getting-started.mdx +0 -1
- package/carbon/scripts/dev-init.js +1 -1
- package/carbon/scripts/generate-dev-configs.sh +5 -7
- package/carbon/scripts/validate-dev-configs.sh +5 -7
- package/carbon/src/client/components/TechStackSection.tsx +0 -68
- package/carbon/src/client/index.css +0 -14
- package/carbon/src/client/locales/de.json +0 -18
- package/carbon/src/client/locales/en.json +86 -36
- package/carbon/src/client/locales/es.json +0 -18
- package/carbon/src/client/locales/fr.json +0 -18
- package/carbon/src/client/locales/pt.json +0 -18
- package/carbon/src/client/pages/Home.tsx +0 -3
- package/package.json +4 -2
- package/services/index.json +29 -0
- package/services/metabase/compose/docker-compose.override.yml +14 -0
- package/services/metabase/compose/docker-compose.prod.yml +29 -0
- package/services/metabase/compose/docker-compose.yml +68 -0
- package/services/metabase/db/init.sh +29 -0
- package/services/metabase/docs/integration.md +191 -0
- package/services/metabase/k8s/deployment.yaml +88 -0
- package/services/metabase/k8s/ingressroute.yaml +22 -0
- package/services/metabase/k8s/kustomization.yaml +9 -0
- package/services/metabase/k8s/network-policy.yaml +74 -0
- package/services/metabase/k8s/pvc.yaml +12 -0
- package/services/metabase/k8s/service.yaml +15 -0
- package/services/metabase/manifest.json +34 -0
- package/services/metabase/scripts/setup.sh +152 -0
- package/services/n8n/compose/docker-compose.override.yml +14 -0
- package/services/n8n/compose/docker-compose.prod.yml +32 -0
- package/services/n8n/compose/docker-compose.yml +99 -0
- package/services/n8n/db/init.sh +25 -0
- package/services/n8n/docs/SSO.md +124 -0
- package/services/n8n/docs/integration.md +155 -0
- package/services/n8n/hooks/hooks.js +131 -0
- package/services/n8n/k8s/deployment.yaml +116 -0
- package/services/n8n/k8s/ingressroute.yaml +24 -0
- package/services/n8n/k8s/kustomization.yaml +9 -0
- package/services/n8n/k8s/network-policy.yaml +82 -0
- package/services/n8n/k8s/pvc.yaml +14 -0
- package/services/n8n/k8s/service.yaml +14 -0
- package/services/n8n/manifest.json +36 -0
- package/services/n8n/scripts/setup.sh +42 -0
- package/{carbon/docker-compose.observability.prod.yml → services/observability/compose/docker-compose.prod.yml} +8 -0
- package/services/observability/docs/integration.md +31 -0
- package/services/observability/k8s/grafana-deployment.yaml +107 -0
- package/services/observability/k8s/grafana-provisioning-configmap.yaml +65 -0
- package/services/observability/k8s/grafana-pvc.yaml +14 -0
- package/services/observability/k8s/grafana-service.yaml +16 -0
- package/services/observability/k8s/ingressroute.yaml +22 -0
- package/services/observability/k8s/kustomization.yaml +24 -0
- package/services/observability/k8s/loki-configmap.yaml +74 -0
- package/services/observability/k8s/loki-deployment.yaml +72 -0
- package/services/observability/k8s/loki-pvc.yaml +14 -0
- package/services/observability/k8s/loki-service.yaml +16 -0
- package/services/observability/k8s/network-policy.yaml +141 -0
- package/services/observability/k8s/prometheus-configmap.yaml +80 -0
- package/services/observability/k8s/prometheus-deployment.yaml +78 -0
- package/services/observability/k8s/prometheus-pvc.yaml +14 -0
- package/services/observability/k8s/prometheus-rbac.yaml +55 -0
- package/services/observability/k8s/prometheus-service.yaml +16 -0
- package/services/observability/manifest.json +28 -0
- package/services/redis/compose/docker-compose.prod.yml +10 -0
- package/services/redis/compose/docker-compose.yml +24 -0
- package/services/redis/docs/integration.md +148 -0
- package/services/redis/k8s/deployment.yaml +70 -0
- package/services/redis/k8s/kustomization.yaml +8 -0
- package/services/redis/k8s/network-policy.yaml +20 -0
- package/services/redis/k8s/pvc.yaml +12 -0
- package/services/redis/k8s/service.yaml +15 -0
- package/services/redis/manifest.json +30 -0
- package/services/s3/compose/docker-compose.s3-ha.yml +86 -0
- package/services/s3/compose/docker-compose.s3.yml +35 -0
- package/services/s3/manifest.json +87 -0
- package/src/add.js +57 -89
- package/src/cli.js +1 -1
- package/src/create.js +3 -87
- package/src/lib/deploy/bundle.js +4 -2
- package/src/lib/deploy/compose/index.js +45 -17
- package/src/lib/deploy/orchestrator.js +13 -1
- package/src/remove.js +9 -6
- package/carbon/content/docs/optional-services.mdx +0 -160
- package/carbon/src/client/components/MetricsStrip.tsx +0 -48
- /package/{carbon/docker-compose.observability.override.yml → services/observability/compose/docker-compose.override.yml} +0 -0
- /package/{carbon/docker-compose.observability.yml → services/observability/compose/docker-compose.yml} +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards/logs.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards/overview.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards/postgresql.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards.dev/logs.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards.dev/overview.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/dashboards.dev/postgresql.json +0 -0
- /package/{carbon → services/observability}/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +0 -0
- /package/{carbon → services/observability}/volumes/grafana/provisioning/dashboards/dashboards.yml +0 -0
- /package/{carbon → services/observability}/volumes/grafana/provisioning/datasources/datasources.yml +0 -0
- /package/{carbon → services/observability}/volumes/loki/loki-config.yml +0 -0
- /package/{carbon → services/observability}/volumes/prometheus/prometheus.yml +0 -0
- /package/{carbon → services/observability}/volumes/promtail/promtail-config.yml +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: PersistentVolumeClaim
|
|
3
|
+
metadata:
|
|
4
|
+
name: grafana-pvc
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-grafana
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
accessModes:
|
|
10
|
+
- ReadWriteOnce
|
|
11
|
+
storageClassName: hcloud-volumes
|
|
12
|
+
resources:
|
|
13
|
+
requests:
|
|
14
|
+
storage: 5Gi
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: grafana
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-grafana
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
type: ClusterIP
|
|
10
|
+
ports:
|
|
11
|
+
- port: 3000
|
|
12
|
+
targetPort: http
|
|
13
|
+
protocol: TCP
|
|
14
|
+
name: http
|
|
15
|
+
selector:
|
|
16
|
+
app: vibecarbon-grafana
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
apiVersion: traefik.io/v1alpha1
|
|
2
|
+
kind: IngressRoute
|
|
3
|
+
metadata:
|
|
4
|
+
name: vibecarbon-grafana
|
|
5
|
+
namespace: vibecarbon
|
|
6
|
+
spec:
|
|
7
|
+
entryPoints:
|
|
8
|
+
- websecure
|
|
9
|
+
routes:
|
|
10
|
+
# No strip-prefix: Grafana handles the subpath itself via GF_SERVER_SERVE_FROM_SUB_PATH
|
|
11
|
+
# and GF_SERVER_ROOT_URL=$(SITE_URL)/admin/grafana/.
|
|
12
|
+
- match: PathPrefix(`/admin/grafana`)
|
|
13
|
+
kind: Rule
|
|
14
|
+
priority: 20
|
|
15
|
+
services:
|
|
16
|
+
- name: grafana
|
|
17
|
+
port: 3000
|
|
18
|
+
middlewares:
|
|
19
|
+
- name: admin-auth
|
|
20
|
+
- name: security-headers
|
|
21
|
+
tls:
|
|
22
|
+
secretName: vibecarbon-tls
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
2
|
+
kind: Kustomization
|
|
3
|
+
|
|
4
|
+
resources:
|
|
5
|
+
# Prometheus
|
|
6
|
+
- prometheus-rbac.yaml
|
|
7
|
+
- prometheus-configmap.yaml
|
|
8
|
+
- prometheus-pvc.yaml
|
|
9
|
+
- prometheus-deployment.yaml
|
|
10
|
+
- prometheus-service.yaml
|
|
11
|
+
# Grafana
|
|
12
|
+
- grafana-pvc.yaml
|
|
13
|
+
- grafana-provisioning-configmap.yaml
|
|
14
|
+
- grafana-deployment.yaml
|
|
15
|
+
- grafana-service.yaml
|
|
16
|
+
# Loki
|
|
17
|
+
- loki-configmap.yaml
|
|
18
|
+
- loki-pvc.yaml
|
|
19
|
+
- loki-deployment.yaml
|
|
20
|
+
- loki-service.yaml
|
|
21
|
+
# Network policies
|
|
22
|
+
- network-policy.yaml
|
|
23
|
+
# IngressRoute (applied when service is deployed)
|
|
24
|
+
- ingressroute.yaml
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# LOKI CONFIGURATION
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Single-process mode with local filesystem storage.
|
|
5
|
+
# Suitable for single-node clusters; for HA, switch to S3-backed storage.
|
|
6
|
+
apiVersion: v1
|
|
7
|
+
kind: ConfigMap
|
|
8
|
+
metadata:
|
|
9
|
+
name: loki-config
|
|
10
|
+
labels:
|
|
11
|
+
app: vibecarbon-loki
|
|
12
|
+
component: observability
|
|
13
|
+
data:
|
|
14
|
+
loki-config.yaml: |
|
|
15
|
+
auth_enabled: false
|
|
16
|
+
|
|
17
|
+
server:
|
|
18
|
+
http_listen_port: 3100
|
|
19
|
+
grpc_listen_port: 9096
|
|
20
|
+
|
|
21
|
+
common:
|
|
22
|
+
path_prefix: /loki
|
|
23
|
+
storage:
|
|
24
|
+
filesystem:
|
|
25
|
+
chunks_directory: /loki/chunks
|
|
26
|
+
rules_directory: /loki/rules
|
|
27
|
+
replication_factor: 1
|
|
28
|
+
ring:
|
|
29
|
+
instance_addr: 127.0.0.1
|
|
30
|
+
kvstore:
|
|
31
|
+
store: inmemory
|
|
32
|
+
|
|
33
|
+
query_range:
|
|
34
|
+
results_cache:
|
|
35
|
+
cache:
|
|
36
|
+
embedded_cache:
|
|
37
|
+
enabled: true
|
|
38
|
+
max_size_mb: 100
|
|
39
|
+
|
|
40
|
+
schema_config:
|
|
41
|
+
configs:
|
|
42
|
+
- from: "2024-01-01"
|
|
43
|
+
store: tsdb
|
|
44
|
+
object_store: filesystem
|
|
45
|
+
schema: v13
|
|
46
|
+
index:
|
|
47
|
+
prefix: index_
|
|
48
|
+
period: 24h
|
|
49
|
+
|
|
50
|
+
storage_config:
|
|
51
|
+
tsdb_shipper:
|
|
52
|
+
active_index_directory: /loki/tsdb-index
|
|
53
|
+
cache_location: /loki/tsdb-cache
|
|
54
|
+
|
|
55
|
+
limits_config:
|
|
56
|
+
reject_old_samples: true
|
|
57
|
+
reject_old_samples_max_age: 168h # 7 days
|
|
58
|
+
max_query_series: 5000
|
|
59
|
+
max_query_parallelism: 2
|
|
60
|
+
|
|
61
|
+
compactor:
|
|
62
|
+
working_directory: /loki/compactor
|
|
63
|
+
compaction_interval: 10m
|
|
64
|
+
retention_enabled: true
|
|
65
|
+
retention_delete_delay: 2h
|
|
66
|
+
retention_delete_worker_count: 150
|
|
67
|
+
# Loki 3.x requires delete_request_store when retention_enabled is true,
|
|
68
|
+
# else the container crash-loops with "CONFIG ERROR: invalid compactor
|
|
69
|
+
# config". Mirrors the compose fix (volumes/loki/loki-config.yml);
|
|
70
|
+
# filesystem matches object_store above.
|
|
71
|
+
delete_request_store: filesystem
|
|
72
|
+
|
|
73
|
+
analytics:
|
|
74
|
+
reporting_enabled: false
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
apiVersion: apps/v1
|
|
2
|
+
kind: Deployment
|
|
3
|
+
metadata:
|
|
4
|
+
name: loki
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-loki
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
replicas: 1
|
|
10
|
+
strategy:
|
|
11
|
+
type: Recreate
|
|
12
|
+
selector:
|
|
13
|
+
matchLabels:
|
|
14
|
+
app: vibecarbon-loki
|
|
15
|
+
template:
|
|
16
|
+
metadata:
|
|
17
|
+
labels:
|
|
18
|
+
app: vibecarbon-loki
|
|
19
|
+
component: observability
|
|
20
|
+
spec:
|
|
21
|
+
securityContext:
|
|
22
|
+
fsGroup: 10001
|
|
23
|
+
runAsUser: 10001
|
|
24
|
+
runAsGroup: 10001
|
|
25
|
+
seccompProfile:
|
|
26
|
+
type: RuntimeDefault
|
|
27
|
+
containers:
|
|
28
|
+
- name: loki
|
|
29
|
+
image: grafana/loki:latest
|
|
30
|
+
imagePullPolicy: IfNotPresent
|
|
31
|
+
args:
|
|
32
|
+
- -config.file=/etc/loki/loki-config.yaml
|
|
33
|
+
ports:
|
|
34
|
+
- containerPort: 3100
|
|
35
|
+
name: http
|
|
36
|
+
volumeMounts:
|
|
37
|
+
- name: config
|
|
38
|
+
mountPath: /etc/loki
|
|
39
|
+
- name: data
|
|
40
|
+
mountPath: /loki
|
|
41
|
+
resources:
|
|
42
|
+
requests:
|
|
43
|
+
cpu: 100m
|
|
44
|
+
memory: 256Mi
|
|
45
|
+
limits:
|
|
46
|
+
cpu: 500m
|
|
47
|
+
memory: 512Mi
|
|
48
|
+
livenessProbe:
|
|
49
|
+
httpGet:
|
|
50
|
+
path: /ready
|
|
51
|
+
port: http
|
|
52
|
+
initialDelaySeconds: 30
|
|
53
|
+
periodSeconds: 20
|
|
54
|
+
timeoutSeconds: 5
|
|
55
|
+
failureThreshold: 3
|
|
56
|
+
readinessProbe:
|
|
57
|
+
httpGet:
|
|
58
|
+
path: /ready
|
|
59
|
+
port: http
|
|
60
|
+
initialDelaySeconds: 15
|
|
61
|
+
periodSeconds: 10
|
|
62
|
+
timeoutSeconds: 3
|
|
63
|
+
failureThreshold: 3
|
|
64
|
+
securityContext:
|
|
65
|
+
allowPrivilegeEscalation: false
|
|
66
|
+
volumes:
|
|
67
|
+
- name: config
|
|
68
|
+
configMap:
|
|
69
|
+
name: loki-config
|
|
70
|
+
- name: data
|
|
71
|
+
persistentVolumeClaim:
|
|
72
|
+
claimName: loki-pvc
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: PersistentVolumeClaim
|
|
3
|
+
metadata:
|
|
4
|
+
name: loki-pvc
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-loki
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
accessModes:
|
|
10
|
+
- ReadWriteOnce
|
|
11
|
+
storageClassName: hcloud-volumes
|
|
12
|
+
resources:
|
|
13
|
+
requests:
|
|
14
|
+
storage: 10Gi
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: loki
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-loki
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
type: ClusterIP
|
|
10
|
+
ports:
|
|
11
|
+
- port: 3100
|
|
12
|
+
targetPort: http
|
|
13
|
+
protocol: TCP
|
|
14
|
+
name: http
|
|
15
|
+
selector:
|
|
16
|
+
app: vibecarbon-loki
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# OBSERVABILITY NETWORK POLICIES
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Each observability service gets its own policy to satisfy the default-deny-all
|
|
5
|
+
# baseline. Only explicitly needed traffic paths are opened.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
# =============================================================================
|
|
9
|
+
# PROMETHEUS NETWORK POLICY
|
|
10
|
+
# =============================================================================
|
|
11
|
+
apiVersion: networking.k8s.io/v1
|
|
12
|
+
kind: NetworkPolicy
|
|
13
|
+
metadata:
|
|
14
|
+
name: prometheus-policy
|
|
15
|
+
namespace: vibecarbon
|
|
16
|
+
spec:
|
|
17
|
+
podSelector:
|
|
18
|
+
matchLabels:
|
|
19
|
+
app: vibecarbon-prometheus
|
|
20
|
+
policyTypes:
|
|
21
|
+
- Ingress
|
|
22
|
+
- Egress
|
|
23
|
+
ingress:
|
|
24
|
+
# Allow health checks from the app (services-status API)
|
|
25
|
+
- from:
|
|
26
|
+
- podSelector:
|
|
27
|
+
matchLabels:
|
|
28
|
+
app: vibecarbon-app
|
|
29
|
+
ports:
|
|
30
|
+
- protocol: TCP
|
|
31
|
+
port: 9090
|
|
32
|
+
# Allow Grafana to query metrics
|
|
33
|
+
- from:
|
|
34
|
+
- podSelector:
|
|
35
|
+
matchLabels:
|
|
36
|
+
app: vibecarbon-grafana
|
|
37
|
+
ports:
|
|
38
|
+
- protocol: TCP
|
|
39
|
+
port: 9090
|
|
40
|
+
egress:
|
|
41
|
+
# Scrape all pods in the namespace (any port, since scrape targets vary)
|
|
42
|
+
- to:
|
|
43
|
+
- podSelector: {}
|
|
44
|
+
# Scrape kubelet/cAdvisor on k3s nodes (port 10250)
|
|
45
|
+
# Node IPs are outside the cluster CIDR, so allow broad egress to node network
|
|
46
|
+
- to:
|
|
47
|
+
- ipBlock:
|
|
48
|
+
cidr: 0.0.0.0/0
|
|
49
|
+
except:
|
|
50
|
+
- 10.42.0.0/16 # Exclude pod CIDR (already covered by podSelector above)
|
|
51
|
+
ports:
|
|
52
|
+
- protocol: TCP
|
|
53
|
+
port: 10250
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
# =============================================================================
|
|
57
|
+
# GRAFANA NETWORK POLICY
|
|
58
|
+
# =============================================================================
|
|
59
|
+
apiVersion: networking.k8s.io/v1
|
|
60
|
+
kind: NetworkPolicy
|
|
61
|
+
metadata:
|
|
62
|
+
name: grafana-policy
|
|
63
|
+
namespace: vibecarbon
|
|
64
|
+
spec:
|
|
65
|
+
podSelector:
|
|
66
|
+
matchLabels:
|
|
67
|
+
app: vibecarbon-grafana
|
|
68
|
+
policyTypes:
|
|
69
|
+
- Ingress
|
|
70
|
+
- Egress
|
|
71
|
+
ingress:
|
|
72
|
+
# Allow traffic from Traefik (IngressRoute for /admin/grafana)
|
|
73
|
+
- from:
|
|
74
|
+
- podSelector:
|
|
75
|
+
matchLabels:
|
|
76
|
+
app: vibecarbon-traefik
|
|
77
|
+
ports:
|
|
78
|
+
- protocol: TCP
|
|
79
|
+
port: 3000
|
|
80
|
+
# Allow health checks from the app (services-status API)
|
|
81
|
+
- from:
|
|
82
|
+
- podSelector:
|
|
83
|
+
matchLabels:
|
|
84
|
+
app: vibecarbon-app
|
|
85
|
+
ports:
|
|
86
|
+
- protocol: TCP
|
|
87
|
+
port: 3000
|
|
88
|
+
egress:
|
|
89
|
+
# Query Prometheus for metrics
|
|
90
|
+
- to:
|
|
91
|
+
- podSelector:
|
|
92
|
+
matchLabels:
|
|
93
|
+
app: vibecarbon-prometheus
|
|
94
|
+
ports:
|
|
95
|
+
- protocol: TCP
|
|
96
|
+
port: 9090
|
|
97
|
+
# Query Loki for logs
|
|
98
|
+
- to:
|
|
99
|
+
- podSelector:
|
|
100
|
+
matchLabels:
|
|
101
|
+
app: vibecarbon-loki
|
|
102
|
+
ports:
|
|
103
|
+
- protocol: TCP
|
|
104
|
+
port: 3100
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
# =============================================================================
|
|
108
|
+
# LOKI NETWORK POLICY
|
|
109
|
+
# =============================================================================
|
|
110
|
+
apiVersion: networking.k8s.io/v1
|
|
111
|
+
kind: NetworkPolicy
|
|
112
|
+
metadata:
|
|
113
|
+
name: loki-policy
|
|
114
|
+
namespace: vibecarbon
|
|
115
|
+
spec:
|
|
116
|
+
podSelector:
|
|
117
|
+
matchLabels:
|
|
118
|
+
app: vibecarbon-loki
|
|
119
|
+
policyTypes:
|
|
120
|
+
- Ingress
|
|
121
|
+
- Egress
|
|
122
|
+
ingress:
|
|
123
|
+
# Allow the app to push logs
|
|
124
|
+
- from:
|
|
125
|
+
- podSelector:
|
|
126
|
+
matchLabels:
|
|
127
|
+
app: vibecarbon-app
|
|
128
|
+
ports:
|
|
129
|
+
- protocol: TCP
|
|
130
|
+
port: 3100
|
|
131
|
+
# Allow Grafana to query logs
|
|
132
|
+
- from:
|
|
133
|
+
- podSelector:
|
|
134
|
+
matchLabels:
|
|
135
|
+
app: vibecarbon-grafana
|
|
136
|
+
ports:
|
|
137
|
+
- protocol: TCP
|
|
138
|
+
port: 3100
|
|
139
|
+
egress: []
|
|
140
|
+
# Loki in single-process mode with local storage has no outbound dependencies.
|
|
141
|
+
# DNS is handled by the allow-dns policy at the namespace level.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# PROMETHEUS CONFIGURATION
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Scrape config for k8s node metrics and postgres-exporter.
|
|
5
|
+
# Add additional scrape targets as services are deployed.
|
|
6
|
+
apiVersion: v1
|
|
7
|
+
kind: ConfigMap
|
|
8
|
+
metadata:
|
|
9
|
+
name: prometheus-config
|
|
10
|
+
labels:
|
|
11
|
+
app: vibecarbon-prometheus
|
|
12
|
+
component: observability
|
|
13
|
+
data:
|
|
14
|
+
prometheus.yml: |
|
|
15
|
+
global:
|
|
16
|
+
scrape_interval: 30s
|
|
17
|
+
evaluation_interval: 30s
|
|
18
|
+
|
|
19
|
+
scrape_configs:
|
|
20
|
+
# Scrape Prometheus's own metrics
|
|
21
|
+
- job_name: "prometheus"
|
|
22
|
+
static_configs:
|
|
23
|
+
- targets: ["localhost:9090"]
|
|
24
|
+
|
|
25
|
+
# Scrape Kubernetes node metrics via kubelet
|
|
26
|
+
# k3s exposes metrics on the default kubelet port
|
|
27
|
+
- job_name: "kubernetes-nodes"
|
|
28
|
+
scheme: https
|
|
29
|
+
tls_config:
|
|
30
|
+
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
31
|
+
insecure_skip_verify: true
|
|
32
|
+
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
33
|
+
kubernetes_sd_configs:
|
|
34
|
+
- role: node
|
|
35
|
+
relabel_configs:
|
|
36
|
+
- action: labelmap
|
|
37
|
+
regex: __meta_kubernetes_node_label_(.+)
|
|
38
|
+
|
|
39
|
+
# Scrape cAdvisor metrics from kubelet (container resource usage)
|
|
40
|
+
- job_name: "kubernetes-cadvisor"
|
|
41
|
+
scheme: https
|
|
42
|
+
tls_config:
|
|
43
|
+
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
44
|
+
insecure_skip_verify: true
|
|
45
|
+
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
46
|
+
kubernetes_sd_configs:
|
|
47
|
+
- role: node
|
|
48
|
+
metrics_path: /metrics/cadvisor
|
|
49
|
+
relabel_configs:
|
|
50
|
+
- action: labelmap
|
|
51
|
+
regex: __meta_kubernetes_node_label_(.+)
|
|
52
|
+
|
|
53
|
+
# Scrape pods with prometheus.io/scrape annotation
|
|
54
|
+
- job_name: "kubernetes-pods"
|
|
55
|
+
kubernetes_sd_configs:
|
|
56
|
+
- role: pod
|
|
57
|
+
namespaces:
|
|
58
|
+
names:
|
|
59
|
+
- vibecarbon
|
|
60
|
+
relabel_configs:
|
|
61
|
+
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
|
|
62
|
+
action: keep
|
|
63
|
+
regex: "true"
|
|
64
|
+
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
|
|
65
|
+
action: replace
|
|
66
|
+
target_label: __metrics_path__
|
|
67
|
+
regex: (.+)
|
|
68
|
+
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
|
|
69
|
+
action: replace
|
|
70
|
+
regex: ([^:]+)(?::\d+)?;(\d+)
|
|
71
|
+
replacement: $1:$2
|
|
72
|
+
target_label: __address__
|
|
73
|
+
- action: labelmap
|
|
74
|
+
regex: __meta_kubernetes_pod_label_(.+)
|
|
75
|
+
- source_labels: [__meta_kubernetes_namespace]
|
|
76
|
+
action: replace
|
|
77
|
+
target_label: kubernetes_namespace
|
|
78
|
+
- source_labels: [__meta_kubernetes_pod_name]
|
|
79
|
+
action: replace
|
|
80
|
+
target_label: kubernetes_pod_name
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
apiVersion: apps/v1
|
|
2
|
+
kind: Deployment
|
|
3
|
+
metadata:
|
|
4
|
+
name: prometheus
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-prometheus
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
replicas: 1
|
|
10
|
+
strategy:
|
|
11
|
+
type: Recreate
|
|
12
|
+
selector:
|
|
13
|
+
matchLabels:
|
|
14
|
+
app: vibecarbon-prometheus
|
|
15
|
+
template:
|
|
16
|
+
metadata:
|
|
17
|
+
labels:
|
|
18
|
+
app: vibecarbon-prometheus
|
|
19
|
+
component: observability
|
|
20
|
+
spec:
|
|
21
|
+
serviceAccountName: prometheus
|
|
22
|
+
securityContext:
|
|
23
|
+
fsGroup: 65534
|
|
24
|
+
runAsUser: 65534
|
|
25
|
+
runAsGroup: 65534
|
|
26
|
+
seccompProfile:
|
|
27
|
+
type: RuntimeDefault
|
|
28
|
+
containers:
|
|
29
|
+
- name: prometheus
|
|
30
|
+
image: prom/prometheus:latest
|
|
31
|
+
imagePullPolicy: IfNotPresent
|
|
32
|
+
args:
|
|
33
|
+
- --config.file=/etc/prometheus/prometheus.yml
|
|
34
|
+
- --storage.tsdb.path=/prometheus
|
|
35
|
+
- --storage.tsdb.retention.time=15d
|
|
36
|
+
- --web.console.libraries=/etc/prometheus/console_libraries
|
|
37
|
+
- --web.console.templates=/etc/prometheus/consoles
|
|
38
|
+
- --web.enable-lifecycle
|
|
39
|
+
ports:
|
|
40
|
+
- containerPort: 9090
|
|
41
|
+
name: http
|
|
42
|
+
volumeMounts:
|
|
43
|
+
- name: config
|
|
44
|
+
mountPath: /etc/prometheus
|
|
45
|
+
- name: data
|
|
46
|
+
mountPath: /prometheus
|
|
47
|
+
resources:
|
|
48
|
+
requests:
|
|
49
|
+
cpu: 100m
|
|
50
|
+
memory: 256Mi
|
|
51
|
+
limits:
|
|
52
|
+
cpu: 500m
|
|
53
|
+
memory: 512Mi
|
|
54
|
+
livenessProbe:
|
|
55
|
+
httpGet:
|
|
56
|
+
path: /-/healthy
|
|
57
|
+
port: http
|
|
58
|
+
initialDelaySeconds: 15
|
|
59
|
+
periodSeconds: 20
|
|
60
|
+
timeoutSeconds: 5
|
|
61
|
+
failureThreshold: 3
|
|
62
|
+
readinessProbe:
|
|
63
|
+
httpGet:
|
|
64
|
+
path: /-/ready
|
|
65
|
+
port: http
|
|
66
|
+
initialDelaySeconds: 5
|
|
67
|
+
periodSeconds: 10
|
|
68
|
+
timeoutSeconds: 3
|
|
69
|
+
failureThreshold: 3
|
|
70
|
+
securityContext:
|
|
71
|
+
allowPrivilegeEscalation: false
|
|
72
|
+
volumes:
|
|
73
|
+
- name: config
|
|
74
|
+
configMap:
|
|
75
|
+
name: prometheus-config
|
|
76
|
+
- name: data
|
|
77
|
+
persistentVolumeClaim:
|
|
78
|
+
claimName: prometheus-pvc
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: PersistentVolumeClaim
|
|
3
|
+
metadata:
|
|
4
|
+
name: prometheus-pvc
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-prometheus
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
accessModes:
|
|
10
|
+
- ReadWriteOnce
|
|
11
|
+
storageClassName: hcloud-volumes
|
|
12
|
+
resources:
|
|
13
|
+
requests:
|
|
14
|
+
storage: 10Gi
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# PROMETHEUS RBAC
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Prometheus needs cluster-wide read access to discover and scrape targets.
|
|
5
|
+
# ServiceAccount is namespace-scoped; ClusterRole + ClusterRoleBinding grant
|
|
6
|
+
# read access to nodes, pods, services, and endpoints across all namespaces.
|
|
7
|
+
apiVersion: v1
|
|
8
|
+
kind: ServiceAccount
|
|
9
|
+
metadata:
|
|
10
|
+
name: prometheus
|
|
11
|
+
labels:
|
|
12
|
+
app: vibecarbon-prometheus
|
|
13
|
+
component: observability
|
|
14
|
+
---
|
|
15
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
16
|
+
kind: ClusterRole
|
|
17
|
+
metadata:
|
|
18
|
+
name: vibecarbon-prometheus
|
|
19
|
+
labels:
|
|
20
|
+
app: vibecarbon-prometheus
|
|
21
|
+
component: observability
|
|
22
|
+
rules:
|
|
23
|
+
- apiGroups: [""]
|
|
24
|
+
resources:
|
|
25
|
+
- nodes
|
|
26
|
+
- nodes/proxy
|
|
27
|
+
- nodes/metrics
|
|
28
|
+
- services
|
|
29
|
+
- endpoints
|
|
30
|
+
- pods
|
|
31
|
+
verbs: ["get", "list", "watch"]
|
|
32
|
+
- apiGroups: ["networking.k8s.io"]
|
|
33
|
+
resources:
|
|
34
|
+
- ingresses
|
|
35
|
+
verbs: ["get", "list", "watch"]
|
|
36
|
+
- nonResourceURLs:
|
|
37
|
+
- /metrics
|
|
38
|
+
- /metrics/cadvisor
|
|
39
|
+
verbs: ["get"]
|
|
40
|
+
---
|
|
41
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
42
|
+
kind: ClusterRoleBinding
|
|
43
|
+
metadata:
|
|
44
|
+
name: vibecarbon-prometheus
|
|
45
|
+
labels:
|
|
46
|
+
app: vibecarbon-prometheus
|
|
47
|
+
component: observability
|
|
48
|
+
roleRef:
|
|
49
|
+
apiGroup: rbac.authorization.k8s.io
|
|
50
|
+
kind: ClusterRole
|
|
51
|
+
name: vibecarbon-prometheus
|
|
52
|
+
subjects:
|
|
53
|
+
- kind: ServiceAccount
|
|
54
|
+
name: prometheus
|
|
55
|
+
namespace: vibecarbon
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: prometheus
|
|
5
|
+
labels:
|
|
6
|
+
app: vibecarbon-prometheus
|
|
7
|
+
component: observability
|
|
8
|
+
spec:
|
|
9
|
+
type: ClusterIP
|
|
10
|
+
ports:
|
|
11
|
+
- port: 9090
|
|
12
|
+
targetPort: http
|
|
13
|
+
protocol: TCP
|
|
14
|
+
name: http
|
|
15
|
+
selector:
|
|
16
|
+
app: vibecarbon-prometheus
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "observability",
|
|
3
|
+
"description": "Prometheus, Grafana, Loki monitoring stack",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"url": "http://grafana.localhost",
|
|
6
|
+
|
|
7
|
+
"files": {
|
|
8
|
+
"compose/docker-compose.yml": "docker-compose.observability.yml",
|
|
9
|
+
"compose/docker-compose.prod.yml": "docker-compose.observability.prod.yml",
|
|
10
|
+
"compose/docker-compose.override.yml": "docker-compose.observability.override.yml",
|
|
11
|
+
"volumes/": "volumes/",
|
|
12
|
+
"k8s/": "k8s/base/observability/",
|
|
13
|
+
"docs/integration.md": "observability-integration.md"
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
"credentials": {
|
|
17
|
+
"title": "Observability Stack",
|
|
18
|
+
"fields": [
|
|
19
|
+
{ "label": "Grafana", "value": "http://grafana.localhost (k8s: /admin/grafana via Traefik admin-auth)" },
|
|
20
|
+
{ "label": "Prometheus", "value": "http://prometheus.localhost (k8s: in-cluster :9090)" },
|
|
21
|
+
{ "label": "Loki", "value": "http://loki.localhost (k8s: in-cluster :3100)" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"kustomization": {
|
|
26
|
+
"entry": "observability/"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Redis - Production Overrides
|
|
2
|
+
# Use with: docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.redis.yml -f docker-compose.redis.prod.yml up -d
|
|
3
|
+
#
|
|
4
|
+
# Redis is an internal cache/session store — the app reaches it over the compose
|
|
5
|
+
# network (redis://redis:6379). Drop the dev host-port publishing so prod never
|
|
6
|
+
# binds 6379 on the host (defense-in-depth behind the 22/80/443-only firewall).
|
|
7
|
+
|
|
8
|
+
services:
|
|
9
|
+
redis:
|
|
10
|
+
ports: []
|