Documentation
¶
Overview ¶
Package addons carries the cluster add-on manifests (CoreDNS, local-path storage, Cilium CNI) embedded in the stratum binary, and renders each one for the cluster it is about to be installed into — substituting the mirrored image registry, the pinned versions, and the per-cluster apiserver endpoint.
Rendering is all this package does. The controller writes the rendered bundles into /var/lib/stratum/manifests (internal/cluster.writeBundles) and the operator's deployer server-side-applies and prunes them, so there is one apply path rather than two.
Index ¶
- Constants
- Variables
- func FillAPIServer(m []byte, a APIServer) []byte
- func NeedsAPIServer(m []byte) bool
- func RenderCilium(dualStack bool, s CiliumSettings) []byte
- func RenderCiliumStaged(s CiliumSettings) []byte
- func RenderCoreDNS() []byte
- func RenderDashboard(s DashboardSettings) []byte
- func RenderHelmCRDs() []byte
- func RenderJoinFencePolicy() []byte
- func RenderLocalPath() []byte
- func RenderNodeMarkPolicy() []byte
- type APIServer
- type CiliumSettings
- type DashboardSettings
Constants ¶
const ( DNSAddressSentinel = "__STRATUM_DNS_IP__" ClusterDomainSentinel = "__STRATUM_CLUSTER_DOMAIN__" EnableIPv6Sentinel = "__STRATUM_ENABLE_IPV6__" StorageDefaultSentinel = "__STRATUM_STORAGE_DEFAULT__" )
The four per-cluster inputs the staged bundles carry as named sentinels instead of the staging node's local values. The staging path leaves them unfilled, so every control plane stages the same bytes; the deployer fills each at apply time from the cluster-inputs record the staging writes beside the prune inventory (operator.manifestSentinels is the consuming table). They resolve to what their name says:
- DNSAddressSentinel: the kube-dns Service's clusterIP, the tenth address of the cluster's service CIDR (netcfg.DNSIPFor).
- ClusterDomainSentinel: the cluster domain the Corefile serves.
- EnableIPv6Sentinel: Cilium's dual-stack toggle, true or false.
- StorageDefaultSentinel: whether local-path claims the default StorageClass, true when spec.storage.default is local-path.
const ( StorageLocalPath = "local-path" StorageNone = "none" )
Storage backends selectable in the cluster config (spec.storage.default). Only local-path and none are selectable here.
const ( DashboardStack = "dashboard" DashboardNamespace = "stratum-dashboard" DashboardName = "stratum-dashboard" DashboardTLSSecret = "stratum-dashboard-tls" DashboardSessionSecret = "stratum-dashboard-session" DashboardCASecret = "stratum-dashboard-ca" DashboardHostsKey = "stratum.ciq.com/serving-hosts" DefaultDashboardPort = 30443 )
The in-cluster dashboard's fixed names, shared with the operator that keeps its Secrets.
Variables ¶
var ( CorednsVersion = "unknown" LocalPathVersion = "unknown" // ImageRegistry is the namespace every bundled manifest pulls from. A // running cluster reaches no upstream registry: the images are mirrored // here by digest (tools/mirror-images.sh) and carried in the airgap payload // under these exact names, so the manifest and the payload agree by // construction. Unstamped builds get a name that resolves nowhere, on // purpose — same reason as CorednsVersion. ImageRegistry = "unknown" )
Stamped from build/versions.mk at link time (see the repo Makefile) so the deployed images always match the pin manifest and the airgap payload.
var DashImage = "unknown"
DashImage is the dashboard image the payload carries, stamped at link time.
var DashboardTokenSecrets = map[string]string{
"stratum-dashboard-admin-token": "stratum-dashboard-admin",
"stratum-dashboard-viewer-token": "stratum-dashboard-viewer",
}
DashboardTokenSecrets maps each sign-in token Secret the stack carries to its ServiceAccount.
Functions ¶
func FillAPIServer ¶
FillAPIServer resolves the apiserver sentinels. The URL list is space separated, which is the form Cilium's chart renders for k8s.apiServerURLs in both places it appears.
func NeedsAPIServer ¶
NeedsAPIServer reports whether a manifest still carries an apiserver sentinel that FillAPIServer must resolve before it is applied.
func RenderCilium ¶
func RenderCilium(dualStack bool, s CiliumSettings) []byte
RenderCilium substitutes the per-node-independent values into the embedded manifest: the registry, the operator replica count, and the cluster's spec.network.cilium settings. The apiserver sentinels are left for FillAPIServer, because the right values depend on the cluster, not on the node rendering the file — and so is the dual-stack toggle: what enable-ipv6 should say is the cluster's, not the staging node's, so the staging path calls RenderCiliumStaged, which leaves it as EnableIPv6Sentinel for the deployer to fill at apply time. The dualStack argument only decides what a direct RenderCilium caller's bytes say.
func RenderCiliumStaged ¶
func RenderCiliumStaged(s CiliumSettings) []byte
RenderCiliumStaged renders the Cilium bundle the staging path stages: RenderCilium's render with the dual-stack toggle left as the EnableIPv6Sentinel instead of the staging node's own DualStack answer. Every control plane therefore stages the same bytes, and the deployer fills the toggle at apply time from the cluster-inputs record, the way it fills the apiserver sentinels from cluster state.
func RenderCoreDNS ¶
func RenderCoreDNS() []byte
RenderCoreDNS renders the CoreDNS stack the staging path stages: the registry, the pinned busybox helper image and the CoreDNS version resolve here, while the two per-cluster inputs stay as the DNSAddressSentinel (the kube-dns Service's clusterIP) and the ClusterDomainSentinel (the Corefile's zone) — the deployer fills both at apply time from the cluster-inputs record, so every control plane stages the same bytes whatever its own service CIDR and domain are. Both inputs live in cluster state, so the render takes no dnsIP or domain argument: an argument that the bytes never read states an intent the manifest does not carry.
func RenderDashboard ¶
func RenderDashboard(s DashboardSettings) []byte
RenderDashboard renders the dashboard stack. A zero NodePort gives a ClusterIP Service.
func RenderHelmCRDs ¶
func RenderHelmCRDs() []byte
func RenderJoinFencePolicy ¶
func RenderJoinFencePolicy() []byte
RenderJoinFencePolicy is the join fence admission policy and its binding.
func RenderLocalPath ¶
func RenderLocalPath() []byte
RenderLocalPath renders the local-path stack the staging path stages: the registry, the pinned busybox helper image and the provisioner's version resolve here, while whether the StorageClass claims the cluster default stays as the StorageDefaultSentinel — the cluster's storage decision, which the deployer fills at apply time from the cluster-inputs record.
func RenderNodeMarkPolicy ¶
func RenderNodeMarkPolicy() []byte
RenderNodeMarkPolicy is the node-mark admission policy stack.
Types ¶
type APIServer ¶
type APIServer struct {
// Host is KUBERNETES_SERVICE_HOST in every Cilium pod.
Host string
// URLs is k8s-api-server-urls: every control plane, which the agents rotate
// through until they reach the kubernetes Service. Empty means Host alone.
URLs []string
}
APIServer is how Cilium reaches the apiserver before Kubernetes networking exists: kube-proxy-free agents cannot use the in-cluster Service until they are themselves up.
func APIServerFor ¶
APIServerFor derives the Cilium apiserver settings from facts every control plane sees identically, so the manifest is the same whichever of them the operator leader runs on. A render that bakes in the rendering node's own IP would differ per control plane: a leader change re-points every agent at the new leader and rolls the DaemonSet during the failover it was reacting to, and an agent pinned to one control plane loses the API whenever that one does.
- With a VIP: the VIP alone. kube-vip already moves it.
- Without one: every control plane's address, sorted, and the first of them as Host. Losing a node does not remove its Node object, so failover changes neither value; a join or a removal does, and rolls the agents once, as a planned change.
selfIP is the fallback while no Node carries the control-plane label yet (the first apply on a fresh cluster). An empty result means there is nothing to render with, and the caller must not apply.
type CiliumSettings ¶
type CiliumSettings struct {
MTU int `json:"mtu,omitempty"`
Devices []string `json:"devices,omitempty"`
BGPControlPlane bool `json:"bgpControlPlane,omitempty"`
NativeRouting bool `json:"nativeRouting,omitempty"`
IPv4NativeRoutingCIDR string `json:"ipv4NativeRoutingCIDR,omitempty"`
IPv6NativeRoutingCIDR string `json:"ipv6NativeRoutingCIDR,omitempty"`
AutoDirectNodeRoutes bool `json:"autoDirectNodeRoutes,omitempty"`
}
CiliumSettings are the cluster's Cilium options from spec.network.cilium. The zero value is the shipped configuration: VXLAN tunnel, auto-detected devices, Cilium's own MTU, no BGP control plane.
func DecodeCiliumSettings ¶
func DecodeCiliumSettings(b []byte) (CiliumSettings, error)
DecodeCiliumSettings reads an Encode. Empty input is the shipped configuration, which is what a cluster that predates the settings runs.
func (CiliumSettings) Encode ¶
func (s CiliumSettings) Encode() []byte
Encode is s in the one form two control planes compare: they agree on the cluster's Cilium configuration exactly when their encodings are equal.
func (CiliumSettings) IsDefault ¶
func (s CiliumSettings) IsDefault() bool
IsDefault reports whether s is the shipped configuration.