relay

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: AGPL-3.0 Imports: 38 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TagManagedBy identifies relay VMs (vs other VMs in the account).
	// Always set. Value is "llmsafespaces-relay".
	TagManagedBy = "managed-by"
	// TagOwnerUID is the InferenceRelay CR's UID; empty if Provision
	// was called without OwnerUID set (legacy / pre-fix VMs).
	TagOwnerUID = "inferencerelay-uid"
	// TagProvider identifies which provider slot the VM serves
	// (e.g. "aws", "oci", "gcp"). Empty for legacy VMs.
	TagProvider = "inferencerelay-provider"

	// TagManagedByValue is the canonical value of TagManagedBy.
	TagManagedByValue = "llmsafespaces-relay"
)

Tag keys used by all drivers when provisioning. Centralized here so any driver implementation uses the same wire contract.

View Source
const (
	// InferenceRelayFinalizer is the finalizer name for cleanup on CR deletion.
	InferenceRelayFinalizer = "inferencerelay.llmsafespaces.dev/finalizer"
)

Variables

View Source
var (
	// ErrCapacity indicates the provider returned a capacity/availability error.
	// These should NOT count against the provisioning circuit breaker.
	ErrCapacity = errors.New("provider capacity exhausted")

	// ErrConfig indicates a configuration error (bad AMI, invalid shape, etc.).
	// These DO count against the circuit breaker.
	ErrConfig = errors.New("provider configuration error")

	// ErrTimeout indicates the provisioning operation timed out.
	ErrTimeout = errors.New("provisioning timed out")
)

Error classification for circuit breaker logic.

Functions

func IsCapacityError

func IsCapacityError(err error) bool

IsCapacityError returns true if the error is a provider capacity issue.

func IsConfigError

func IsConfigError(err error) bool

IsConfigError returns true if the error is a configuration issue.

func RenderCloudInit

func RenderCloudInit(cfg CloudInitConfig) (string, error)

RenderCloudInit renders the cloud-init userdata for a relay VM. The result is base64-encoded as expected by cloud provider APIs.

Types

type AWSDriver

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

AWSDriver implements ProviderDriver for AWS EC2. It provisions relay VMs using RunInstances, manages lifecycle via TerminateInstances/DescribeInstances. Credentials are read from a K8s Secret (accessKeyId, secretAccessKey) or the default credential chain (IRSA, env vars, instance metadata).

func NewAWSDriver

func NewAWSDriver(k8sClient client.Client, namespace, credentialSecret string) *AWSDriver

NewAWSDriver creates an AWS EC2 driver that reads credentials from the named K8s Secret (default: aws-relay-irwa).

func (*AWSDriver) Destroy

func (d *AWSDriver) Destroy(ctx context.Context, instanceID, region string) error

Destroy terminates an EC2 instance.

func (*AWSDriver) GetStatus

func (d *AWSDriver) GetStatus(ctx context.Context, instanceID, region string) (*VMStatus, error)

GetStatus returns the current state of an EC2 instance.

func (*AWSDriver) ListInstances

func (d *AWSDriver) ListInstances(ctx context.Context, region string) ([]VMInstance, error)

ListInstances returns relay VMs managed by this driver. The OwnerUID and Provider fields are populated from the instance's tags so callers can filter by InferenceRelay CR ownership (worklog 0474). Pre-fix VMs that lack the tags will have empty OwnerUID/Provider.

func (*AWSDriver) Provision

func (d *AWSDriver) Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)

Provision creates an EC2 instance with the given cloud-init userdata.

type CloudInitConfig

type CloudInitConfig struct {
	// UpstreamURL is the LLM provider endpoint to proxy to.
	UpstreamURL string
	// Token is the per-VM shared-secret the relay-router presents in the
	// X-Relay-Token header. The VM's relay-proxy rejects any request without
	// a constant-time-matching token. Generated by the controller per provider
	// slot and persisted in the relay-vm-tokens Secret.
	Token string
	// ArtifactURLs are the base mirror URLs the VM downloads the relay-proxy
	// binary from. The cloud-init appends "/<binary>" where <binary> is the
	// arch-resolved name (relay-proxy-arm64 / relay-proxy-amd64) and tries
	// each mirror in order. The controller embeds these at render time —
	// typically a GitHub Release URL plus optional object-storage mirrors.
	// Required: without an artifact URL the systemd unit references a binary
	// that can never arrive on the VM.
	ArtifactURLs []string
	// ArtifactSHA256 is the hex SHA-256 of the relay-proxy binary for the
	// VM's architecture. The cloud-init verifies the downloaded binary
	// against this checksum before exec (security doc §7: supply-chain
	// integrity). Required: downloading without verification is rejected.
	ArtifactSHA256 string
	// BinaryName is the arch-resolved artifact name (relay-proxy-arm64 or
	// relay-proxy-amd64). The controller resolves this from the VM shape via
	// archForShape so the cloud-init downloads the matching binary.
	BinaryName string
}

