Add platform infrastructure configuration
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Grafana
|
||||
|
||||
Private Grafana for the home observability stack. The pinned Grafana chart is
|
||||
rendered as the independent `grafana` release in `observability`; the
|
||||
kube-prometheus-stack embedded Grafana remains disabled.
|
||||
|
||||
The workload consumes, but never renders, these existing Secret contracts:
|
||||
|
||||
- `grafana-admin`: `admin-user`, `admin-password`
|
||||
- `grafana-keycloak-oidc`: `client-id`, `client-secret`
|
||||
|
||||
The `grafana` PVC is fixed to `observability-grafana-local-pv` (2Gi, Retain).
|
||||
Host Nginx terminates the exact-SAN certificate and forwards plain HTTP through
|
||||
Traefik; the Kubernetes Ingress therefore contains no TLS material.
|
||||
|
||||
The Pod does not automount a service-account token. A 3600-second projected
|
||||
token, CA, and namespace are mounted only into `grafana-sc-dashboard`, whose
|
||||
namespaced Role can read ConfigMaps but not Secrets. Dashboard ConfigMaps must
|
||||
carry `grafana_dashboard: "1"` in `observability`.
|
||||
|
||||
Provisioned datasource UIDs are `prometheus`, `loki`, and `tempo`. Tempo service
|
||||
map configuration is present for future use, but the metrics-generator and
|
||||
Prometheus remote-write path are intentionally not enabled, so service-graph
|
||||
availability is not an initial acceptance condition.
|
||||
@@ -0,0 +1,27 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: grafana-dashboard-sidecar
|
||||
namespace: observability
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: grafana-dashboard-sidecar
|
||||
namespace: observability
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: grafana-dashboard-sidecar
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: grafana
|
||||
namespace: observability
|
||||
@@ -0,0 +1,37 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: observability
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
hostNetwork: false
|
||||
hostPID: false
|
||||
hostIPC: false
|
||||
containers:
|
||||
- name: grafana-sc-dashboard
|
||||
volumeMounts:
|
||||
- name: dashboard-sidecar-api-access
|
||||
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: dashboard-sidecar-api-access
|
||||
projected:
|
||||
defaultMode: 420
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
expirationSeconds: 3600
|
||||
path: token
|
||||
- configMap:
|
||||
name: kube-root-ca.crt
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
- downwardAPI:
|
||||
items:
|
||||
- path: namespace
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: observability
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: observability
|
||||
|
||||
resources:
|
||||
- dashboard-sidecar-rbac.yaml
|
||||
|
||||
helmGlobals:
|
||||
chartHome: .helm/charts
|
||||
|
||||
helmCharts:
|
||||
- name: grafana
|
||||
repo: https://grafana-community.github.io/helm-charts
|
||||
version: 12.10.1
|
||||
releaseName: grafana
|
||||
namespace: observability
|
||||
valuesFile: values/home.yaml
|
||||
includeCRDs: false
|
||||
skipTests: true
|
||||
|
||||
patches:
|
||||
- path: ingress-class-patch.yaml
|
||||
- path: dashboard-sidecar-token-patch.yaml
|
||||
@@ -0,0 +1,262 @@
|
||||
replicas: 1
|
||||
|
||||
extraLabels:
|
||||
observability.hyeonworks.com/instance: home
|
||||
|
||||
deploymentStrategy:
|
||||
type: Recreate
|
||||
|
||||
revisionHistoryLimit: 3
|
||||
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
|
||||
rbac:
|
||||
create: false
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: grafana
|
||||
automountServiceAccountToken: false
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: grafana/grafana
|
||||
tag: 13.1.1
|
||||
sha: f33c692ba1a5ee15724cf6b22db65e9de39dde14d80f7d73a9546e3fc917270b
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
testFramework:
|
||||
enabled: false
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 472
|
||||
runAsGroup: 472
|
||||
fsGroup: 472
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
|
||||
initChownData:
|
||||
enabled: false
|
||||
|
||||
persistence:
|
||||
type: pvc
|
||||
enabled: true
|
||||
storageClassName: ssd-local-observability-grafana-retain
|
||||
volumeName: observability-grafana-local-pv
|
||||
lookupVolumeName: false
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
size: 2Gi
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
|
||||
admin:
|
||||
existingSecret: grafana-admin
|
||||
userKey: admin-user
|
||||
passwordKey: admin-password
|
||||
|
||||
envValueFrom:
|
||||
GF_AUTH_GENERIC_OAUTH_CLIENT_ID:
|
||||
secretKeyRef:
|
||||
name: grafana-keycloak-oidc
|
||||
key: client-id
|
||||
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET:
|
||||
secretKeyRef:
|
||||
name: grafana-keycloak-oidc
|
||||
key: client-secret
|
||||
|
||||
service:
|
||||
enabled: true
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
targetPort: 3000
|
||||
portName: service
|
||||
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
interval: 30s
|
||||
path: /metrics
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
annotations: {}
|
||||
path: /
|
||||
pathType: Prefix
|
||||
hosts:
|
||||
- grafana.learn.hyeonworks.com
|
||||
tls: []
|
||||
|
||||
grafana.ini:
|
||||
paths:
|
||||
data: /var/lib/grafana/
|
||||
logs: /var/log/grafana
|
||||
plugins: /var/lib/grafana/plugins
|
||||
provisioning: /etc/grafana/provisioning
|
||||
analytics:
|
||||
check_for_updates: false
|
||||
check_for_plugin_updates: false
|
||||
reporting_enabled: false
|
||||
plugins:
|
||||
preinstall_disabled: true
|
||||
server:
|
||||
domain: grafana.learn.hyeonworks.com
|
||||
root_url: https://grafana.learn.hyeonworks.com/
|
||||
enforce_domain: true
|
||||
security:
|
||||
cookie_secure: true
|
||||
cookie_samesite: lax
|
||||
auth:
|
||||
disable_login_form: false
|
||||
oauth_auto_login: false
|
||||
login_maximum_lifetime_duration: 8h
|
||||
login_maximum_inactive_lifetime_duration: 30m
|
||||
auth.anonymous:
|
||||
enabled: false
|
||||
auth.basic:
|
||||
enabled: true
|
||||
auth.generic_oauth:
|
||||
enabled: true
|
||||
name: Keycloak
|
||||
allow_sign_up: true
|
||||
use_pkce: true
|
||||
scopes: openid profile email
|
||||
groups_attribute_path: groups
|
||||
allowed_groups: /platform-observability-admins /platform-observability-viewers
|
||||
role_attribute_strict: true
|
||||
allow_assign_grafana_admin: false
|
||||
skip_org_role_sync: false
|
||||
validate_id_token: true
|
||||
use_refresh_token: true
|
||||
role_attribute_path: "contains(groups[*], '/platform-observability-admins') && 'Admin' || contains(groups[*], '/platform-observability-viewers') && 'Viewer' || null"
|
||||
auth_url: https://id.learn.hyeonworks.com/realms/hyeonworks/protocol/openid-connect/auth
|
||||
token_url: https://id.learn.hyeonworks.com/realms/hyeonworks/protocol/openid-connect/token
|
||||
api_url: https://id.learn.hyeonworks.com/realms/hyeonworks/protocol/openid-connect/userinfo
|
||||
signout_redirect_url: https://id.learn.hyeonworks.com/realms/hyeonworks/protocol/openid-connect/logout
|
||||
|
||||
datasources:
|
||||
datasources.yaml:
|
||||
apiVersion: 1
|
||||
deleteDatasources:
|
||||
- name: Prometheus
|
||||
orgId: 1
|
||||
- name: Loki
|
||||
orgId: 1
|
||||
- name: Tempo
|
||||
orgId: 1
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
uid: prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://observability-core-kube-pr-prometheus.observability.svc.cluster.local:9090
|
||||
isDefault: true
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
timeInterval: 30s
|
||||
- name: Loki
|
||||
uid: loki
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki.observability.svc.cluster.local:3100
|
||||
isDefault: false
|
||||
editable: false
|
||||
jsonData:
|
||||
derivedFields:
|
||||
- name: trace_id
|
||||
matcherRegex: '"trace_id"[[:space:]]*:[[:space:]]*"([0-9a-f]{32})"'
|
||||
datasourceUid: tempo
|
||||
url: '$${__value.raw}'
|
||||
- name: Tempo
|
||||
uid: tempo
|
||||
type: tempo
|
||||
access: proxy
|
||||
url: http://tempo.observability.svc.cluster.local:3200
|
||||
isDefault: false
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: GET
|
||||
nodeGraph:
|
||||
enabled: true
|
||||
serviceMap:
|
||||
datasourceUid: prometheus
|
||||
tracesToLogsV2:
|
||||
datasourceUid: loki
|
||||
spanStartTimeShift: -1m
|
||||
spanEndTimeShift: 1m
|
||||
tags:
|
||||
- key: k8s.namespace.name
|
||||
value: namespace
|
||||
- key: k8s.pod.name
|
||||
value: pod
|
||||
filterByTraceID: true
|
||||
filterBySpanID: false
|
||||
|
||||
sidecar:
|
||||
image:
|
||||
registry: quay.io
|
||||
repository: kiwigrid/k8s-sidecar
|
||||
tag: 2.10.0
|
||||
sha: 129877c81acf2bc8c3fa000e89a62e020eb89d41ceb94767c657aef5bb0cc0d3
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
dashboards:
|
||||
enabled: true
|
||||
label: grafana_dashboard
|
||||
labelValue: "1"
|
||||
searchNamespace:
|
||||
- observability
|
||||
resource: configmap
|
||||
watchMethod: WATCH
|
||||
skipReload: true
|
||||
provider:
|
||||
name: sidecarProvider
|
||||
orgid: 1
|
||||
folder: ""
|
||||
folderUid: ""
|
||||
type: file
|
||||
disableDelete: false
|
||||
allowUiUpdates: false
|
||||
foldersFromFilesStructure: false
|
||||
|
||||
imageRenderer:
|
||||
enabled: false
|
||||
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
|
||||
assertNoLeakedSecrets: true
|
||||
Reference in New Issue
Block a user