feat(llm-inference): move astro-orbiter monitoring to GitOps (values.yaml + dashboards.yaml)

- Prometheus scrape configs for node/gpu/llama-server exporters on
  astro-orbiter now declared in cluster/applications/monitoring/values.yaml
  (additionalScrapeConfigs), applied via ArgoCD sync instead of an
  imperative kubectl secret patch from the Ansible role.
- Grafana dashboard for astro-orbiter LLM inference added as a ConfigMap
  in cluster/applications/monitoring/dashboards.yaml (grafana_dashboard=1
  sidecar label), replacing the role's ad-hoc kubectl apply of a rendered
  Jinja template.
- ansible/roles/llm-inference/tasks/monitoring.yml: removed the kubectl
  get/patch/apply tasks and orphaned grafana-llm-dashboard.json.j2
  template; role now only stands up node_exporter + nvidia_gpu_exporter
  and verifies they're reachable — cluster-facing config lives in Git.
- host_vars/vars.yml + inventory.yml: finalize astro-orbiter as the
  llama.cpp/RTX 3090 host (jarvis user, ssh key), drop stale Ollama/AMD
  vars and ollama_server inventory group superseded by the ATX rebuild.
This commit is contained in:
Hermes Agent service account
2026-08-05 09:43:54 -05:00
parent aa8e229e64
commit aff792a061
8 changed files with 324 additions and 398 deletions

View File

