Skip to content

Kubernetes Enterprise Plugin

The Kubernetes plugin registers one cluster as one Konduo resource and provides read-only operational inventory by default. It includes Overview, Nodes, Workloads, Network, Configuration References, Storage, Availability Policies, Warning Events, Diagnostics, Permissions, and Topology views plus equivalent read-only MCP resources/tools. Controlled resource changes are available only as an explicit opt-in and are never exposed through MCP.

This manual is intended for operators who need to connect a cluster, verify effective access, inspect operational state, and perform a small set of guarded changes without switching to another Kubernetes dashboard.

Five-minute quick start

  1. Choose in_cluster when Konduo runs in the observed cluster. Otherwise, paste a flattened, least-privileged kubeconfig that contains embedded credentials and CA data.
  2. Apply an observer RBAC sample from deploy/rbac/. Replace the sample namespace and ServiceAccount subject before applying it.
  3. Add a Kubernetes resource in Konduo, select the intended cluster or namespace scope, and keep operation_mode=read_only for the first check.
  4. Run the connection test, then open Operations > Permissions. A successful connection proves API reachability, not permission for every inventory.
  5. Open Operations > Overview, confirm the inventory scope, and link a Prometheus-compatible metric target if Monitor will be used.
  6. Enable controlled_write only when changes are required. Grant only the matching operator, creator, updater, or deleter sample for each namespace.

Choose a connection mode

Konduo runs inside the observed cluster

Use connection_mode=in_cluster. This is the recommended and simplest option. The plugin uses the Pod's projected ServiceAccount token, CA, and Kubernetes API endpoint. Kubernetes rotates projected tokens and client-go reads the token file for subsequent requests. Apply either the namespace or cluster observer sample from deploy/rbac/ to the Konduo ServiceAccount.

Konduo runs outside the observed cluster

Use connection_mode=kubeconfig and paste a purpose-built kubeconfig. You may copy YAML from ~/.kube/config, but first reduce it to the intended cluster, context, and least-privileged identity. The selected user must contain exactly one of:

  • an embedded bearer token; or
  • embedded client-certificate-data and client-key-data.

Use embedded certificate-authority-data for a private cluster CA. Set context_name only when it should differ from current-context.

Many managed-cluster kubeconfigs use an exec command to refresh credentials. The plugin deliberately rejects those files because it never runs local programs. A pasted short-lived token stops working when it expires; use in-cluster mode where possible or provision a separately governed observer credential with an explicit rotation process.

Bootstrap endpoint and automatic failover

The API server in kubeconfig or in-cluster configuration is a bootstrap seed, not a permanently fixed target. After the first successful connection, the plugin joins all EndpointSlices for the built-in default/kubernetes Service, discovers the identifiable API servers, and probes each address. The Monitor endpoint area lists the original seed and discovered control-plane API addresses. When EndpointSlices contain no address and Node inventory is available, control-plane Node addresses provide a partial fallback list.

Konduo persists the endpoint list and health state in resource metadata. On a later call, an unavailable bootstrap causes the plugin to test the previously healthy addresses and select the first reachable one. Before accepting a fallback, it compares the built-in default/kubernetes Service UID with the stored cluster identity so an injected address cannot redirect operations to a different cluster. Reads, diagnostics, managed metrics, and controlled operations all use the selected address. Failed writes are not replayed on a second server; endpoint selection happens before a write is sent.

Selected-namespace observers must also apply the default-namespace endpoint observer Role and RoleBinding included in namespace-observer.yaml. Without that grant the bootstrap can still work, but complete endpoint display, same-cluster validation, and automatic failover are not guaranteed. An address that is not directly reachable from Konduo, or is not covered by the cluster's API certificate, is shown as unhealthy and excluded from healthy failover candidates.

Configuration reference

Connection and scope

SettingDefaultPurpose and guidance
connection_modekubeconfigUse in_cluster for the projected ServiceAccount identity or kubeconfig for pasted credentials.
kubeconfigemptyRequired in kubeconfig mode. Paste flattened YAML with embedded token or client certificate/key and CA data.
context_nameemptyOverrides current-context only when a different context must be selected.
scope_modeclusterUse selected_namespaces to constrain all namespaced inventory and operations.
namespacesemptyComma- or newline-separated namespaces required by selected-namespace scope.
operation_moderead_onlycontrolled_write exposes guarded action routes but does not grant Kubernetes RBAC.
timeout_seconds10Kubernetes request timeout from 1 to 30 seconds.
allow_insecure_tlsfalseLab-only TLS verification bypass. Do not enable it in production.

