The viewnode displays Kubernetes cluster nodes with their pods and containers.
It is very useful when you need to monitor multiple resources such as nodes, pods or containers in a dynamic environment like a CI/CD platform.
Source code: GitHub
Usage:
viewnode [flags]
viewnode [command]
Available Commands:
ctx Manage Kubernetes context
help Help about any command
ns Manage Kubernetes namespaces
version Plugin Version
Flags:
-A, --all-namespaces use all namespaces
-b, --container-tree-view format containers in tree view, otherwise inline
-h, --help help for viewnode
--kubeconfig string kubectl configuration file (default: ~/.kube/config or env: $KUBECONFIG)
-n, --namespace string namespace to use; accepts comma-separated values
-f, --node-filter string show only nodes according to filter
-p, --pod-filter string show only pods according to filter
-c, --show-containers show containers in pod
-m, --show-metrics show memory footprint of nodes, pods and containers
-t, --show-pod-start-times show start times of pods
-r, --show-requests-and-limits show requests and limits for containers' cpu and memory (requires -c flag)
--show-running-only show running pods only
-v, --verbosity string defines log level (debug, info, warn, error, fatal, panic) (default "warning")
-w, --watch int[=1] refresh every N seconds; defaults to 1 when set without a value (must be >= 1)
Use "viewnode [command] --help" for more information about a command.
Follow the instructions to install krew and then run the following command:
kubectl krew install viewnode
The plugin will be available as kubectl viewnode.
The viewnode is written in go, so just download the correct executable suitable for your platform from the releases and run it.
You can also download the source code from GitHub and compile it by running the following command:
make build
Showing nodes and pods:
$ viewnode
namespace(s): jenkins-onprem
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-341-ffkt5-2k64t (running)
│ └── docker-in-the-cloud-86-822pd-d6p3d (running)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-338-3wc8r-n1t7z (running)
│ └── docker-in-the-cloud-340-cms5r-pxxq7 (running)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── docker-in-the-cloud-337-4c4lm-q3mtp (running)
├── docker-in-the-cloud-339-4x9dq-0xd3q (running)
├── docker-in-the-cloud-342-r5khq-9cx2w (running)
└── liveness-test-4-boom (failed)
When exactly one namespace is in scope, viewnode prints that namespace once in the header and keeps pod rows flat without repeating <namespace>: before each pod name.
Showing nodes, pods and containers:
$ viewnode --show-containers
namespace(s): jenkins-onprem
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-341-ffkt5-2k64t (running) (3: default/running docker-daemon/running jnlp/running)
│ └── docker-in-the-cloud-86-822pd-d6p3d (running) (3: default/running docker-daemon/running jnlp/terminated)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-338-3wc8r-n1t7z (running) (3: default/running docker-daemon/running jnlp/running)
│ └── docker-in-the-cloud-340-cms5r-pxxq7 (running) (3: default/running docker-daemon/running jnlp/running)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── docker-in-the-cloud-337-4c4lm-q3mtp (running) (3: default/running docker-daemon/running jnlp/running)
├── docker-in-the-cloud-339-4x9dq-0xd3q (running) (3: default/running docker-daemon/running jnlp/running)
├── docker-in-the-cloud-342-r5khq-9cx2w (running) (3: default/running docker-daemon/running jnlp/running)
└── liveness-test-4-boom (failed) (3: dead-container/terminated liveness1/running liveness2/running)
Showing nodes and pods with their start times:
$ viewnode --show-pod-start-times
namespace(s): jenkins-onprem
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-341-ffkt5-2k64t (running/Thu Aug 26 09:36:04 CEST 2021)
│ └── docker-in-the-cloud-86-822pd-d6p3d (running/Thu Aug 19 09:09:20 CEST 2021)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-338-3wc8r-n1t7z (running/Thu Aug 26 09:36:02 CEST 2021)
│ └── docker-in-the-cloud-340-cms5r-pxxq7 (running/Thu Aug 26 09:36:04 CEST 2021)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── docker-in-the-cloud-337-4c4lm-q3mtp (running/Thu Aug 26 09:35:36 CEST 2021)
├── docker-in-the-cloud-339-4x9dq-0xd3q (running/Thu Aug 26 09:36:03 CEST 2021)
├── docker-in-the-cloud-342-r5khq-9cx2w (running/Thu Aug 26 09:36:05 CEST 2021)
└── liveness-test-4-boom (failed/Wed Aug 25 15:07:52 CEST 2021)
You can also combine show options:
$ viewnode --show-pod-start-times --show-containers
namespace(s): jenkins-onprem
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-341-ffkt5-2k64t (running/Thu Aug 26 09:36:04 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
│ └── docker-in-the-cloud-86-822pd-d6p3d (running/Thu Aug 19 09:09:20 CEST 2021) (3: default/running docker-daemon/running jnlp/terminated)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── docker-in-the-cloud-338-3wc8r-n1t7z (running/Thu Aug 26 09:36:02 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
│ └── docker-in-the-cloud-340-cms5r-pxxq7 (running/Thu Aug 26 09:36:04 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── docker-in-the-cloud-337-4c4lm-q3mtp (running/Thu Aug 26 09:35:36 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
├── docker-in-the-cloud-339-4x9dq-0xd3q (running/Thu Aug 26 09:36:03 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
├── docker-in-the-cloud-342-r5khq-9cx2w (running/Thu Aug 26 09:36:05 CEST 2021) (3: default/running docker-daemon/running jnlp/running)
└── liveness-test-4-boom (failed/Wed Aug 25 15:07:52 CEST 2021) (3: dead-container/terminated liveness1/running liveness2/running)
As well as filter nodes and pods:
$ viewnode --node-filter v1vr
namespace(s): jenkins-onprem
4 pod(s) in total
0 unscheduled pod(s)
1 running node(s) with 4 scheduled pod(s):
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── docker-in-the-cloud-337-4c4lm-q3mtp (running)
├── docker-in-the-cloud-339-4x9dq-0xd3q (running)
├── docker-in-the-cloud-342-r5khq-9cx2w (running)
└── liveness-test-4-boom (failed)
Showing nodes across all namespaces:
$ viewnode -A
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── default
│ │ └── docker-in-the-cloud-86-822pd-d6p3d (running)
│ └── jenkins-onprem
│ └── docker-in-the-cloud-341-ffkt5-2k64t (running)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── default
│ │ └── docker-in-the-cloud-340-cms5r-pxxq7 (running)
│ └── jenkins-onprem
│ └── docker-in-the-cloud-338-3wc8r-n1t7z (running)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── default
│ ├── docker-in-the-cloud-339-4x9dq-0xd3q (running)
│ └── liveness-test-4-boom (failed)
└── jenkins-onprem
├── docker-in-the-cloud-337-4c4lm-q3mtp (running)
└── docker-in-the-cloud-342-r5khq-9cx2w (running)
You can also aggregate pods from selected namespaces only:
$ viewnode --namespace jenkins-onprem,default
8 pod(s) in total
0 unscheduled pod(s)
3 running node(s) with 8 scheduled pod(s):
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-8fws running 2 pod(s) (linux/amd64)
│ ├── default
│ │ └── docker-in-the-cloud-86-822pd-d6p3d (running)
│ └── jenkins-onprem
│ └── docker-in-the-cloud-341-ffkt5-2k64t (running)
├── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-b0np running 2 pod(s) (linux/amd64)
│ ├── default
│ │ └── docker-in-the-cloud-340-cms5r-pxxq7 (running)
│ └── jenkins-onprem
│ └── docker-in-the-cloud-338-3wc8r-n1t7z (running)
└── gke-dcgsecigke001-dcgsecigke001-linux-1cd8c3b9-v1vr running 4 pod(s) (linux/amd64)
├── default
│ ├── docker-in-the-cloud-339-4x9dq-0xd3q (running)
│ └── liveness-test-4-boom (failed)
└── jenkins-onprem
├── docker-in-the-cloud-337-4c4lm-q3mtp (running)
└── docker-in-the-cloud-342-r5khq-9cx2w (running)
When more than one namespace is selected, viewnode switches to the grouped namespace tree shown above so the multi-namespace and --all-namespaces layouts stay consistent.
Selected namespaces continue to show the existing totals, unscheduled pod summary, and node pod counts while using the same grouped tree layout as --all-namespaces.
Per-node namespace grouping follows the same inclusion rule as --all-namespaces: only namespaces with matching pods on that node are rendered, while nodes without matches still stay visible:
$ viewnode --namespace default,team-a
3 pod(s) in total
0 unscheduled pod(s)
2 running node(s) with 3 scheduled pod(s):
├── worker-a running 3 pod(s) (linux/amd64)
│ └── default
│ ├── api-0 (running)
│ └── web-0 (running)
└── worker-b running 0 pod(s) (linux/amd64)
Use --watch / -w to keep refreshing the current command instead of wrapping viewnode with an external watch process.
viewnoderuns once and exits.viewnode --watchandviewnode -wrefresh every 1 second.viewnode --watch 5andviewnode -w 5refresh every 5 seconds.- Invalid values such as
--watch 0,-w -1, or--watch abcfail fast before the first refresh. - After the first successful refresh, transient refresh failures replace the current frame with
[<RFC3339 timestamp>] watch refresh failed: <error>and the loop retries after the configured interval.
Examples:
viewnode
viewnode --watch
viewnode --watch 5
viewnode -w 5
viewnode --watch 0You can still wrap viewnode with the shell's watch command when you want watch itself to own the terminal session:
watch -n1 viewnode --show-pod-start-times --show-containers
Manage kubeconfig contexts directly from viewnode:
$ viewnode ctx list
[*] dev-cluster
[ ] staging-cluster
$ viewnode ctx list --filter prod
[ ] prod-admin
[*] prod-cluster
$ viewnode ctx list -f staging
[ ] staging-cluster
$ viewnode ctx list -f does-not-exist
no contexts matched filter "does-not-exist"
$ viewnode ctx get-current
dev-cluster
$ viewnode ctx set-current staging-cluster
current context set to staging-cluster
viewnode ctx list --filter and viewnode ctx list -f apply a case-insensitive substring match to context names. An empty filter behaves like viewnode ctx list.
Aliases:
viewnode ctx lsviewnode ctx getcurrentviewnode ctx setcurrent staging-cluster
Manage namespaces in the current Kubernetes context directly from viewnode:
$ viewnode ns list
[ ] default
[*] jenkins-onprem
[ ] kube-system
$ viewnode ns list --filter kube
[ ] kube-public
[ ] kube-system
$ viewnode ns list -f missing
no namespaces matched filter "missing"
$ viewnode ns get-current
jenkins-onprem
$ viewnode ns set-current kube-system
current namespace set to kube-system
Aliases:
viewnode ns lsviewnode ns getcurrentviewnode ns setcurrent kube-system
viewnode uses Kubernetes client-go (currently v0.35.2 in this repository).
It should work with any cloud platform and Kubernetes distribution supported by client-go.
Compatibility generally follows the Kubernetes client-go policy for nearby cluster versions (for example, same minor version and close minor versions).
© 2026 NTT DATA Deutschland SE, Adam Bogdan Boczek