CloudInitConfig holds the parameters for rendering the relay VM cloud-init.

type HealthChecker

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

HealthChecker scrapes the relay-router's /metrics endpoint to determine per-relay health and traffic metrics.

func NewHealthChecker

func NewHealthChecker(routerURL string) *HealthChecker

NewHealthChecker creates a HealthChecker targeting the given router URL.

func (*HealthChecker) Scrape

func (h *HealthChecker) Scrape(ctx context.Context) (*HealthReport, error)

Scrape fetches and parses the router's Prometheus metrics.

type HealthReport

type HealthReport struct {
	Relays         map[string]*RelayHealth
	FallbackActive bool
}

HealthReport aggregates health data for the entire fleet.

type InferenceRelayReconciler

type InferenceRelayReconciler struct {
	client.Client
	Scheme *runtime.Scheme

	// Namespace is the controller's namespace (for ConfigMaps, Secrets).
	Namespace string

	// HealthChecker scrapes the relay-router /metrics endpoint.
	HealthChecker *HealthChecker

	// Drivers map provider name → driver implementation.
	Drivers map[string]ProviderDriver

	// ExpectedCredentialSecrets maps provider name → the K8s Secret name
	// the driver reads credentials from. The reconciler validates that
	// spec.providers[].credentialsRef.Name matches this value.
	ExpectedCredentialSecrets map[string]string

	// ArtifactURLs are the base mirror URLs the controller embeds into each
	// relay VM's cloud-init so it can download the relay-proxy binary. Set
	// via the --relay-artifact-url controller flag (comma-separated), sourced
	// from the operator's Helm values. The cloud-init appends "/<binary>"
	// (arch-resolved) and tries each mirror in order.
	ArtifactURLs []string

	// ArtifactSHA256Arm64 is the hex SHA-256 of the arm64 relay-proxy binary.
	// Required when provisioning any arm64 shape (AWS t4g, OCI A1).
	ArtifactSHA256Arm64 string

	// ArtifactSHA256Amd64 is the hex SHA-256 of the amd64 relay-proxy binary.
	// Required when provisioning any amd64 shape (GCP e2, AWS t3).
	ArtifactSHA256Amd64 string
}

InferenceRelayReconciler reconciles InferenceRelay CRs to manage the full lifecycle of relay VMs across cloud providers.

func (*InferenceRelayReconciler) Reconcile

Reconcile handles the InferenceRelay CR lifecycle.

func (*InferenceRelayReconciler) SetupWithManager

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

SetupWithManager registers the reconciler with the controller-runtime manager.

Note: the relay-router-peers ConfigMap is intentionally NOT registered via Owns() because it has no ownerReference (see syncPeerConfigMap doc comment for why). The CM is managed by the controller's reconcile loop alone; external edits would not trigger a reconcile, which is acceptable since the controller is the only legitimate writer.

type OCIDriver

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

OCIDriver implements ProviderDriver for Oracle Cloud Infrastructure. It uses the OCI REST API directly (no SDK dependency) with request signing via the user's API key (RSA private key + fingerprint).

func NewOCIDriver

func NewOCIDriver(k8sClient client.Client, namespace, credentialSecret string) *OCIDriver

NewOCIDriver creates an OCI driver that reads credentials from the named K8s Secret (default: oci-credentials).

func (*OCIDriver) Destroy

func (d *OCIDriver) Destroy(ctx context.Context, instanceID, region string) error

Destroy terminates an OCI compute instance.

func (*OCIDriver) GetStatus

func (d *OCIDriver) GetStatus(ctx context.Context, instanceID, region string) (*VMStatus, error)

GetStatus returns the current state of an OCI compute instance.

func (*OCIDriver) ListInstances

func (d *OCIDriver) ListInstances(ctx context.Context, region string) ([]VMInstance, error)

ListInstances returns relay VMs managed by this driver in the given region. The OwnerUID and Provider fields are populated from the instance's FreeformTags; PublicIP is fetched per-instance from the VNIC attachments so adopted instances have a working endpoint.

Pre-fix VMs that lack the tags will have empty OwnerUID/Provider — the orphan detector then preserves them (manual-audit policy).

Worklog 0474.

func (*OCIDriver) Provision

func (d *OCIDriver) Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)

Provision creates an OCI compute instance with the given cloud-init userdata.

type OrphanDetector

type OrphanDetector struct {
	Client   client.Client
	Drivers  map[string]ProviderDriver
	Interval time.Duration

	// Regions enumerates the regions the detector should sweep per
	// driver, in addition to whatever regions are referenced by
	// active InferenceRelay CRs at sweep time. Set explicitly only
	// if you need to sweep regions that no current CR uses (e.g.
	// clean up after a region was removed from the spec).
	Regions []string
}