@@ -1,293 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-llm-inference-dashboard
namespace: monitoring
labels:
grafana_dashboard: "1"
data:
llm-inference.json: |
{
"title": "LLM Inference — astro-orbiter",
"uid": "llm-astro-orbiter",
"timezone": "browser",
"refresh": "30s",
"schemaVersion": 38,
"tags": ["llm", "gpu", "vllm", "astro-orbiter"],
"time": { "from": "now-1h", "to": "now" },
"templating": {
"list": [
{
"name": "instance",
"type": "constant",
"label": "Host",
"query": "{{ hostvars['astro-orbiter']['ansible_host'] }}",
"hide": 0
}
]
},
"panels": [
{
"id": 1,
"title": "GPU Utilization %",
"type": "timeseries",
"gridPos": { "x": 0, "y": 0, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0, "max": 100,
"color": { "mode": "palette-classic" },
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 70 },
{ "color": "red", "value": 90 }
]
}
}
},
"targets": [
{
"expr": "nvidia_smi_utilization_gpu_ratio{hostname=\"astro-orbiter\"} * 100",
"legendFormat": "GPU Util"
}
]
},
{
"id": 2,
"title": "GPU VRAM Used",
"type": "timeseries",
"gridPos": { "x": 8, "y": 0, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "bytes",
"color": { "mode": "palette-classic" }
}
},
"targets": [
{
"expr": "nvidia_smi_memory_used_bytes{hostname=\"astro-orbiter\"}",
"legendFormat": "VRAM Used"
},
{
"expr": "nvidia_smi_memory_total_bytes{hostname=\"astro-orbiter\"}",
"legendFormat": "VRAM Total"
}
]
},
{
"id": 3,
"title": "GPU Temperature",
"type": "gauge",
"gridPos": { "x": 16, "y": 0, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "celsius",
"min": 0, "max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 70 },
{ "color": "red", "value": 85 }
]
}
}
},
"targets": [
{
"expr": "nvidia_smi_temperature_gpu{hostname=\"astro-orbiter\"}",
"legendFormat": "GPU Temp"
}
]
},
{
"id": 4,
"title": "GPU Power Draw",
"type": "timeseries",
"gridPos": { "x": 0, "y": 8, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "watt",
"color": { "mode": "palette-classic" }
}
},
"targets": [
{
"expr": "nvidia_smi_power_draw_watts{hostname=\"astro-orbiter\"}",
"legendFormat": "Power Draw"
},
{
"expr": "nvidia_smi_power_limit_watts{hostname=\"astro-orbiter\"}",
"legendFormat": "Power Limit"
}
]
},
{
"id": 5,
"title": "vLLM — Token Throughput",
"type": "timeseries",
"gridPos": { "x": 8, "y": 8, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "reqps",
"color": { "mode": "palette-classic" }
}
},
"targets": [
{
"expr": "rate(vllm:generation_tokens_total{hostname=\"astro-orbiter\"}[1m])",
"legendFormat": "Tokens/s (gen)"
},
{
"expr": "rate(vllm:prompt_tokens_total{hostname=\"astro-orbiter\"}[1m])",
"legendFormat": "Tokens/s (prompt)"
}
]
},
{
"id": 6,
"title": "vLLM — Request Queue Depth",
"type": "timeseries",
"gridPos": { "x": 16, "y": 8, "w": 8, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "short",
"color": { "mode": "palette-classic" }
}
},
"targets": [
{
"expr": "vllm:num_requests_running{hostname=\"astro-orbiter\"}",
"legendFormat": "Running"
},
{
"expr": "vllm:num_requests_waiting{hostname=\"astro-orbiter\"}",
"legendFormat": "Waiting"
},
{
"expr": "vllm:num_requests_swapped{hostname=\"astro-orbiter\"}",
"legendFormat": "Swapped"
}
]
},
{
"id": 7,
"title": "vLLM — E2E Request Latency (p50/p95/p99)",
"type": "timeseries",
"gridPos": { "x": 0, "y": 16, "w": 12, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "s",
"color": { "mode": "palette-classic" }
}
},
"targets": [
{
"expr": "histogram_quantile(0.50, rate(vllm:e2e_request_latency_seconds_bucket{hostname=\"astro-orbiter\"}[5m]))",
"legendFormat": "p50"
},
{
"expr": "histogram_quantile(0.95, rate(vllm:e2e_request_latency_seconds_bucket{hostname=\"astro-orbiter\"}[5m]))",
"legendFormat": "p95"
},
{
"expr": "histogram_quantile(0.99, rate(vllm:e2e_request_latency_seconds_bucket{hostname=\"astro-orbiter\"}[5m]))",
"legendFormat": "p99"
}
]
},
{
"id": 8,
"title": "vLLM — KV Cache Utilization %",
"type": "timeseries",
"gridPos": { "x": 12, "y": 16, "w": 12, "h": 8 },
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0, "max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 75 },
{ "color": "red", "value": 90 }
]
}
}
},
"targets": [
{
"expr": "vllm:gpu_cache_usage_perc{hostname=\"astro-orbiter\"} * 100",
"legendFormat": "KV Cache %"
}
]
},
{
"id": 9,
"title": "System — CPU Usage %",
"type": "timeseries",
"gridPos": { "x": 0, "y": 24, "w": 8, "h": 7 },
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0, "max": 100
}
},
"targets": [
{
"expr": "100 - (avg by(instance) (rate(node_cpu_seconds_total{mode=\"idle\",instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\"}[1m])) * 100)",
"legendFormat": "CPU Used"
}
]
},
{
"id": 10,
"title": "System — Memory Usage",
"type": "timeseries",
"gridPos": { "x": 8, "y": 24, "w": 8, "h": 7 },
"fieldConfig": {
"defaults": {
"unit": "bytes"
}
},
"targets": [
{
"expr": "node_memory_MemTotal_bytes{instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\"} - node_memory_MemAvailable_bytes{instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\"}",
"legendFormat": "Used"
},
{
"expr": "node_memory_MemTotal_bytes{instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\"}",
"legendFormat": "Total"
}
]
},
{
"id": 11,
"title": "System — Disk Usage (root)",
"type": "gauge",
"gridPos": { "x": 16, "y": 24, "w": 8, "h": 7 },
"fieldConfig": {
"defaults": {
"unit": "percentunit",
"min": 0, "max": 1,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 0.75 },
{ "color": "red", "value": 0.90 }
]
}
}
},
"targets": [
{
"expr": "1 - (node_filesystem_avail_bytes{instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\",mountpoint=\"/\"} / node_filesystem_size_bytes{instance=~\"{{ hostvars['astro-orbiter']['ansible_host'] }}:.*\",mountpoint=\"/\"})",
"legendFormat": "Root disk"
}
]
}
]
}

View File

@@ -15,7 +15,12 @@ ExecStart=/opt/llama.cpp/build/bin/llama-server \
--ctx-size {{ llm_max_model_len }} \
--n-gpu-layers {{ llm_gpu_layers }} \
--parallel {{ llm_parallel_slots }} \
--chat-template gemma
--metrics
# NOTE: no --chat-template flag — llama-server auto-detects and uses the
# GGUF's own embedded Jinja chat template (verified correct Gemma-2
# start_of_turn/end_of_turn format for bartowski's gemma-2-27b-it-Q4_K_M).
# The built-in "--chat-template gemma" name does NOT match this model's
# expected format on this llama.cpp build and produced garbled completions.
Restart=on-failure
RestartSec=10
TimeoutStartSec=120