Metrics

SettingDefaultPurpose and guidance
metrics_enabledtrueEnables Monitor integration for the resource.
metric_collection_modeexternalexternal queries an existing metric source; managed collects bounded Kubernetes API and optional supervisor metrics.
metric_cluster_label_keyemptyCluster discriminator used only when an external metric source contains multiple clusters.
metric_cluster_label_valueemptyValue paired with the external cluster label key.
metric_collection_interval_seconds60Managed collection interval from 30 to 3600 seconds.
metric_collection_timeout_ms10000Managed collection timeout from 1000 to 30000 milliseconds.
collect_resource_metricstrueReads Pod and, in cluster scope, Node usage from metrics.k8s.io.
collect_supervisor_metricstrueReads the bounded K3s/RKE2 supervisor and API-server metric families from /metrics.

Managed collection still needs a selected Prometheus-compatible metric target; the plugin collects and writes samples while Konduo's shared metric subsystem stores and queries them.

Security boundary

Kubeconfig is limited to 256 KiB and bounded cluster/user/context entries. The plugin rejects external file references, exec, auth-provider, basic auth, impersonation, proxy URLs, extensions, HTTP servers, and insecure TLS unless the explicit lab-only override is enabled. Never enable allow_insecure_tls in production.

The plugin does not request Secret content. Its admin-only ConfigMap read returns only bounded and redacted values. Pod logs are available only as a bounded, admin-only read of one explicitly selected container. Pod terminal exec is a separate guarded, admin-only interactive session for one running container and the fixed /bin/sh entry shell. Neither surface is exposed to MCP, diagnostics, or background collection. The plugin does not expose generic apply, arbitrary exec commands, Kubernetes APIs/patches, or resource selectors. Warning events are count-bounded and sanitized before they leave the plugin.

Scope and permissions

  • scope_mode=cluster observes all readable namespaces and nodes.
  • scope_mode=selected_namespaces requires a comma/newline-separated namespaces list and keeps namespaced inventory within that list.
  • operation_mode=read_only is the default. controlled_write only enables the guarded UI/action routes; it never grants Kubernetes permission.
  • timeout_seconds accepts 1–30 seconds.

The Permissions view uses SelfSubjectAccessReview to explain effective access. Missing inventory permission produces limited or partial evidence; it does not mark a reachable API server as down. SelfSubjectReview identity evidence is optional because some clusters do not grant it.

The observer samples intentionally contain no wildcard resources or verbs and no access to Secrets, Pod logs, exec, or mutation APIs. They grant only explicit read access to ConfigMaps and ServiceAccounts. Adapt the namespace sample for each observed namespace. Add cluster-log-reader.yaml or a namespace-log-reader.yaml per allowed Namespace only when logs are required. Optional cluster-operator.yaml and namespace-operator.yaml grants are separate and contain only the patch/create verbs used by controlled actions and the exact create verb on pods/exec used by Pod terminal sessions.

Managed supervisor metrics need one additional cluster-scoped permission: get on the non-resource URL /metrics. The cluster observer sample includes it. The namespace observer sample keeps namespaced inventory in Roles and adds a separate ClusterRole/ClusterRoleBinding for /metrics, because a Role cannot grant a non-resource URL. The Permissions view reports this grant separately.

Managed Metrics API collection also needs get and list on metrics.k8s.io nodes and pods. The cluster observer sample includes both; the namespace observer grants only Pod metrics in each observed namespace.

The resource inventory tabs require the additional named read grants in the updated observer examples: Service, EndpointSlice, Ingress, PVC, PDB, and HPA for a namespace observer, plus ConfigMap and ServiceAccount reads and PV and StorageClass for a cluster observer. The examples intentionally do not grant Secret API access.

Choosing an RBAC sample

GoalSample to start with
Observe every permitted namespace and Nodescluster-observer.yaml
Observe selected namespaces onlynamespace-observer.yaml per namespace
Read Pod logs across the clustercluster-log-reader.yaml
Read Pod logs in selected namespacesnamespace-log-reader.yaml per namespace
Open Pod terminalscluster-operator.yaml or namespace-operator.yaml
Rollout restart, scale, suspend/resume, or trigger a CronJobcluster-operator.yaml or namespace-operator.yaml
Create a resourceMatching namespace-*-creator.yaml
Edit a resourceMatching namespace-*-updater.yaml
Delete a resourceMatching namespace-*-deleter.yaml