OrphanDetector periodically lists every cloud VM tagged "managed-by=llmsafespaces-relay" and destroys any whose owner UID does not match any active InferenceRelay CR. Catches the case where the controller missed a deletion event entirely (e.g. crash during finalizer processing, or pre-fix-version VMs with the legacy tag schema). See worklog 0473/0474.

This is belt-and-suspenders to the per-CR adopt + sweep paths in reconciler.go. Those paths cover the common case (Status.Update conflict during provisioning, deletion-time Status mismatch). The orphan detector covers everything else.

func (*OrphanDetector) NeedLeaderElection

func (d *OrphanDetector) NeedLeaderElection() bool

NeedLeaderElection returns true so only the leader runs the sweep. Without this, every controller replica would race to destroy the same orphans (and one of the destroy calls would no-op or error).

func (*OrphanDetector) Start

func (d *OrphanDetector) Start(ctx context.Context) error

Start runs the detector loop until ctx is canceled. It satisfies manager.Runnable so the controller-runtime manager can schedule it.

type PeerConfig

type PeerConfig struct {
	Relays []PeerEntry `json:"relays"`
}

PeerConfig is the JSON shape of the relay-router-peers ConfigMap.

type PeerEntry

type PeerEntry struct {
	ID       string `json:"id"`
	Endpoint string `json:"endpoint"`
	Provider string `json:"provider"`
	State    string `json:"state"`
	Token    string `json:"token"`
}

PeerEntry is the JSON shape for one relay VM in the ConfigMap. Must match cmd/relay-router/fleet.go PeerEntry exactly. The Endpoint is the relay VM's public IP/host:port that the router dials over HTTP. Token is the per-VM shared secret the router presents in the X-Relay-Token header.

type ProviderDriver

type ProviderDriver interface {
	// Provision creates a relay VM with the given cloud-init userdata
	// and returns the instance ID and public IP.
	Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)

	// Destroy terminates a relay VM.
	Destroy(ctx context.Context, instanceID, region string) error

	// GetStatus returns the current VM state and public IP.
	GetStatus(ctx context.Context, instanceID, region string) (*VMStatus, error)

	// ListInstances returns relay VMs managed by this driver.
	ListInstances(ctx context.Context, region string) ([]VMInstance, error)
}

ProviderDriver abstracts cloud-provider VM lifecycle operations. Rotation is always destroy + provision (no IP rotation method by design).

type ProvisionRequest

type ProvisionRequest struct {
	Name      string
	Region    string
	Shape     string
	CloudInit string

	// OwnerUID is the InferenceRelay CR's UID. Drivers MUST tag the
	// provisioned VM with this value so it can be adopted by the
	// reconciler if a Status update is lost mid-provisioning (the
	// classic K8s controller leak — provisioning side-effect committed
	// but Status persistence failed). Empty OwnerUID disables tagging
	// and the leak-protection guarantee. See worklog 0473/0474.
	OwnerUID string

	// Provider identifies which provider slot this VM serves
	// (e.g. "aws"). Drivers MUST tag the VM with this value so the
	// reconciler can adopt the right slot when multiple providers
	// share the same OwnerUID.
	Provider string
}

ProvisionRequest holds the parameters for provisioning a relay VM.

type ProvisionResult

type ProvisionResult struct {
	InstanceID string
	PublicIP   string
}

ProvisionResult is returned by Provision on success.

type RelayHealth

type RelayHealth struct {
	ID            string
	Healthy       bool
	ActiveStreams int64
	Requests      int64
	Requests429   int64
	EgressBytes   int64
}

RelayHealth represents the observed health of a single relay VM as reported by the router's /metrics endpoint.

type VMInstance

type VMInstance struct {
	InstanceID string
	PublicIP   string
	State      VMState
	OwnerUID   string
	Provider   string
}

VMInstance is a lightweight summary used by ListInstances.

OwnerUID and Provider are populated from the instance's tags when the driver provisioned with those tags set. Older VMs without tags will have empty values; the reconciler treats those as un-adoptable and the orphan detector destroys them after a grace period.

type VMState

type VMState string

VMState represents the lifecycle state of a VM as reported by the cloud provider.

const (
	VMStatePending    VMState = "pending"
	VMStateRunning    VMState = "running"
	VMStateStopping   VMState = "stopping"
	VMStateStopped    VMState = "stopped"
	VMStateTerminated VMState = "terminated"
	VMStateNotFound   VMState = "not-found"
)

type VMStatus

type VMStatus struct {
	InstanceID string
	State      VMState
	PublicIP   string
}

VMStatus represents the observed state of a relay VM.

Jump to

Keyboard shortcuts

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