Kubernetes

Pods, Workloads, Config, RBAC, CRDs, Nodes, Clusters, and Network views for your Kubernetes clusters, plus the Read-Write Cluster IDE (Enterprise).

KubeWatch surfaces Kubernetes data across dedicated pages in the sidebar rather than one combined view: Pods, Workloads, Config, RBAC, CRDs, Nodes, Clusters, and Network. On the Enterprise plan, several of these pages also let you act on the cluster directly (an interactive terminal, port forward, workload edits, arbitrary manifest apply, and full Helm release management), what we call the Read-Write Cluster IDE.

Pods

The Pods page lists pods grouped by namespace. Use the Namespace selector in the top right to view one namespace at a time (or All namespaces) so large clusters aren't shown on a single screen. Columns:

  • Name
  • Phase: Running, Pending, Failed, or Succeeded
  • Node: the node the pod is scheduled on
  • Restarts
  • Age: how long the pod has been running

Click a row to open that pod's own detail page, with three tabs:

  • Overview: phase, IP, node (linked to that node's own detail page), QoS class, which workload controls it, labels and annotations, a conditions table, a card per container (image, linked to its own image details; ready state; restart count; current state and reason; volume mounts, each with a Browse action), and this pod's own Events.
  • Logs: live tail and full historical search, both scoped to this one pod (and, for multi-container pods, whichever container you pick). See Logs for what each mode offers.
  • Exec (Enterprise): see below.

Terminal (Enterprise)

The Exec tab opens a real interactive shell inside a running container, no kubectl required. Pick a container (for multi-container pods) and a terminal opens directly in the dashboard.

Unlike the rest of the data on this page, an interactive terminal is a genuine write-adjacent capability, not read-only monitoring, so it's gated by two independent checks:

  • Plan: available on the Enterprise plan. On Free or Pro, the Exec tab shows an upgrade prompt instead of a terminal.
  • RBAC opt-in: your cluster operator must explicitly enable it when installing the agent (--set rbac.allowExec=true, off by default, see Kubernetes Agent). Without it, the agent has no permission to open a shell into any pod, even if your plan allows it.

Every session is logged (who, when, which pod/container, how long) for audit purposes.

Port forward (Enterprise)

Next to the container selector, a Port forward button opens a text field for a port number. Enter the port your pod's container is listening on and hit Open: KubeWatch proxies the HTTP request through the server and agent and opens it in a new browser tab, no local kubectl port-forward needed. Useful for reaching a pod's own debug UI, metrics endpoint, or admin panel directly.

This only works for HTTP(S) services on that port, not arbitrary TCP protocols (a database's native wire protocol, for example): it's a browser-native proxy, not a raw TCP tunnel to your machine.

Each request opens its own short-lived tunnel rather than a persistent connection, so a page with many resources (images, scripts, stylesheets) will feel a bit slower to load than visiting the service directly, a deliberate tradeoff for a browser-based feature with no local setup.

Gated the same way as the terminal above: your plan needs port forward enabled (Enterprise), and your cluster operator must opt in separately when installing the agent (--set rbac.allowPortForward=true, off by default and independent of rbac.allowExec, see Kubernetes Agent).

Restart / Delete (Enterprise)

Both the Pods list and a pod's own detail page have Restart and Delete actions. Restart is only offered for pods managed by a Deployment, StatefulSet, or DaemonSet, since Kubernetes has no in-place pod restart, only delete-then-recreate; a bare pod with no owning controller only gets Delete.

Like every other cluster-mutating action in the Read-Write Cluster IDE, there's no fast path: requesting a restart or delete needs a second admin's approval before anything happens, tracked alongside workload edits on the Workloads page. Deleting a bare pod also captures its full current state first, so if the delete turns out to be a mistake, it can be recreated from exactly what it looked like via Roll back on that same approval.

Gated by the Enterprise plan and its own RBAC opt-in (--set rbac.allowDeletePods=true, off by default, independent of rbac.allowEditWorkloads, since that flag only ever grants updates to the owning Deployment/StatefulSet/DaemonSet, never delete on the pod itself).

Workloads

The Workloads page lists Deployments, StatefulSets, and DaemonSets across your cluster, with replica counts, container images, and age. This view is available on every plan, no RBAC opt-in needed: the agent's base ClusterRole always includes read-only access to these resources. Click a row's name to open that workload's own detail page: conditions, related pods (linked back to each pod's own detail page), labels, annotations, and its own Events.

Edit and restart (Enterprise)

Each row has an Edit button that expands into a form for changing a workload's container image or replica count, plus an Also restart pods checkbox (the equivalent of kubectl rollout restart) for triggering a rolling restart with no image or replica change required. Nothing applies immediately:

  1. You submit a request specifying the new image, replica count, restart, or any combination of the three.
  2. An admin on your team reviews and approves it from the Edit requests section further down this same page, including the admin who submitted it.
  3. Only after approval does the agent apply the change.

Every request is recorded (who requested it, who approved or denied it, what changed, and the outcome), and an applied edit can be rolled back, which itself queues a new request through the identical approval gate rather than an instant revert.

Gated by the Enterprise plan and a separate RBAC opt-in (--set rbac.allowEditWorkloads=true, off by default). This is the narrowest write capability in the Read-Write Cluster IDE: only image, replica count, and restart, never a raw manifest, so it can't touch fields like securityContext or volume mounts.

Delete a Deployment, StatefulSet, or DaemonSet (Enterprise)

Each row (and the workload's own detail page) also has a Delete action, gated the same way as Edit and Restart: submitting it needs the exact workload name typed to confirm, then any one admin on your team to approve before the agent actually deletes the object. Gated by the Enterprise plan and its own RBAC opt-in (--set rbac.allowDeleteWorkloads=true, off by default, independent of allowEditWorkloads, since that flag only ever grants update/patch, never delete).

Delete a namespace (Enterprise)

Pick a specific namespace from the filter at the top of the Workloads page to reveal a Delete namespace button. This is the single most destructive action in the dashboard: it cascades to every object inside the namespace, not just the workloads shown on this page (pods, services, secrets, configmaps, PersistentVolumeClaims, and so on), and can't be undone.

Unlike every other write action on this page, there's no admin-approval queue here: clicking Delete namespace opens a confirmation dialog, and confirming it dispatches the delete immediately. The agent still applies it asynchronously, so the Namespace delete requests section further down this same page is a read-only log of what was requested, by whom, and whether it applied, not an approval queue.

Gated by its own dedicated plan flag (separate from the one Edit/Restart/Delete workload share) and its own RBAC opt-in (--set rbac.allowDeleteNamespaces=true, off by default, and never included in the enableReadWriteClusterIDE umbrella flag even when that's turned on, precisely because of how destructive this one action is).

Config

The Config page has two tabs:

  • ConfigMaps: names, namespaces, and key names (not values). Available on every plan. A View action per row (Enterprise) fetches the ConfigMap's live full YAML, including values, on demand, gated by the same plan and RBAC opt-in as Apply Manifest (rbac.allowGenericApply). Admins additionally get an Edit option from that view, which submits through the same snapshot-then-apply pipeline as Apply Manifest, no separate approval step.
  • Secrets (Enterprise): names, types, and key names only. Values are never sent to KubeWatch, ever. Requires the Enterprise plan and a cluster operator opt-in (--set rbac.allowViewSecrets=true, off by default). If this tab shows no data even with a connected cluster, see the step-by-step setup and troubleshooting in Kubernetes Agent → Setting up Secrets, RBAC, and CRD instance viewing.

RBAC (Enterprise)

The RBAC page lists Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings across your cluster: what permissions exist, and who or what they're bound to. Viewing is gated behind the Enterprise plan and a cluster operator opt-in (--set rbac.allowViewRBAC=true, off by default), since it reveals your cluster's security posture. Setup walkthrough and troubleshooting: Kubernetes Agent → Setting up Secrets, RBAC, and CRD instance viewing.

Edit RBAC (Enterprise)

You can create, edit, and delete namespaced Roles and RoleBindings directly from this page, never a ClusterRole or ClusterRoleBinding, which stay read-only no matter what. Same request-then-approval shape as Workloads editing:

  1. You submit a create, edit, or delete request for a specific Role or RoleBinding in a specific namespace.
  2. An admin on your team reviews and approves it from this page's own pending-approvals list, including the admin who submitted it.
  3. Only after approval does the agent apply the change.

A RoleBinding may reference an existing ClusterRole as its roleRef (a normal Kubernetes pattern, e.g. binding a namespace's ServiceAccount to the built-in view ClusterRole): that never modifies the ClusterRole itself, only the binding.

Kubernetes's own RBAC rules still apply on top of this: you can't grant a Role permissions your cluster's agent ServiceAccount doesn't itself already hold. If an edit is rejected for that reason, the error explains it rather than failing silently.

Gated by the Enterprise plan and its own RBAC opt-in (--set rbac.allowEditRBAC=true, off by default, independent of rbac.allowViewRBAC and of every other Read-Write Cluster IDE flag). This is deliberately narrower than Apply Manifest and Helm Releases, both of which permanently exclude rbac.authorization.k8s.io from what they can touch. RBAC editing is the one exception, and only through this page's own request/approval gate.

CRDs

The CRDs page lists installed CustomResourceDefinitions (group, kind, scope, and status) on every plan, since a CRD's schema alone reveals nothing sensitive.

Browsing the actual instances of a CRD (the real objects, not just the schema) is different: instance content varies wildly by CRD and can be sensitive, so nothing is browsable by default. Your cluster operator opts in per CRD group they trust (--set rbac.customResourceReadGroups[0]=cert-manager.io, for example), and it also requires the Enterprise plan. A CRD's group not being in that list is the most common reason "View instances" comes back empty, see Kubernetes Agent → CRD instances for the exact setup steps.

Apply Manifest (Enterprise)

The Apply Manifest page accepts a raw, multi-document YAML manifest (one or more Kubernetes objects) and applies it to your cluster, for anything that doesn't fit a Workloads edit: creating a new resource, or updating fields a narrow edit can't reach.

This is the broadest write capability KubeWatch offers, so it goes through the most scrutiny:

  • Only a curated set of kinds is accepted (Services, ConfigMaps, Secrets, PersistentVolumeClaims, ServiceAccounts, Namespaces, Deployments, StatefulSets, DaemonSets, ReplicaSets, Jobs, CronJobs, Ingresses, NetworkPolicies, HorizontalPodAutoscalers, and PodDisruptionBudgets). RBAC objects, admission webhooks, CustomResourceDefinitions, certificate signing requests, and direct pod create/delete are permanently excluded, with no override, since each is a path to escalating privileges rather than a normal application change.
  • There's no separate admin-approval queue: submitting confirms in a dialog, then the agent snapshots each object's current state (or confirms it doesn't exist yet) and applies the manifest right away, gated only by the Enterprise plan and RBAC opt-in below.
  • The Apply requests section further down the page is a read-only log of every request: the raw manifest submitted, the per-object create-or-update classification, who requested it, and the outcome.
  • Rolling back an applied request creates a new request (deleting anything that was created, reapplying the prior content for anything that was updated), through the identical snapshot-then-apply pipeline, no approval either.

Gated by the Enterprise plan and its own RBAC opt-in (--set rbac.allowGenericApply=true, off by default, independent of rbac.allowEditWorkloads). Your cluster operator can also opt specific CustomResourceDefinitions they already trust into this allow-list (--set rbac.genericApplyExtraGroups[0].apiGroup=karpenter.sh, for example).

Helm Releases (Enterprise)

The Helm Releases page manages a chart's full lifecycle: install, upgrade, roll back, and uninstall, without a helm CLI on your machine.

Charts only ever come from a trusted repo your admins register first (name and HTTPS URL), never a free-text URL typed into a request, so a release request can't point the agent at an arbitrary or attacker-controlled source. Before anything is approvable, the chart is rendered into its full set of Kubernetes manifests so an admin can actually read what a chart would create, not just its name and version, and that rendered content is what gets approved: if it were somehow re-rendered before approval, the mismatch is rejected rather than silently approving different content.

This is the broadest capability in KubeWatch, broader than Apply Manifest: a chart can define nearly any namespaced object with none of that page's kind restrictions, since Helm applies through its own client rather than KubeWatch's manifest allow-list. Gated by the Enterprise plan and its own RBAC opt-in (--set rbac.allowHelmLifecycle=true, off by default, independent of and broader than rbac.allowGenericApply). A secondary opt-in (--set rbac.allowHelmManagesRBAC=true) additionally allows a chart to create its own namespaced Role or RoleBinding, for charts that provision their own ServiceAccount permissions. Cluster-scoped ClusterRoles and ClusterRoleBindings are never permitted, even with that flag on.

Rolling back an installed release queues an uninstall request. Rolling back an upgraded release queues a rollback to its prior revision. Both go through the same render-then-approve gate as a fresh install, no shortcut.

Nodes

The Nodes page shows a card per node with its status, roles, kubelet version, architecture, and OS. Above those, each node also gets its own Capacity allocation card breaking down Cores, Memory, Pods, and Ephemeral storage as donut charts: how much Kubernetes itself reserves for system daemons, how much scheduled workloads have requested, and what's still available.

Click a card to open that node's own detail page: the same capacity donuts, plus addresses, taints (with a note on what a taint without a matching pod toleration means), a conditions table, every pod currently scheduled on it (linked back to each pod's own detail page), labels and annotations, and this node's own Events.

Cost estimate

Each node card also shows an estimated compute cost (per day and per month), and the top of the page totals it across every node in the cluster. This works out of the box, no cloud credentials or setup required, and updates immediately as nodes scale up or down: it's computed from the node's cloud provider and instance type (read from the Kubernetes Node object itself, specifically spec.providerID and the node.kubernetes.io/instance-type label) against a built-in pricing table, not a call to your cloud bill.

It works the same way across AWS, Azure, and GCP (any managed Kubernetes whose cloud controller manager sets spec.providerID, so also self-managed clusters on these clouds, not just EKS/AKS/GKE specifically). If an instance type isn't in the pricing table, the cost is shown with an "(est.)" label, a generic estimate from typical per-vCPU/per-GB rates rather than an exact price. Nodes with no recognized cloud provider (bare metal, or a local cluster like kind/minikube) show no cost at all rather than a misleading $0.

This is a list-price estimate for at-a-glance cost awareness, not a substitute for your actual cloud invoice: it doesn't account for reservations, savings plans, or spot pricing. For real billing data pulled from your cloud account, see [Cloud Costs](/dashboard/cloud-costs).

Restart / Stop / Terminate a node (Enterprise)

A node's own detail page has Restart node, Stop node, and Terminate node buttons, only shown for nodes with a recognized cloud provider (the same spec.providerID detection the cost estimate above uses): bare-metal and local (kind/minikube) nodes never get these, since there's no cloud VM behind them to act on. These act on the underlying cloud instance directly (EC2 RebootInstances/StopInstances/TerminateInstances, GCP Compute reset/stop/delete, or Azure restart/powerOff/delete), not through the in-cluster agent: the agent has no cloud credentials and is never given account-level cloud permissions, so this dispatches from KubeWatch's own servers using whichever AWS, GCP, or Azure account you've already connected on the Cloud Costs page for that cloud. No separate cluster connection is required, and this works whether or not that same cluster also appears on the Clusters page below.

Clicking one of these buttons opens a confirmation dialog. There's no separate admin-approval step: confirming dispatches the cloud API call immediately, in the same request, gated only by the Enterprise plan and admin role. Terminate is permanent; Stop and Restart both cause a real outage on that node until it comes back (if it ever does, for Stop). The Node action requests table on the Clusters page is a read-only log of what was requested, by whom, and its outcome, not an approval queue.

Gated by the Enterprise plan, independent of every other Enterprise gate on this page (Exec, Secrets, Edit and restart, and so on).

Clusters

The Clusters page is the cluster registry, connected clusters and their summaries (node and pod counts). Unlike the rest of this page, connecting a cluster here doesn't require installing the Kubernetes Agent inside it: KubeWatch talks to the cluster's API server directly, using credentials you provide. You can connect a cluster by pasting a kubeconfig, using in-cluster credentials (when KubeWatch itself runs inside the cluster), or letting KubeWatch discover clusters directly from a connected cloud account.

A connected cluster only ever powers the read-only pod/node/service summaries on this page, it's a separate data source from the agent-reported Pods/Workloads/Nodes views above. This page also shows a Node action requests table (admin only), a read-only log of every Restart/Stop/Terminate request and its outcome (see the Nodes section above), regardless of which cloud account or cluster the target node belongs to.

Connect with a kubeconfig

This is the most common path, for any cluster (managed or self-managed, on any cloud or on-prem) you have kubectl access to already.

  1. Click Add cluster, give it a Name (and optionally a Description), and leave Connection type on its default, kubeconfig.
  2. Get a clean, single-context kubeconfig by running this against the cluster you want to connect:
    kubectl config view --raw --minify
    
    Both flags matter, not just the first one: --minify strips the output down to only your current context, so KubeWatch doesn't have to guess which context to use out of a multi-cluster kubeconfig (it connects to whatever current-context says, so run this from the right context, or add --context <name> first). --raw embeds the actual certificate/token data inline instead of file paths or exec-plugin references (e.g. aws eks get-token, gke-gcloud-auth-plugin): those plugins run on your machine, not on KubeWatch's servers, so a kubeconfig that depends on one will fail to connect here. If your cluster normally needs one of those plugins, use a service account token instead (see the RBAC step below) rather than your own user credentials.
  3. Paste the full output into the kubeconfig YAML field. KubeWatch base64-encodes it automatically before sending, there's nothing extra to do on your end.
  4. Click Add cluster. It's created immediately with status pending, then KubeWatch attempts the connection right away:
    • connected: the summary and pod/node/service data on this page start populating.
    • error: hover the status (or open the cluster) to see why, almost always an unreachable endpoint or a permissions problem, see Troubleshooting below.

Minimum permissions: KubeWatch only ever lists Pods, Nodes, and Services through this connection (nothing else, no logs, no secrets, no exec), so the identity in your kubeconfig only needs read access to those three. Rather than pasting your own personal kubeconfig (which is usually far more privileged), consider creating a dedicated read-only service account:

kubectl create serviceaccount kubewatch-readonly
kubectl create clusterrole kubewatch-readonly --verb=get,list,watch --resource=pods,nodes,services
kubectl create clusterrolebinding kubewatch-readonly --clusterrole=kubewatch-readonly --serviceaccount=default:kubewatch-readonly

Then generate a kubeconfig for that service account's token (via a long-lived Secret token, or kubectl create token kubewatch-readonly --duration=8760h on Kubernetes 1.24+) instead of using kubectl config view against your own admin credentials.

Connect in-cluster

The in-cluster connection type only works for a self-hosted install running inside the Kubernetes cluster you want to monitor (not on SaaS, and not for a self-hosted install on Docker Compose): it uses the clusters service's own pod service account, with no kubeconfig to manage at all. If you pick this option from anywhere else, connecting fails immediately with "in-cluster connection not available: service not running inside a Kubernetes pod." Grant that service account the same read-only pods/nodes/services permissions shown above.

Auto-discover EKS, GKE, and AKS clusters

If you've already connected an AWS, GCP, or Azure account on the Cloud Costs page, the Clusters page shows a Discovered clusters section listing every Kubernetes cluster KubeWatch found in that account, no separate cloud credentials needed for discovery. Each entry shows the cluster's name, region or location, and status, with a one-click Connect button.

Connecting re-derives the cluster's endpoint and CA certificate directly from your cloud account rather than trusting anything cached from the discovery scan, and mints a fresh authentication token for the connection:

  • AWS EKS: connects using a presigned IAM authenticator token (the same scheme aws eks get-token uses), refreshed automatically roughly every 10 minutes to stay ahead of its ~15-minute lifetime.
  • GCP GKE: connects using a GCP OAuth2 access token, refreshed roughly every 45 minutes to stay ahead of its 1-hour lifetime.
  • Azure AKS: connects using the cluster's static-credential kubeconfig. AKS clusters with AAD authentication and local accounts disabled are shown as Manual connect required instead of a Connect button, since that path needs the kubelogin exec plugin, which KubeWatch does not attempt to emulate. Connect those the normal way, with a kubeconfig you generate yourself.

Rescan at any time with the Rescan button. A cluster already connected shows as Connected instead of a Connect button.

Kubernetes version upgrades (Enterprise)

When a connected EKS, GKE, or AKS cluster has a newer minor version available, its card shows an Upgrade to vX.Y button (admin only). Confirming queues a real control-plane upgrade against your cloud provider: there's no admin-approval step beyond the confirmation dialog, gated only by the Enterprise plan and admin role. It runs in the background and is polled to completion since a control-plane upgrade takes several minutes, unlike the node actions above. Node pools aren't upgraded automatically and may need a separate step afterward.

Troubleshooting a cluster stuck in "error"

  • Invalid or unparseable kubeconfig: usually means something other than raw kubeconfig YAML was pasted (e.g. a file path, or output from a command other than kubectl config view --raw --minify). Re-run the exact command above and paste its full output.
  • Connection timed out / endpoint unreachable: the cluster's API server must be reachable from KubeWatch's servers. A cluster on a private network (a VPC with no public endpoint, a corporate VPN, kind/minikube on your laptop) can't be reached this way, this feature has no local tunnel or agent to bridge that gap. If the cluster is only reachable privately, monitor it with the Kubernetes Agent instead, which runs inside the cluster and pushes data out rather than being connected into.
  • 403 Forbidden / permission denied: the identity in your kubeconfig lacks get/list/watch on pods, nodes, or services. Use the service account setup under "Connect with a kubeconfig" above rather than a personal account with cluster-wide restrictions (some managed clusters' default users are scoped narrower than cluster-admin).
  • Works once, then goes stale: a kubeconfig using a cloud CLI's short-lived exec-plugin token (aws eks get-token, gke-gcloud-auth-plugin) only works at the moment you ran kubectl config view --raw, since the plugin itself doesn't run on KubeWatch's side to refresh it. Use a long-lived service account token instead, or connect via auto-discovery above, which mints and refreshes its own tokens automatically.

Control Plane

The Control Plane page shows live metrics from the API server and scheduler themselves, not your workloads: request rates by HTTP status code, request latency (p99) by verb, in-flight requests, and API Priority & Fairness concurrency. This works the same way on EKS, GKE, AKS, and self-managed clusters, since it comes from the API server's own standard /metrics endpoint (the same one any Prometheus setup scrapes), not a cloud-specific integration.

Scheduler metrics (pending pods by queue, schedule attempts by result) currently require EKS 1.28 or later, since they're fetched through EKS's own dedicated scheduler metrics API. GKE and AKS have no equivalent endpoint yet; self-managed clusters running their own visible kube-scheduler pods aren't covered by this specific collector either.

Not shown here: etcd's own metrics (such as database size), which even AWS's own EKS console can only get from CloudWatch, not a directly scrapable endpoint. If you need those, CloudWatch Container Insights or a similar cloud-provider tool is the source for them today, not KubeWatch.

Network

The Network page has two tabs: Docker Networks (containers grouped by Docker network, with subnet, gateway, and per-container IP/port detail) and Kubernetes Services (per-namespace traffic, Services with LoadBalancer health, and Ingress rules). A summary of the same data also appears as charts on the Overview page.

Click a Service or Ingress to open its own describe panel: for a Service, its full port list, selector, endpoint counts, and annotations, and for an Ingress, its ingress class, every rule, TLS hosts, and annotations. Both panels also show that resource's own Events.

Kubernetes data appears once an agent is running in the cluster with a read-only service account. Every write capability above is off by default at both the plan level and the cluster RBAC level. Workloads editing, RBAC editing, and Helm Releases additionally require a second admin's approval before anything is ever applied; Apply Manifest, Delete namespace, and node Restart/Stop/Terminate confirm client-side instead and apply immediately once confirmed. See [Kubernetes Agent](/agents/kubernetes) for the full RBAC reference.