controller

package
v0.3.0-alpha Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: AGPL-3.0 Imports: 33 Imported by: 0

Documentation

Overview

Package controller provides the Kubernetes controller for watching pods and managing eBPF program attachments.

Index

Constants

View Source
const (
	// AnnotationEnabled is the annotation that enables Kloak for a pod.
	AnnotationEnabled = "getkloak.io/enabled"

	// CgroupBasePath is the base path for cgroups v2.
	CgroupBasePath = "/sys/fs/cgroup"
)
View Source
const (
	// AnnotationSecretEnabled is the label/annotation to enable Kloak secret replication.
	AnnotationSecretEnabled = "getkloak.io/enabled"

	// AnnotationPort is the annotation to specify an allowed port for a secret.
	AnnotationPort = "getkloak.io/port"

	// AnnotationHosts is the annotation to specify allowed hosts for a secret.
	AnnotationHosts = "getkloak.io/hosts"

	// ShadowSecretSuffix is the suffix appended to the name of the shadow secret.
	ShadowSecretSuffix = "-kloak"
)
View Source
const (
	KubeDNSNamespace = "kube-system"
	KubeDNSName      = "kube-dns"
)

The cluster DNS Service, whose answers the data plane trusts.

View Source
const (
	// DefaultNRISocket is where containerd (2.0+) and CRI-O (1.30+) serve
	// NRI by default.
	DefaultNRISocket = "/var/run/nri/nri.sock"
)
View Source
const DefaultSecretResyncPeriod = 5 * time.Minute

DefaultSecretResyncPeriod is how often the data plane's secrets are synced when no Secret changes: what releases the virtual IP of a host no secret is restricted to any more once its retention is over, and repairs maps that drifted.

Variables

This section is empty.

Functions

func TrustedDNSServers added in v0.3.0

func TrustedDNSServers(ctx context.Context, reader client.Reader, static []net.IP, log *zap.SugaredLogger) []net.IP

TrustedDNSServers returns the DNS servers whose answers the data plane believes: kube-dns's ClusterIPs (both of a dual-stack Service, which pods are given both of as nameservers), the addresses of its endpoints, and static (--trusted-dns-servers). The endpoints are where answers come from when the CNI load balances Services at the socket (Cilium's kube-proxy replacement): the pod's query goes to a CoreDNS pod directly, and so the answer comes back from its address, not from the ClusterIP. A failed read leaves its addresses out.

Types

type NRIPlugin added in v0.3.0

type NRIPlugin struct {
	Preparer   SandboxPreparer
	SocketPath string
	// HostRoot is the host's root filesystem as this process sees it: the
	// runtime reports network namespace paths in the host's mount
	// namespace. "" means /proc/1/root (with hostPID).
	HostRoot string
	Log      *zap.SugaredLogger

	// Reconnect delays: after the runtime's connection closed, and while no
	// runtime serves NRI at SocketPath. Zero means the defaults.
	RetryAfterClose  time.Duration
	RetryUnavailable time.Duration
	// contains filtered or unexported fields
}

NRIPlugin hooks kloak into the container runtime through NRI (the Node Resource Interface of containerd and CRI-O). The runtime calls it while it creates each pod sandbox, and again before each container, and waits for it: kloak attaches the virtual IP DNS rewrite then (PrepareSandbox), before any container of the pod resolves a name. Without NRI (a runtime without it, NRI disabled, or the socket not mounted), the Reconciler attaches the rewrite by polling Pending pods instead.

The plugin never fails a runtime request: an error would fail the pod's sandbox or container. A request taking longer than the runtime's timeout (2 s by default) disconnects the plugin, which reconnects.

func (*NRIPlugin) Run added in v0.3.0

func (p *NRIPlugin) Run(ctx context.Context) error

Run serves NRI until ctx is done, reconnecting when the runtime's connection closes. It returns nil: NRI is optional, and the manager stops when a runnable returns an error.

type Reconciler

type Reconciler struct {
	client.Client
	Log           *zap.SugaredLogger
	Scheme        *runtime.Scheme
	UprobeManager *ebpf.TLSUprobeManager
	CgroupRoot    string
	// NodeName filters pods to only those on this node (empty = all nodes)
	NodeName string
	// APIReader reads a pod from the API server when the cache does not have
	// it yet (PrepareSandbox); nil: cache only.
	APIReader client.Reader
	// contains filtered or unexported fields
}

