Documentation
¶
Overview ¶
Package servicediscovery enumerates the running orchestrator and template-builder instances that callers route sandbox and build traffic to.
Every backend reports a broken source the same way: the error reaches the caller, which skips the cycle and keeps its last known set. The listers — nomad.NewServices, nomad.NewNodePool, nomad.NewAllocations, kube.NewPods, dns.New, NewLocal, NewRemote and NewStatic — hit their source per call, and provider.New selects one from configuration; Cached wraps one in a background refresh and serves the last good set alongside the last refresh error, so a dead source is reported rather than read as an indefinitely stale one. ErrNotYetSynced distinguishes a cache that has never completed a refresh from one that read an empty source. NewMerged propagates either side's error for the same reason.
Index ¶
Constants ¶
const ( BackendNomad = "nomad" BackendKubernetes = "kubernetes" BackendLocal = "local" BackendRemote = "remote" BackendDNS = "dns" BackendStatic = "static" )
The lister that produced an instance. Both schedulers run instances during the migration and shift on independent schedules, so an operator reading the catalog has to be able to tell the two apart; the rest are named so the answer is never "unknown".
Variables ¶
var ErrNotYetSynced = errors.New("service discovery has not completed a refresh yet")
ErrNotYetSynced is what a cached Discoverer reports before its first refresh lands: no set has been read, which is not the same as reading an empty one.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Provider selects the discovery backend. "NOMAD+K8S-PODS" unions the two
// single-platform ones and needs the configuration of both.
Provider string `env:"PROVIDER,required"`
OrchestratorPort uint16 `env:"PORT" envDefault:"5008"`
// when Provider == "DNS"
DNSQuery []string `env:"DNS_QUERY"`
DNSResolverAddress string `env:"DNS_RESOLVER_ADDRESS"`
// when Provider == "K8S-PODS" or "NOMAD+K8S-PODS"
//
// Empty K8sAPIEndpoint uses the pod's own ServiceAccount and only works
// inside the cluster; set it to reach a cluster from outside, on Google ADC.
K8sAPIEndpoint string `env:"K8S_API_ENDPOINT"`
PodNamespace string `env:"POD_NAMESPACE"`
PodLabels string `env:"POD_LABELS"`
HostIP bool `env:"HOST_IP"`
// when Provider == "STATIC"
StaticEndpoints []string `env:"STATIC"`
// when Provider == "NOMAD" or "NOMAD+K8S-PODS"
NomadEndpoint string `env:"NOMAD_ENDPOINT"`
NomadToken string `env:"NOMAD_TOKEN"`
}
type Discoverer ¶
type Discoverer interface {
ListInstances(ctx context.Context) ([]Instance, error)
// Start begins the background refresh a cached adapter needs before its
// first ListInstances returns anything; query adapters ignore it.
Start(ctx context.Context)
// Stop ends what Start began.
Stop(ctx context.Context)
}
Discoverer enumerates currently running instances. Implementations are safe for concurrent use; callers list on a fixed interval plus on demand from the request path.
func Cached ¶
func Cached(lister Discoverer, logger logger.Logger) Discoverer
Cached wraps lister in a background refresh loop.
func NewLocal ¶
func NewLocal(addr string) (Discoverer, error)
NewLocal builds a Discoverer that always returns one instance reachable at addr. addr may be "host:port" or just "host"; when the port is omitted, consts.OrchestratorAPIPort is used.
func NewMerged ¶
func NewMerged(primary, fallback Discoverer) Discoverer
NewMerged creates a Discoverer that unions primary's and fallback's instances, deduplicated by ID with primary taking precedence.
func NewRemote ¶
func NewRemote(client *api.ClientWithResponses) Discoverer
NewRemote creates a Discoverer backed by a remote cluster's edge API.
func NewStatic ¶
func NewStatic(results []string, port uint16) Discoverer
type Instance ¶
type Instance struct {
// WorkloadID is unique within this instance's source. Backends that union
// with each other must agree on it for the same instance — which is why the
// two Nomad node backends both derive it from the node rather than reaching
// for an allocation. Consumers compare it as an opaque string of no assumed
// width.
WorkloadID string
// NodeID is the machine the instance runs on. Empty where the source has no
// notion of one: DNS and STATIC resolve addresses, not schedulers, and the
// machine only arrives once the instance answers over gRPC. Every source
// the api uses reports one; the two that do not are consumed only where it
// is never read.
NodeID string
// IPAddress is the host the instance's gRPC server listens on: the Nomad
// node IP, or the pod IP of a host-networked pod.
IPAddress string
// Port is that server's port.
Port uint16
// Backend is the lister that produced this instance. Only two of them name
// a scheduler; the others say how the instance was learned of instead,
// which is the honest answer and keeps the field total.
Backend string
}
Instance is a single discovered instance.
It carries two identities because consumers need different ones and a single key cannot serve both. ID answers "is this the same thing I saw last cycle", and every backend picks the narrowest identity its source exposes: an allocation or a pod, where a restart produces a new one, so a consumer tracking service instances notices the restart. NodeID answers "which machine is it on", and survives that restart, so a consumer tracking placement targets is not churned by it.