kubernetes

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

Package kubernetes is fiberd's home in a Kubernetes grant Pod, where fiberd is the Pod's one container. The home fetches the Pod's grant from the controller with the Pod's bound service-account token, renews it at half its lease and writes it into the grants directory. The directory is polled for *.jwt files, so a grant another writer drops there is read too. Without a token file, grants arrive only as such files.

Control-plane liveness is the API server answering for the Pod. Readiness is a Pod condition a readiness gate waits on, set once a template is warm. The cgroup subtree is the Pod's own, under the kubelet's ceiling. Endpoints are the Pod's IP, and the device channel is the Pod's ResourceClaim. Scope is what the Pod is, namespace, service account, node and claims, and the home loses it when the Pod is gone, replaced or terminating, the namespace terminates, a claim is deleted under a live Pod, or the cluster has not served the claims for the stale TTL.

The production controller that creates grant Pods is a separate project. It lists PodConditionZygoteReady as a readiness gate on every grant Pod and serves the grants the home fetches.

Index

Constants

View Source
const (
	// DefaultStaleTTL is how long the API server may go without answering
	// for the Pod before the home counts as unhealthy.
	DefaultStaleTTL = 30 * time.Second
	// DefaultGrantsPoll is how often the grants directory is read.
	DefaultGrantsPoll = 2 * time.Second
	// DefaultGrantFetchTimeout is how long New retries the first grant
	// fetch.
	DefaultGrantFetchTimeout = 60 * time.Second
)
View Source
const (
	// PodConditionZygoteReady is the Pod condition fiberd sets once a
	// template is warm. The Kubernetes controller lists it as a readiness
	// gate on every grant Pod, so the Pod joins its Service only then.
	PodConditionZygoteReady = "fiberd.io/zygote-ready"
	// ReasonTemplateWarm is the condition's reason while it is True. At
	// least one grant has a warm template.
	ReasonTemplateWarm = "TemplateWarm"
	// ReasonNoWarmTemplate is the condition's reason while it is False.
	// No grant has a warm template yet, or the last one went cold.
	ReasonNoWarmTemplate = "NoWarmTemplate"
)
View Source
const Name = "kubernetes"

Name is what this home is selected by.

Variables

View Source
var ErrNoResourceClaims = errors.New("the cluster serves no resource.k8s.io API")

ErrNoResourceClaims is what GetResourceClaim returns when the cluster serves no resource.k8s.io group, so no ResourceClaim can be read.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Kube is the cluster. Required.
	Kube Kube
	// PodName and PodNamespace name this Pod. Required.
	PodName      string
	PodNamespace string
	// PodUID is this Pod's UID. Required. A Pod read with another UID is
	// a replacement, and the scope is lost.
	PodUID string
	// StaleTTL is how long the API server may go without answering for
	// the Pod before the home is unhealthy. Default DefaultStaleTTL.
	StaleTTL time.Duration
	// Poll is how often the API server is asked. It is also how long one
	// round may take. Default half of StaleTTL.
	Poll time.Duration
	// GrantsDir is the directory polled for *.jwt files, and the one the
	// grant fetch writes. Empty means no delivery and no grant to admit.
	// fiberd refuses to start this home so, unless a test-hooks build runs
	// under -admin-unsafe, where grants arrive inside Clone requests.
	GrantsDir string
	// GrantsPoll is how often GrantsDir is read. Default DefaultGrantsPoll.
	GrantsPoll time.Duration
	// GrantTokenFile is the path of the Pod's bound service-account
	// token, sent to fetch the Pod's grant. Empty means no fetch, and
	// grants arrive only as files. Set, it needs GrantIssuerURL and
	// GrantsDir.
	GrantTokenFile string
	// GrantIssuerURL is the issuer, the controller. Grants are fetched
	// from it with "/v1/grant" appended. It must be https when the fetch
	// is on.
	GrantIssuerURL string
	// GrantCAFile is the PEM CA bundle the grant endpoint's certificate
	// must chain to. Empty means the system roots.
	GrantCAFile string
	// GrantFetchTimeout is how long New retries the first grant fetch.
	// Default DefaultGrantFetchTimeout.
	GrantFetchTimeout time.Duration
	// Cache is the verifier's key cache, refreshed in the background while
	// the home runs. Nil means no issuer keys to refresh.
	Cache *grant.Cache
	// Family picks which Pod IP callers dial. Unix means fibers are
	// reachable from inside the Pod only, and no address is advertised.
	Family endpoint.Family
	// Devices is what the device driver exposed to this Pod, device paths
	// or ids, handed to every grant's engine as its device channel.
	Devices []string
	// CgroupRoot is the cgroup v2 subtree fiberd may carve. Empty means
	// the cgroup this process runs in, under /sys/fs/cgroup, delegated:
	// fiberd moves into its `fiberd` leaf and carves under its `grants`
	// child.
	CgroupRoot string
	// Clock drives the polls and stamps the health. Default the real
	// clock.
	Clock clock.WithTicker
	// Logger receives the home's log lines. Default klog's.
	Logger logr.Logger
}

Config is what cmd/fiberd hands New.

func (Config) Validate

func (c Config) Validate() error

Validate reports the first thing wrong with c, after defaults.

type Home

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

Home is the Kubernetes home. It implements home.Home, and the optional fiberd.ScopeLoser, fiberd.EndpointHoster and the issuer override behind the admin socket.

func New

func New(ctx context.Context, cfg Config) (*Home, error)