The sample bindings target ServiceAccount konduo-kubernetes-observer in namespace konduo. Change both fields when the deployed Konduo identity is different. Do not combine every write sample by default; add only the resource families and namespaces an operator is expected to change.

Using each workspace

  • Monitoring presents time-series dashboards backed by the linked metric target. Use it for trends, utilization, and alert-oriented signals.
  • Diagnostics collects a bounded diagnostic snapshot on first entry and separates Summary, Nodes, Scheduling, Workloads, Containers, Capacity, Control Plane, History, and Deep Analysis.
  • Operations is the current Kubernetes API workspace. Start with Overview, then inspect Workloads, Network, Configuration, Storage, Availability Policies, Nodes, Warning Events, Topology, and effective Permissions.

The Operations pages intentionally show compact freshness state next to the refresh control instead of dedicating a large summary panel to cache metadata. Use manual refresh after an out-of-band kubectl change; successful Konduo create, edit, action, and delete flows invalidate the related inventory and track convergence before returning to the list.

Viewing Pod logs

Open Logs on a Pod row in Workloads. The contextual viewer shows a compact Pod summary, selects the first regular container automatically, and provides one selector for choosing another regular, init, or ephemeral container. It reads the last 50, 100, 200, or 500 lines within a 15-minute, 1-hour, 6-hour, or 24-hour lookback. The viewer also supports the previous container instance and a case-insensitive result filter. Responses are capped at 128 KiB and each message at 16 KiB. It intentionally provides no follow stream, download, or multi-Pod aggregation. Interactive access is a separate Pod-row action with a stronger permission boundary.

Because application logs may contain secrets, the ordinary observer grant does not include them. The user needs Konduo administrator access with kubernetes-plugin.pod-logs.read, while the Kubernetes identity needs get on pods/log in the target Namespace. Operations > Permissions reports that subresource separately.

Opening a Pod terminal

Open Terminal on a Pod row in Workloads. The contextual page summarizes the selected Pod, chooses its first running regular container, and lets an operator switch to another regular or ephemeral container. The entry shell is fixed to /bin/sh; shell selection, arbitrary command text, and arbitrary Kubernetes API paths are not accepted. Switch shells after connecting when another shell is installed. An image without /bin/sh cannot use the terminal; use Pod logs or an image that includes a shell.

The action appears only in controlled_write mode for a Konduo administrator with kubernetes-plugin.pod-terminal.open. The Kubernetes identity also needs create on pods/exec in the target Namespace, provided by the matching operator sample. The Pod-row action is available only while the Pod is Running and its regular containers are Ready. Immediately before opening the stream the plugin re-fetches the Pod, verifies its UID, the selected container state, /bin/sh, and SelfSubjectAccessReview. Refresh the Workloads page when a Pod was replaced.

The session uses Konduo's common browser-terminal ticket and WebSocket policy, including origin checks, input bounds, idle timeout, maximum lifetime, and audit events. It uses the healthy API endpoint selected by failover. Sessions are user-private, non-shareable, not persisted, and excluded from MCP and diagnostics. Closing the session closes the Kubernetes exec stream.

Resource inventories and relationships

  • Network reads typed Service, EndpointSlice, and Ingress summaries. It reports selector/port policy and endpoint readiness but omits endpoint addresses. A Service with no matching EndpointSlice, no Ready endpoint, a pending LoadBalancer, or an invalid empty ExternalName remains distinguishable.
  • Configuration lists ConfigMaps and ServiceAccounts as well as ConfigMap, Secret, ServiceAccount, and image-pull-Secret references. Direct ConfigMap and ServiceAccount reads require the admin-only kubernetes.resources.configuration_content.read capability and matching Kubernetes RBAC. ConfigMap text values are bounded and credential-like keys or inline credential patterns are redacted; binary values expose key and size only. Secret values and ServiceAccount token values are never requested. Detail sheets render ConfigMap keys as copyable documents, repeated objects such as ports and conditions as wrapping cards, primitive references as compact badges, and omit empty optional sections.
  • MCP and Topology continue to use the separate reference-only route protected by kubernetes.resources.sensitive_references.read. That path derives only allowlisted Pod-template references and does not call the ConfigMap or Secret API.
  • Storage shows bounded PVC summaries and, in cluster scope when permitted, PV and StorageClass summaries. StorageClass parameters, CSI handles, and raw node affinity are omitted.
  • Availability Policies shows PDB health and HPA targets/replica bounds with allowlisted condition and metric-type summaries.

