k8s

package
v0.0.0-...-8fb1331 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package k8s implements the Registry interface using the Kubernetes API server as the backend. It discovers service endpoints by listing pods with the aether.io/managed=true label and derives service names from each pod's ServiceAccount. Node topology labels provide region and zone locality information.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// ClusterName is the name of the cluster, used to populate ServiceEndpoint.ClusterName.
	ClusterName string
}

Config holds the configuration for the Kubernetes registry backend.

type KubernetesRegistry

type KubernetesRegistry struct {
	// contains filtered or unexported fields
}

KubernetesRegistry is a Registry implementation backed by the Kubernetes API server. It reads pods labeled with aether.io/managed=true and converts them to ServiceEndpoints. Write operations (Register/Unregister) are no-ops since the API server is the source of truth.

func NewKubernetesRegistry

func NewKubernetesRegistry(log *slog.Logger, reader client.Reader, cfg Config) *KubernetesRegistry

NewKubernetesRegistry creates a new Kubernetes API server backed Registry. The reader should be a direct API reader (e.g., manager.GetAPIReader()) to avoid cache synchronization issues during startup.

func (*KubernetesRegistry) Close

func (r *KubernetesRegistry) Close() error

Close is a no-op for the Kubernetes registry.

func (*KubernetesRegistry) Initialize

func (r *KubernetesRegistry) Initialize(_ context.Context) error

Initialize is a no-op for the Kubernetes registry. The API server connection is managed by the controller-runtime manager.

func (*KubernetesRegistry) ListAllEndpoints

ListAllEndpoints returns all endpoints for all services, grouped by service name (ServiceAccount). It lists all managed pods, resolves node localities, and converts each pod to a ServiceEndpoint.

Pods are filtered by the protocol each declares in endpoint.aether.io/protocol, exactly as in ListEndpoints — see there for why this backend used to return an empty map for TCP and why it no longer has to (#878). A service with no pod serving the requested protocol is absent from the result rather than present and empty, so the agent's cluster passes see only the services they should build.

func (*KubernetesRegistry) ListEndpoints

func (r *KubernetesRegistry) ListEndpoints(ctx context.Context, service string, protocol registryv1.Service_Protocol) ([]*registryv1.ServiceEndpoint, error)

ListEndpoints returns all endpoints for a service by listing managed pods whose ServiceAccount matches the given service name. Node topology labels are used for locality information.

Endpoints are filtered by the protocol each POD declares in endpoint.aether.io/protocol, so a query for P returns exactly the pods serving P (#878).

This backend used to return nothing at all for a TCP query. That was a workaround, not a property of Kubernetes: podToEndpoint ignored the protocol annotation, so every managed pod looked like an HTTP endpoint, and answering a TCP query with that same set made every mesh service collapse to a TCP-only entry — the agent's LoadClustersFromRegistry builds a service's HTTP cluster (with its outbound and cap_http vhosts) from the HTTP listing, then OVERWRITES the same map key with a vhost-less tcp:true entry from the TCP listing. The CDS cluster and GAMMA vhost vanished and captured requests 503'd with no_healthy_upstream.

Reading the annotation removes the need for the workaround: a pod declaring "tcp" appears only in the TCP listing and a pod declaring "http" only in the HTTP one, so the two listings are disjoint and the agent's second pass has nothing to clobber. The "a service is HTTP or TCP, never both" invariant still holds, because every pod behind one ServiceAccount carries the same annotation.

Filtering runs in BOTH directions on purpose. Returning HTTP-declaring pods under TCP is the bug above; returning TCP-declaring pods under HTTP is the same bug mirrored, and would put a raw-TCP pod behind an h2 cluster.

func (*KubernetesRegistry) RegisterEndpoint

RegisterEndpoint is a no-op. The Kubernetes API server is the source of truth for pod endpoints.

func (*KubernetesRegistry) UnregisterEndpoint

func (r *KubernetesRegistry) UnregisterEndpoint(_ context.Context, _ string, _ string) error

UnregisterEndpoint is a no-op. The Kubernetes API server is the source of truth for pod endpoints.

func (*KubernetesRegistry) UnregisterEndpoints

func (r *KubernetesRegistry) UnregisterEndpoints(_ context.Context, _ string, _ []string) error

UnregisterEndpoints is a no-op. The Kubernetes API server is the source of truth for pod endpoints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL