Services
Every address a Service answers on, one tap from the clipboard — with the cluster’s DNS zones discovered rather than assumed.

The Services tab is the kubectl get svc view: namespace-scoped, live over the watch API,
with a type facet (ClusterIP, NodePort, LoadBalancer, ExternalName — each with a
count) and a free-text search that spans name, namespace, type, cluster IP, port
numbers and names, and external hostnames. So “8080”, “https” or part of a load
balancer’s hostname all find the row.
The point is the clipboard
On a phone, what you want from a Service is almost always an address you can paste somewhere. So Kubo derives every address a Service answers on:
- cluster DNS —
name.namespace.svc.<domain>, and the short forms; - the cluster IP;
- the node port;
- any LoadBalancer ingress, external IP, or ExternalName target.
Each is offered as one entry per (domain × address × port), and each is individually
copyable. Where a port looks like a web port, a copyable http(s)://… URL is offered
too — the scheme is guessed from appProtocol first, then the port’s name, then its
number.
Tapping a row copies its primary address in one tap (the external one when there is one,
otherwise cluster DNS). The row menu copies the short hostname, the fully-qualified DNS
name, host:port or the URL, and opens the Service’s YAML. Tapping the row’s body opens a
sheet listing every address separately.
Two honest edge cases:
- a NodePort has no node IP in the Service object, so Kubo copies just the port and says “on any node IP” rather than inventing an address;
- a headless service (
clusterIP: None) drops the cluster-IP entry, because there isn’t one.
DNS zones are discovered, not assumed
cluster.local is a convention, not a guarantee: a cluster can serve a different zone
entirely, and operators often alias a second one. So Kubo reads the CoreDNS ConfigMap
in kube-system and parses the Corefile for the kubernetes plugin’s zones (dropping
reverse .arpa zones), plus any domain a rewrite name rule aliases onto them —
suffix, regex and exact forms, inline and block. Known ConfigMap names are tried
first (coredns, AKS’ coredns-custom, RKE2’s, kube-dns), then kube-system is scanned
for whatever actually holds a Corefile.
Reading ConfigMaps is an optional permission, so this is detection-gated: any failure
falls back to cluster.local.
And because a silent fallback is indistinguishable from a cluster that genuinely serves
cluster.local, discovery keeps a trail — every candidate probed, with its outcome
(found / not found / forbidden / failed) and error. A banner under the facet chips names
the zones in use, flags them when they are assumed rather than discovered, and opens the
full trail. Each discovered zone gets its own copyable hostname: the primary one labelled
“Cluster DNS”, the rest “Cluster DNS alias”.
Discovery runs once per screen, not per row, so scrolling cannot re-run it.
Events involving a Service deep-link here, so a FailedToUpdateEndpoint warning in the
events feed lands on the Service it is about.
Back to Kubernetes.