All four routes validate namespace/kind/name filters, apply the configured scope, sort by namespace/kind/name, and enforce a 300-row and 320-KiB inventory payload budget below the global 512-KiB response limit. partial, truncated, errors, pagination, and the compact collection-status indicator distinguish an empty result from missing permission, a later-page failure, or a reached bound. Results are cached for 30 seconds.

Topology connects Service to EndpointSlice and selected Pod, EndpointSlice to Pod/Node, Ingress to Service, workload to ConfigMap/ServiceAccount references, Pod to PVC, PVC to PV, PV to StorageClass, PDB to selected Pods, and HPA to its scale target. It does not embed the source inventory object or any manifest. Secret and image-pull-Secret names are deliberately excluded from the general Topology route because that route does not carry the sensitive-reference capability.

Using the relationship graph

The Topology page renders the bounded object and relationship snapshot as an interactive graph. It starts at one relationship level; switch to two levels when more context is needed. At most 13 nodes are rendered at once so a dense cluster does not shrink every object into unreadable labels.

  • Select a node to make it the focus and expand its nearby parents and children.
  • Use Back for focus history, Reset focus for the initial object, and Reset layout to compact excessive spacing after manual dragging.
  • Drag nodes freely and use zoom or pan for local inspection.
  • Right-click a node to view its properties or edit it when that typed resource supports guarded editing and the current user has the required capability.
  • Use incoming and outgoing relationship chips below the graph to move focus without searching the canvas.

If the properties action reports that an object no longer exists, refresh the graph. Kubernetes object replacement changes the UID, and the stale graph node must not be resolved as the new object merely because its name is unchanged.

Operational interpretation

  • A healthy connection means Kubernetes discovery succeeded. limited means the identity needs additional read permission only if the missing view is required.
  • Node target fingerprints use immutable metadata.uid, so renamed/replaced nodes are not conflated.
  • Workload and topology results are bounded. truncated=true means the current MVP collection limit was reached; it is not cluster data loss. One request reads at most three Kubernetes list pages, 500 objects, and 4 MiB per resource, while the plugin response is capped at 512 KiB. A later-page failure retains already collected rows and returns partial=true with limitation evidence.
  • Overview, Event, Diagnostics, and Topology snapshots are reused for 30 seconds; Node and Workload snapshots for 60 seconds; and Permission snapshots for five minutes. Concurrent identical requests collapse into one Kubernetes API load. Inspect snapshot.observed_at, age_seconds, stale, and cache_hit to distinguish fresh observations from reuse. Credential or connection changes produce a new protected fingerprint and do not reuse the previous cache entry.
  • The Overview workload total counts inventory rows across Pods and supported controllers (Deployment, StatefulSet, DaemonSet, Job, and CronJob). It is not a Pod-only count. Check partial and truncated before treating zero as complete evidence.
  • Node and workload rows separate Konduo health_status (healthy, warning, critical, or unknown) from Kubernetes native_status. Use the namespace, kind, health, name, and problems-only controls to narrow the bounded snapshot.
  • Selecting a row opens a detail sheet with allowlisted conditions, replica counts, owner identity, container state, images, and related Event lookup context. Environment variables, Secret contents, credentials, and taint values are never included. Mutation entry points remain on the inventory row so the detail sheet stays focused on inspection.
  • A namespace filter must remain inside the instance's configured namespace scope. partial, evidence_available, and truncated describe unavailable evidence separately from a genuine empty result.
  • Warning Events are a bounded, current Kubernetes API view, not durable incident history. The 15-minute, 1-hour, and 6-hour lookbacks only filter what the API still retains; they do not guarantee that the full requested interval exists.
  • Event summaries add occurrence counts by reason, object kind, and namespace. first_observed_at and last_observed_at use deterministic Kubernetes timestamp fallbacks. When truncated=true, use pagination.next_cursor with an exact namespace where required. A missing Event must never be read as proof that no historical incident occurred. The cursor is an opaque Kubernetes continuation token: never write it to logs or error messages. The plugin bounds and validates it and only forwards it to the Event list request.
  • Diagnostics are stable, structured findings rather than server-authored English sentences. Each finding carries a stable key, severity and status code, localized message/action keys, bounded structured evidence, affected object identities, related Event IDs, and explicit evidence availability.
  • Initial snapshot correlation connects unhealthy Nodes to scheduled Pods, unhealthy controllers to selector-matching Pods, and those objects to recent Warning Events. Pending Pods with FailedScheduling Events, CrashLoop/image-pull failures, OOM evidence, replica shortages, and failed Jobs receive distinct status codes. No logs, exec, environment variables, or object secrets are read.
  • The permission matrix sorts denied and unknown reviews first and identifies the affected views and diagnostics. It never creates RoleBindings or elevates access.
  • The Topology view renders a bounded, focus-based relationship graph for Node, Pod, controller, ReplicaSet, and allowlisted resource objects. Narrow the snapshot by namespace, workload, node, or health, then move through one or two relationship levels. Object IDs use Kubernetes UIDs; dense neighborhoods are capped and expanded progressively instead of rendering every Pod at once.
  • Diagnostics derive evidence from API reachability, Node Ready conditions, Pod phases/restarts, and RBAC coverage. They do not alter the cluster.

