Documentation
¶
Index ¶
- Constants
- Variables
- func IsCapacityError(err error) bool
- func IsConfigError(err error) bool
- func RenderCloudInit(cfg CloudInitConfig) (string, error)
- type AWSDriver
- func (d *AWSDriver) Destroy(ctx context.Context, instanceID, region string) error
- func (d *AWSDriver) GetStatus(ctx context.Context, instanceID, region string) (*VMStatus, error)
- func (d *AWSDriver) ListInstances(ctx context.Context, region string) ([]VMInstance, error)
- func (d *AWSDriver) Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)
- type CloudInitConfig
- type HealthChecker
- type HealthReport
- type InferenceRelayReconciler
- type OCIDriver
- func (d *OCIDriver) Destroy(ctx context.Context, instanceID, region string) error
- func (d *OCIDriver) GetStatus(ctx context.Context, instanceID, region string) (*VMStatus, error)
- func (d *OCIDriver) ListInstances(ctx context.Context, region string) ([]VMInstance, error)
- func (d *OCIDriver) Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)
- type OrphanDetector
- type PeerConfig
- type PeerEntry
- type ProviderDriver
- type ProvisionRequest
- type ProvisionResult
- type RelayHealth
- type VMInstance
- type VMState
- type VMStatus
Constants ¶
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.
const (
// InferenceRelayFinalizer is the finalizer name for cleanup on CR deletion.
InferenceRelayFinalizer = "inferencerelay.llmsafespaces.dev/finalizer"
)
Variables ¶
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 ¶
IsCapacityError returns true if the error is a provider capacity issue.
func IsConfigError ¶
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 ¶
NewAWSDriver creates an AWS EC2 driver that reads credentials from the named K8s Secret (default: aws-relay-irwa).
func (*AWSDriver) ListInstances ¶
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 ¶
func (r *InferenceRelayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)
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 ¶
NewOCIDriver creates an OCI driver that reads credentials from the named K8s Secret (default: oci-credentials).
func (*OCIDriver) ListInstances ¶
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).
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 ¶
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.