Reconciler watches pods and manages eBPF cgroup tracking.

func NewReconciler

func NewReconciler(c client.Client, log *zap.SugaredLogger, scheme *runtime.Scheme, uprobeMgr *ebpf.TLSUprobeManager, cgroupRoot, nodeName string) *Reconciler

NewReconciler creates a new pod reconciler.

func (*Reconciler) GetTrackedPodCount

func (r *Reconciler) GetTrackedPodCount() int

GetTrackedPodCount returns the number of currently tracked pods.

func (*Reconciler) PrepareSandbox added in v0.3.0

func (r *Reconciler) PrepareSandbox(ctx context.Context, sb *Sandbox) bool

PrepareSandbox attaches the virtual IP DNS rewrite in a kloak pod's network namespace and binds the pod at its addresses, while the container runtime creates the pod's sandbox or one of its containers (NRI): the runtime waits for it, so the rewrite is in place before any container of the pod resolves a name. It reports whether the pod is prepared; when it is not (no NRI, or a failure), the reconciler attaches the rewrite by polling the Pending pod, which leaves a short window at pod start.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile handles pod create/update/delete events.

func (*Reconciler) SetupWithManager

func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type Sandbox added in v0.3.0

type Sandbox struct {
	ID        string
	UID       string
	Namespace string
	Name      string
	// Annotations are the pod's (the kubelet passes them to the sandbox).
	Annotations map[string]string
	// NetnsPath is the sandbox's network namespace as a path this process
	// can open; "" when the runtime does not report one (host network).
	NetnsPath string
	// IPs are the pod's addresses, when the runtime reports them.
	IPs []netip.Addr
}

Sandbox is a pod sandbox the container runtime is creating, as it reports it over NRI.

type SandboxPreparer

type SandboxPreparer interface {
	PrepareSandbox(ctx context.Context, sb *Sandbox) bool
}

SandboxPreparer prepares a pod sandbox the container runtime is creating (Reconciler.PrepareSandbox).

type SecretReconciler

type SecretReconciler struct {
	client.Client
	Log    *zap.SugaredLogger
	Scheme *runtime.Scheme
}

SecretReconciler reconciles a Secret object

func (*SecretReconciler) Reconcile

func (r *SecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile handles Secret events.

func (*SecretReconciler) SetupWithManager

func (r *SecretReconciler) SetupWithManager(mgr ctrl.Manager) error

type SecretSyncReconciler added in v0.3.0

type SecretSyncReconciler struct {
	// Sync makes the data plane hold the cluster's current secrets
	// (TLSUprobeManager.SyncSecrets). An error is logged by the controller
	// and retried with backoff.
	Sync func(context.Context) error
	// ResyncPeriod is the time between syncs when nothing changes;
	// 0 means DefaultSecretResyncPeriod.
	ResyncPeriod time.Duration
}

SecretSyncReconciler keeps the data plane's secrets in step with the cluster's kloak Secrets: an enabled Secret or a shadow that is created, changed or deleted triggers a sync.

func (*SecretSyncReconciler) Reconcile added in v0.3.0

func (r *SecretSyncReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error)

Reconcile syncs every secret. Every request is secretSyncRequest.

func (*SecretSyncReconciler) SetupWithManager added in v0.3.0

func (r *SecretSyncReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager watches Secrets, through the cache the Secret reconciler already fills, and syncs once at start: with no kloak Secret there is no event, and the virtual IPs restored from the pinned maps still need to be retired.

type TrustedDNSReconciler added in v0.3.0

type TrustedDNSReconciler struct {
	client.Client
	// Static are the --trusted-dns-servers.
	Static []net.IP
	// Apply makes the data plane trust exactly these servers.
	Apply func([]net.IP) error
	Log   *zap.SugaredLogger
	// contains filtered or unexported fields
}

TrustedDNSReconciler keeps the trusted DNS servers (TrustedDNSServers) in the data plane as kube-dns changes: its endpoints come and go with the CoreDNS pods.

func (*TrustedDNSReconciler) Reconcile added in v0.3.0

func (r *TrustedDNSReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error)

Reconcile recomputes the trusted servers and applies them when they changed. Every request names kube-dns.

func (*TrustedDNSReconciler) SetupWithManager added in v0.3.0

func (r *TrustedDNSReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager watches the kube-dns Service and its EndpointSlices.

Jump to

Keyboard shortcuts

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