Metrics, anomaly rules, Pod-log evidence, exec, and generic remediation are not part of the diagnostic API snapshot surface. Direct bounded log viewing remains separate behind the Pod row's Open Logs action in Operations > Workloads.

Controlled resource operations

Keep operation_mode=read_only unless the resource is intentionally authorized to change workloads. For selected scope, prefer namespace-operator.yaml in only the namespaces Konduo may operate. The cluster operator example is broader and should be used only when cluster-wide operation is required.

The Workloads table exposes actions on each supported row:

  • the pencil opens the structured/YAML resource editor, including replica and CronJob schedule/suspend fields;
  • the play action performs rollout restart for Deployment, StatefulSet, and DaemonSet, or creates one Job from the selected CronJob template; and
  • the trash action opens the guarded deletion workflow.

Each workload kind has only one immediate play action, so the action dialog does not ask the operator to choose an operation that cannot vary. It re-reads the object, verifies UID and resourceVersion, runs an exact SelfSubjectAccessReview, and uses Kubernetes server-side dry-run before real execution. Konduo RBAC still applies. A successful action invalidates the inventory cache and tracks reconciliation before the list is refreshed. Controller detail includes a compact, bounded related-Pod table. Independent rollout-restart, scale, CronJob suspend, and CronJob trigger capabilities remain published for least-privilege grants. Automatic rollback is not performed.

There is no generic restart API for a Pod. The plugin therefore does not delete Pods as a restart shortcut; use the owning controller action. Immediate actions do not accept arbitrary GVRs, URLs, JSON patches, or kubectl commands. Typed resource editing is described separately below.

Structured resource creation

controlled_write exposes the following creation flows from the + button on Overview and each owning resource page:

  • Workloads: Deployment, StatefulSet, DaemonSet, Job, and CronJob
  • Network: Service and Ingress
  • Configuration: ConfigMap and ServiceAccount
  • Storage: PersistentVolumeClaim
  • Availability Policies: PodDisruptionBudget and HorizontalPodAutoscaler

Workload forms include image, bounded line-oriented container command and args lists, port, CPU/memory requests and limits, non-secret environment entries, and kind-specific replica, update strategy, Job execution, and CronJob scheduling fields. Command and argument entries round-trip to YAML arrays. Ingress references only an existing TLS Secret name and never reads its value. ServiceAccount API token automount is disabled by default.

Create actions are hidden in read-only mode. Namespace is selected from the configured observation scope. The UI offers both a structured form and YAML expert mode. YAML accepts one document of an allowlisted kind through strict typed decoding; operators still cannot choose an arbitrary API group, GVR, URL, or JSON patch. Duplicate keys, multiple documents, aliases/anchors, merge keys, custom tags, unknown fields, status, and high-risk Pod settings are rejected. Immediately before creation, the plugin runs an exact Namespace/API group/resource/create SelfSubjectAccessReview. Submission defaults to Kubernetes server-side dry-run. Actual creation requires disabling dry-run and typing CREATE. Success clears the related inventory cache before the page reloads. An existing object with the same name is reported as a failure rather than an idempotent success.

Closing and reopening the create dialog resets previous values. Dim text in the Namespace selector is a placeholder, not a selected default; choose a namespace explicitly before validation.

Apply only the required deploy/rbac/namespace-*-creator.yaml Role in each allowed Namespace. The examples contain no wildcard and do not grant Secret, PV, StorageClass, Role, or RoleBinding creation. ConfigMap input is bounded by key, value, and total size and rejects credential-like keys and inline values. Secret creation and value reads remain unsupported. PV, StorageClass, Role, and RoleBinding creation and clone remain unsupported.

