K8s View
View Kubernetes resources through views you define, refreshed live, with commands bound to the resources they
apply to. Kubeconfig, kubectl and basic actions come from the
Kubernetes extension
by Microsoft, which K8s View depends on.
Features
- One place to pick the cluster and namespace. The Context panel and the status bar share one selection; every
view and command follows it. Selecting a context here never changes
current-context in your kubeconfig. A slow
connection can be cancelled; contexts using an exec auth plugin (aws, kubelogin, gke-gcloud-auth-plugin…)
sign in through an interactive terminal, so device codes and password prompts work; Reconnect (⟳) signs in
again whenever you need to enter a passkey or password.
- One view at a time. The sidebar shows a single view; Switch view (title bar) lists every view, and only the
shown one is watched. The same picker creates a custom view, opens a view's JSON to design it, or hides views you
do not use (
k8sView.views.hidden).
- Built-in views — Workload, CronJob (job pods as grey/green/red dots), Config, Service (running port-forwards,
Ingress, HTTPRoute with Open in browser), ServiceAccount (with the RoleBindings / ClusterRoleBindings that grant
it permissions), Gateway API (Gateways, routes, Envoy Gateway / BackendTLS policies, GatewayClasses,
ReferenceGrants), Scaling (HPA, VPA, KEDA, PodDisruptionBudgets), Node (Cordon, Uncordon, Drain… with
timeout/DaemonSet/emptyDir options), Volume (PVCs, PVs, StorageClasses, VolumeSnapshots, VolumeAttachments),
Event (namespace and cluster-wide), CRDs (storage/served/deprecated/stored versions per CRD, List instances;
APIServices) and Single resource kind (list any kind the cluster serves, e.g. a CRD).
- Views as data. Built-in views are JSON files using the same schema as yours. Add a view, override one with
"extends", or hide it with "enabled": false.
- Presets for FluxCD and cert-manager, switched on automatically when their CRDs exist. HelmReleases offer
Show values and Show default values, read from Helm's release storage (no
helm CLI needed).
- Commands bound to resources. Right-click → Commands… lists what applies to that kind: logs, exec, port-forward,
rollout restart,
flux reconcile, cmctl renew, or anything you declare.
- Colored logs of a pod, a container or a whole Deployment/StatefulSet/DaemonSet/Job in one terminal: one color
per
pod/container, highlighted log levels, new pods picked up automatically.
- Decrypt secret opens every key of a Secret decoded, in a read-only document that is never saved.
- Snippets in their own sidebar section: commands for the selected context/namespace with parameters
(
${input:app}, pick a Deployment name…), created with a wizard. Built in: events, Find pods by label /
annotation…, Containers & images in use — all following the selected namespace or All namespaces.
- Live. Data comes from watches (one per kind, shared by every view, opened only while visible), falling back to
polling when watching is not allowed.
- Resource table in the editor: sort, filter, group, hide/reorder/resize columns and save the layout back to JSON,
multi-select to run a command on many resources, details drawer with YAML, events, conditions and related objects.
Configuration files
| Source |
Location |
Notes |
| Built-in |
inside the extension |
always on |
| Preset |
inside the extension |
k8sView.presets.enabled / k8sView.presets.autoEnable |
| Remote |
k8sView.remoteConfigs (https URL, e.g. a GitHub gist) |
commands blocked unless listed in allowCommands |
| User |
k8sView.configFiles (default ~/.config/k8s-view/*.json) |
every workspace |
| Workspace |
.vscode/k8s-view/*.json |
commands only run in trusted workspaces |
Later sources win when ids collide. Files are JSON with comments; IntelliSense and validation are provided for any
k8s-view/*.json file.
{
"version": 1,
"views": [
{
"id": "team",
"title": "Team",
"sections": [
{
"id": "deployments",
"title": "Deployments",
"resources": [{ "group": "apps", "kind": "Deployment" }],
"filter": { "path": "$.metadata.labels.team", "op": "eq", "value": "payments" },
"status": { "preset": "replicas" },
"columns": [
{ "title": "Ready", "template": "${$.status.readyReplicas|default:0}/${$.spec.replicas}" },
{ "title": "Age", "path": "$.metadata.creationTimestamp", "render": "age" }
],
"children": [{ "relation": { "type": "ownerRef", "group": "apps", "kind": "ReplicaSet" } }]
}
]
}
],
"commands": [
{
"id": "team.restart",
"title": "Restart",
"match": [{ "group": "apps", "kind": "Deployment" }],
"run": { "type": "process", "command": "kubectl", "args": ["rollout", "restart", "deployment/${name}", "-n", "${namespace}", "--context", "${context}"] },
"dangerous": true,
"refreshAfter": true
}
]
}
Templates
${…} works in columns, descriptions and commands: variables (${name}, ${namespace}, ${kind}, ${kindLower},
${group}, ${apiVersion}, ${plural}, ${uid}, ${label:<key>}, ${annotation:<key>}; in commands also
${context}, ${cluster}, ${kubeconfig}, ${timestamp}, ${workspaceFolder}, ${input:<id>}) or JSONPath
(${$.status.phase}). Modifiers: |lower, |upper, |trunc:N, |default:text, |count, |sum.
Relations
type |
Finds |
ownerRef |
children whose ownerReferences point to the parent (Deployment → ReplicaSet → Pod) |
labelSelector |
children matched by the parent's selector (Service → Pods) |
fieldRef |
objects referenced by the parent (Kustomization → source, HTTPRoute → Services) |
reverseFieldRef |
objects that reference the parent (RoleBinding → ServiceAccount) |
field |
items inside the object (containers, ConfigMap keys) |
Safety
- Commands run without a shell (
process, terminal), so names, labels and JSONPath values cannot inject
commands. The kubectl type quotes each argument.
- Commands marked
"dangerous": true (delete, scale, rollout restart, suspend…) are disabled until you set
k8sView.commands.dangerous to confirm or allow (user setting only).
- Contexts matching
k8sView.context.protected show a red status bar and always ask before running a command.
- Workspace commands need a trusted workspace and a one-time Allow; changing their definition asks again.
- Remote config commands (
k8sView.remoteConfigs) are blocked unless they match the source's allowCommands
patterns, which must name the subcommand (kubectl get **, never kubectl **). They also need a one-time Allow
and can never use cwd, env, connection flags (--server, --kubeconfig, --token, --as…) or another
--context. See docs/remote-config.md.
- Secret values never reach the views, the output channel or command templates; Reveal / Copy decoded value
fetch them on demand.
Settings
| Setting |
Default |
Description |
k8sView.context.followKubernetesExtension |
false |
Follow the context/namespace of the Kubernetes extension (⚙ in the Context panel opens these settings) |
k8sView.context.protected |
[] |
Regexes of sensitive contexts |
k8sView.context.connectTimeoutSeconds |
5 |
Timeout of the connection check |
k8sView.configFiles |
["~/.config/k8s-view/*.json"] |
User config files |
k8sView.remoteConfigs |
[] |
Config files from https URLs (url, allowCommands, optional sha256); user setting only |
k8sView.presets.enabled / autoEnable |
[] / true |
Presets |
k8sView.views.hidden |
[] |
Ids of views hidden from Switch view (never watched) |
k8sView.extraPath |
[] |
Extra PATH for commands and exec auth plugins |
k8sView.refresh.mode |
watch |
watch, poll or manual |
k8sView.refresh.pollIntervalSeconds |
10 |
Polling interval, at least 3 s (the Context panel offers Pause, Live, 3, 5 and 10 s) |
k8sView.refresh.debounceMs |
250 |
Batch changes before redrawing |
k8sView.refresh.maxWatches |
20 |
Concurrent watches before falling back to polling |
k8sView.refresh.pauseWhenUnfocused |
false |
Pause while the window is unfocused |
k8sView.commands.dangerous |
restricted |
restricted, confirm or allow |
k8sView.logs.tailLines |
200 |
Recent lines shown when logs open |
k8sView.logs.timestamps |
false |
Timestamp on every log line |
k8sView.logs.highlight |
true |
Color log levels |
Documentation
Detailed guides (Vietnamese) live in docs/: usage, building custom views, commands & snippets,
and guidelines.
Development
This package lives in the vscode-extension pnpm workspace.
pnpm install
pnpm --filter k8s-view build # schema + extension bundle + webviews
pnpm --filter k8s-view test # unit tests (Vitest)
pnpm --filter k8s-view typecheck
pnpm --filter k8s-view test:integration # VS Code + a kind cluster (see .github/workflows/ci.yml)
Press F5 in the repository root to launch an Extension Development Host.
| |