New builds the home. It reads nothing from the cluster. The first read happens in EndpointHost, Devices or the first poll round. The health starts in sync, so a Pod the API server has not answered for yet is not unhealthy before the stale TTL has passed.

With a grant token file, New fetches the Pod's grant before it returns, retrying for up to GrantFetchTimeout. It fails when no grant came by then, unless the grants directory holds an unexpired grant file for the Pod. Run renews the grant from there.

ctx bounds New's own work, which is the first grant fetch. When ctx ends first, New closes the home and returns ctx's cause. ctx is not the home's lifetime. Run's context and Close end the home once New has returned it.

func (*Home) CgroupRoot

func (h *Home) CgroupRoot() string

func (*Home) Close

func (h *Home) Close()

Close ends what New started, the wait for the Pod's address in EndpointHost. Run's context ends everything else.

func (*Home) Devices

func (h *Home) Devices(ctx context.Context, _ core.Grant) (core.DeviceChannel, func(), error)

Devices is the Pod's ResourceClaim with the devices the driver exposed, a static set when the Pod has devices but no claim, and nothing otherwise. The claim is the Pod's, so there is nothing to release per grant. The Pod is read first when it has not been yet. A failed read never fails the admission, since fiberd does not retry one until the grant changes. The answer is then the static set, or no channel without devices.

func (*Home) EndpointHost

func (h *Home) EndpointHost() string

EndpointHost is the Pod's IP of the configured family. The last Pod stored is consulted first. fiberd asks before Run, and PID 1 can start before the kubelet has written the address, so the home then reads the Pod every podIPRetry for up to podIPWait. Close, or Run's context ending, cuts the wait short. It returns "" when the Pod has no address of that family in time, and logs the last read error once when it gives up. The unix family advertises no address, so it returns "" at once.

func (*Home) Grants

func (h *Home) Grants(ctx context.Context) (<-chan home.GrantEvent, error)

Grants polls the projected directory. A new or changed *.jwt file is GrantAdded, a removed one GrantRemoved.

func (*Home) Health

func (h *Home) Health() *core.SourceHealth

func (*Home) Name

func (h *Home) Name() string

func (*Home) OnScopeLost

func (h *Home) OnScopeLost(fn func(ctx context.Context, reason string))

OnScopeLost sets what is called, once per reason and on a goroutine of the home's own, when the Pod's scope goes away under it. fiberd wires its epoch bump.

func (*Home) OwnGrant

func (h *Home) OwnGrant() ([]byte, bool)

OwnGrant is the Pod's own grant, the file the grant fetch wrote. Clone admits it on the Pod UID in place of the token presented. A home without a grant fetch holds none.

func (*Home) PublishReady

func (h *Home) PublishReady(ctx context.Context, grantUID string, ready bool) error

PublishReady records that the grant's template is warm, or no longer is, and sets the Pod condition when that flips "any template is warm".

func (*Home) Ready

func (h *Home) Ready() bool

Ready reports whether any grant's template is warm, which is what the Pod condition says once it is published.

func (*Home) Run

func (h *Home) Run(ctx context.Context)

Run drives the liveness poll, the delivery of scope losses, the key cache refresh and the grant renewal until ctx ends. It returns only once all of them have stopped. A second Run logs and returns at once, as a shared informer does.

func (*Home) Scope

func (h *Home) Scope() []core.ScopeClaim

Scope is the facts the Pod is made of. Before the first Pod is stored it holds what the configuration knows, the namespace, the Pod name and its UID. A stored Pod adds the service account, the node and one claim per ResourceClaim.

func (*Home) SelfAdmitUID

func (h *Home) SelfAdmitUID() string

SelfAdmitUID is the Pod UID, since the controller issues this Pod's grant under it and a token for an earlier Pod of the same name must not self-admit here.

func (*Home) SetIssuerReachable

func (h *Home) SetIssuerReachable(reachable bool)

SetIssuerReachable is the test-only override behind fiberd's admin socket. false marks the API server unreachable now and keeps it so. true resumes the polls and marks it reachable. The pause comes first, and it waits for a round marking the health, so the mark here is the last one.

type Kube

type Kube interface {
	// GetPod reads one Pod.
	GetPod(ctx context.Context, namespace, name string) (*corev1.Pod, error)
	// GetNamespace reads one Namespace.
	GetNamespace(ctx context.Context, name string) (*corev1.Namespace, error)
	// GetResourceClaim reads the metadata of one ResourceClaim, which is
	// all the home needs from it. It returns ErrNoResourceClaims when the
	// cluster serves no resource.k8s.io group.
	GetResourceClaim(ctx context.Context, namespace, name string) (*metav1.PartialObjectMetadata, error)
	// PatchPodStatus applies a strategic merge patch to the Pod's status
	// subresource.
	PatchPodStatus(ctx context.Context, namespace, name string, patch []byte) error
}

Kube is the slice of the Kubernetes API the home touches. NewKube serves it from a cluster, and fake.Kube from memory.

func NewKube

func NewKube(ctx context.Context, cfg *rest.Config) (Kube, error)

NewKube connects to the cluster cfg names and discovers which resource.k8s.io version it serves. A cluster without that group still works, and GetResourceClaim then returns ErrNoResourceClaims.

Directories

Path Synopsis
Package fake serves the Kubernetes home's slice of the API from memory, for tests that need no API server.
Package fake serves the Kubernetes home's slice of the API from memory, for tests that need no API server.

Jump to

Keyboard shortcuts

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