Guarded structured/YAML resource updates

Deployment, StatefulSet, DaemonSet, CronJob, Service, Ingress, ConfigMap, ServiceAccount, PDB, and HPA can be edited from the pencil action on an inventory row or Edit resource on a Topology node. The detail sheet stays read-only so there is no second, inconsistent edit route. Job and PVC are outside the initial update scope.

Structured editing copies the live typed object and changes only fields owned by the form, preserving fields the form does not represent. YAML expert mode starts from a sanitized canonical live object; Secret and existing credential values are never sent to the browser.

Immediately before update, the plugin re-fetches the object, pins UID and resourceVersion, executes an exact update SelfSubjectAccessReview, and runs a typed Kubernetes server-side dry-run. Identity, immutable fields, credential-like values, and high-risk Pod-spec changes are rejected. Actual apply uses the simple confirmation APPLY. If resourceVersion changed, refresh the inventory and reopen the editor. Success invalidates the related cache and tracks workload reconciliation before refreshing the list. Grant only the matching deploy/rbac/namespace-*-updater.yaml Role. Update is not exposed through MCP.

Guarded structured deletion

Deletion is available only from the action on a selected supported inventory row in controlled_write; detail sheets remain focused on inspection and editing. Supported resources are the five workload controllers, Service, Ingress, ConfigMap, ServiceAccount, PDB, HPA, and a separately guarded PVC flow. The plugin does not offer bulk deletion, arbitrary manifests/GVRs, force deletion, finalizer removal, Namespace/Node/RBAC deletion, or deletion through MCP.

The action re-fetches the typed target and requires the selected UID and resourceVersion to still match. It then calculates bounded direct impact, executes an exact delete SelfSubjectAccessReview, and asks the Kubernetes API server to dry-run the same foreground deletion. Real execution repeats the server dry-run and requires the target resource name continuously shown beside the input. The final delete uses UID/resourceVersion preconditions. NotFound and an already terminating object are reported explicitly instead of being treated as success.

PVC deletion additionally shows phase, requested storage, StorageClass, bound PV and readable reclaim policy, and refuses a claim mounted by a visible Pod. Grant deletion with only the matching deploy/rbac/namespace-*-deleter.yaml; do not widen observer, operator, or creator Roles.

Diagnostic workflow and troubleshooting

The resource side menu separates Monitoring, Diagnostics, and Operations. Operations contains the API snapshot overview, inventories, Events, Topology, and Permissions. Diagnostic findings and explicit diagnostic actions remain in Diagnostics and do not appear among the operational inventory tabs.

The Diagnostics workspace has separate Summary, Nodes, Scheduling, Workloads, Containers, Capacity, Control Plane, History, and Deep Analysis tabs.

  1. Opening Diagnostics makes the Summary read collect the initial bounded Kubernetes API evidence. Use Refresh diagnostics in the Summary table header for an explicit refresh afterward.
  2. Review each category status, diagnostic time, evidence, and next action in the Summary table. A snapshot becomes stale after five minutes and expires after 30 minutes of inactivity. A failed refresh keeps the last successful snapshot usable.
  3. Use each category detail tab to inspect canonical findings, affected immutable UIDs, sanitized Event IDs, owner/placement context, evidence freshness, and the suggested next action. A missing source is unavailable, not a healthy zero.
  4. Use History only for delegated logical metrics. Lookbacks are bounded to 1h, 6h, 24h, 7d, 14d, or 30d; at least five samples and 50% coverage are required. transient, repeated, and sustained describe a time pattern, not certainty beyond the available evidence.

Use Deep Analysis only when the standard snapshot identifies a specific object that needs more evidence. Select an allowlisted Node, Deployment, StatefulSet, DaemonSet, Job, CronJob, or Pod. auto selects the matching built-in profile; the explicit profiles are node_impact, workload_convergence, and pod_stability. Namespace scope is enforced again when the job starts and when its result is read. UID can be supplied to reject a replaced object.

Deep jobs are process-local, asynchronous, and intentionally temporary. The store allows at most 256 jobs and 64 MiB of results, four concurrent jobs in the process, two per resource, and a 30-second hard timeout. Completed/partial jobs are retained for 45 minutes, failures for 60 minutes, cancellations for 15 minutes, and no entry survives the six-hour stale ceiling. Identical active or recent jobs are deduplicated. Restarting the plugin deletes them. Rotating the connection or credential hides old jobs so they cannot be replayed. These jobs are not the durable cross-resource reports described by Connected Diagnostics.

