{% extends "base.html" %} {% block title %}Kubernetes{% endblock %} {% block content %} {% from '_limit.html' import limit, paused, locked %} {% if not plan.kubernetes %}{{ locked('Kubernetes monitoring is on Pro (3 clusters) and Enterprise, or the Observability module. Nodes keep reporting basic metrics.') }}{% endif %}
Every node runs the Vigil agent as a DaemonSet and reports its pods, container states and node conditions. {{ totals.clusters }} cluster{{ 's' if totals.clusters != 1 }} · {{ totals.nodes }} node{{ 's' if totals.nodes != 1 }} · {{ totals.pods }} pods.
Creates namespace vigil, a ServiceAccount with read access to pods/nodes, a Secret with the token and a DaemonSet (python:3.12-slim, hostNetwork, host filesystem mounted read-only at /host). Each node shows up as a server named <cluster>/<node>. Change cluster= to name the cluster; the token below belongs to {{ token_server.name }} (any server token in this workspace works; nodes register themselves).
kubectl apply -f "{{ manifest }}"
{% if not manifest_ready %}Verify: kubectl -n vigil get pods -o wide · logs: kubectl -n vigil logs ds/vigil-agent · remove: kubectl delete ns vigil (plus the ClusterRole/Binding).
Add a server first (Servers → Add server) to get a token, then come back for the kubectl apply one-liner.
Apply the DaemonSet above. Nodes appear here within a minute, grouped by cluster, with pods, restarts, CrashLoopBackOff / OOMKilled containers and node pressure conditions.
| {{ p.kind }} | {% if p.kind == 'pod' %}{{ p.namespace }}/{{ p.name }}{% else %}{{ p.node }}{% endif %} | {{ p.what }} | {% if p.kind == 'pod' %}on {{ p.node }}{% endif %} | node → |
| Namespace | Pod | Node | Phase | Ready | Restarts | Containers | CPU | Memory | Age |
|---|---|---|---|---|---|---|---|---|---|
| {{ p.namespace }} | {{ p.name }}{% if p.owner %} {{ p.owner }} {% endif %} | {{ p.node }} | {{ p.phase or '?' }}{% for pr in p.problems %} {{ pr }} {% endfor %} |
{{ p.ready }}/{{ p.total }} | {{ p.restarts or 0 }} | {% for c in p.containers or [] %} {{ c.name }} {{ c.state or '' }}{% if c.reason %} {{ c.reason }}{% endif %} {% endfor %} |
{% if p.cpu_millicores is not none %}{{ p.cpu_millicores|int }}m{% else %}—{% endif %} | {% if p.mem_bytes is not none %}{{ fmt_bytes(p.mem_bytes) }}{% else %}—{% endif %} | {{ fmt_uptime(p.age_s) }} |
| No pods match. | |||||||||