Troubleshooting states:

  • partial: target evidence was collected but an optional bounded source, such as Warning Events, was unavailable. Review warnings; do not treat this as full success or total failure.
  • failed: verify connectivity, current observer permission, target UID, and namespace scope, then start a new job. Failed credentials are never returned.
  • cancelled: the operator requested cancellation or the plugin shut down.
  • expired_or_inaccessible: the TTL elapsed, the plugin restarted, access was revoked, the resource scope differs, or the connection fingerprint changed. No old job metadata is disclosed in this state.
  • Backpressure: wait for another job on the resource to finish. Raising an API client QPS setting does not increase the fixed analysis concurrency budget.

Deep Analysis never reads Pod logs, environment variables, Secret or ConfigMap content and never uses exec. It has no arbitrary GVR, URL, kubectl, PromQL, or MCP execution interface. The Event message sanitizer applies string and byte bounds and removes URL credentials, bearer tokens, API keys, and JWT-like text.

Metrics and Monitor

Enable metrics and choose one of two collection modes. Both modes require a Prometheus-compatible metric target through generic resource metric linkage:

  • external reads metrics already present in that source. A single-cluster source needs no additional selector. For a multi-cluster source, review the discovery result and set metric_cluster_label_key and metric_cluster_label_value.
  • managed uses the existing kubeconfig or in-cluster ServiceAccount. It generates bounded kube-state-metrics-compatible snapshots from read-only Kubernetes API objects and writes them to the selected metric target. No exporter, second URL, or second credential is required. Core stamps and queries the immutable konduo_resource_instance_id isolation label.

Managed collection runs every 60 seconds by default and accepts a 30–3600 second interval and 1–30 second timeout. API snapshots include Node conditions, Pod phase/restarts/waiting reason, supported workload availability, and Pod CPU and memory requests/limits. With collect_resource_metrics=true, the same Kubernetes identity also reads metrics.k8s.io. Cluster scope collects Node and Pod/container CPU and memory usage; selected-namespace scope collects usage for Pods in those namespaces. Metrics Server must be installed and the observer needs get and list on the corresponding metrics.k8s.io nodes and pods resources. Object and sample caps remain enforced; partial or truncated reads are recorded as collection failures rather than healthy zeroes.

With collect_supervisor_metrics=true, the collector requests HTTPS /metrics from the same API server using the same transport and credential. For K3s, start each server with --supervisor-metrics; the endpoint is exposed on the supervisor/API port (normally 6443). Only the documented K3s/RKE2 cluster-management families and required API server families are accepted. API server series are aggregated to the code, verb, histogram bucket, and request-kind dimensions used by the mapping pack, avoiding unbounded group/version/resource cardinality. Redirects, arbitrary endpoints, and unbounded response bodies are rejected. If /metrics is disabled or forbidden, the API snapshot is retained and the run is reported as partial. Disable this option on a cluster that does not expose the K3s/RKE2 supervisor endpoint.

Managed mode does not proxy kubelet endpoints. It periodically writes current Metrics API usage gauges to the configured metric target, enabling Node CPU/memory and container CPU/memory queries. These values use separate konduo_kubernetes_*_usage_* names and managed queries because they are not cAdvisor cumulative counters. Throttling and OOM still require external kubelet/cAdvisor series. Root filesystem utilization requires node-exporter node_filesystem_* series and is not attributed to kubelet/cAdvisor.

Core owns shared metric_label_filters; the plugin never accepts arbitrary PromQL.

Monitor rows cover Cluster Health, Nodes, Workloads, Capacity, optional Control Plane, and optional K3s/RKE2 Supervisor signals. Cluster Health distinguishes managed collection freshness, Ready Node ratio, unavailable workloads, and Pending versus Failed Pods. Nodes include normalized CPU/memory utilization and Memory/Disk/PID pressure. Workloads include bounded CPU, memory, restart, and throttling Top 10 views plus CrashLoopBackOff, OOM, and failed Job evidence. Capacity compares CPU and memory requests, limits, and request-to-allocatable ratios. Control Plane adds API server errors, P99 latency, and inflight requests; Supervisor adds minimum certificate lifetime and unhealthy embedded load balancer backends when the corresponding K3s/RKE2 families exist.

Every panel declares whether it requires managed collection, kube-state-metrics, metrics.k8s.io, kubelet/cAdvisor, node-exporter, API server, or supervisor metrics. unavailable, invalid_config, multiple_cluster_label_values, requires_managed_collection, and mapping_requires_metric_validation are not observed zeroes. Never treat an empty series as healthy zero until metric existence and cluster label isolation have been validated.

Metric and anomaly contracts stay in the EE overlay; CE receives no Kubernetes-specific queries or panels.

Metric anomalies and impact correlation

The initial Enterprise rule pack covers sustained Node NotReady and pressure, unavailable workload replicas, Pending Pods, restart surges, CrashLoopBackOff, OOM evidence, CPU throttling, Node filesystem pressure, Job failures, and optional API server error and latency signals. Every rule declares its logical metric, threshold, evaluation window, and for duration so that a transient spike is distinct from a sustained failure. Core owns rule overrides and reset, and every change requires an audit record.

A missing, stale, or failed metric query is reported as evidence_unavailable; it is never interpreted as a healthy zero or as an anomaly. Warning Events are short-lived supplemental evidence, not a standalone trigger. Impact lookup connects the metric target to bounded Node, Pod, ReplicaSet, parent Workload, structured diagnostic, and Event identifiers. Symptoms derived from the same root Kubernetes UID share a rule-independent SHA-256 fingerprint. Both affected objects and correlation groups are capped at 20. The plugin performs no automatic remediation, arbitrary PromQL, background log collection, scale, rollout, cordon, or drain operation.

Troubleshooting checklist

Symptom or stateWhat to check
Connection test failsVerify kubeconfig server, embedded CA data, selected context, and token or certificate expiry. Replace kubeconfigs that use exec, external files, or HTTP servers.
Connection is healthy but a view is limited or partialOpen Operations > Permissions, find denied get/list reviews and affected views, and add only the required observer rule.
Configuration is empty or ConfigMap content is missingVerify Konduo administrator access, kubernetes.resources.configuration_content.read, and Kubernetes read access to ConfigMaps and ServiceAccounts. Secret values remain hidden by design.
Pod logs cannot be openedVerify Konduo administrator access, kubernetes-plugin.pod-logs.read, get on pods/log in the target Namespace, and that the Pod/container still exists. Previous logs are available only while retained by the container runtime.
Pod terminal cannot be openedVerify operation_mode=controlled_write, Konduo administrator access with kubernetes-plugin.pod-terminal.open, create on pods/exec, Running/Ready state, and /bin/sh in the image. Refresh after a Pod replacement or endpoint change.
Diagnostics remains unavailableWait for the initial collection or use Refresh diagnostics. If it persists, check connection and Node, Pod, and Event read permission plus collection warnings.
Managed metrics is partially failingCheck Metrics Server and metrics.k8s.io RBAC. Set collect_supervisor_metrics=false when the cluster does not expose K3s/RKE2 /metrics.
Node CPU or memory is absentConfirm collect_resource_metrics=true, Metrics Server installation, and Node/Pod metric permission for cluster scope or Pod metric permission for each selected namespace. /metrics alone does not provide Node usage.
An action button is missingCheck operation_mode=controlled_write, the Konduo action capability, supported resource kind, and matching creator/updater/operator/deleter Kubernetes RBAC. Some combinations, such as Pod or Job update, are intentionally unsupported.
K8S_OPERATION_TARGET_STALE or an update conflictAnother change advanced resourceVersion. Refresh the list and reopen the row action against the current object.
Dry-run succeeds but execution failsCheck whether the object changed after validation, the confirmation text, and the exact verb permission. Real execution repeats target lookup and server dry-run.
Delete target cannot be foundAnother tool may already have deleted it or the filtered inventory may be cached. Refresh and check whether a new object has a different UID.
The list still shows old state after successWait for operation convergence tracking. For an unsupported tracking case or an out-of-band change, use Refresh to bypass the cached snapshot.
Topology properties cannot be openedRefresh Topology and verify current namespace/status filters and read permission. A node with a replaced UID is never silently resolved as the new object.

Never paste kubeconfig, token, certificate, or Secret values into an error report. Provide only plugin and Kubernetes versions, distribution, connection mode, scope, error code and time, and denied entries from the Permissions view.

Compatibility validation

The plugin pins client-go v0.36.3 and only uses stable APIs shared by the declared Kubernetes 1.34.x–1.36.x support window. Release CI should run TestKubernetesLiveReadOnlyContract against 1.36.x and 1.34.x clusters with a flattened observer kubeconfig. A skipped local live test is not evidence that a version has passed release certification.