Skip to content

CRD Reference

All resources are cluster-scoped under drop.corewire.io/v1alpha1.

Quick Example

apiVersion: drop.corewire.io/v1alpha1
kind: CachedImage
metadata:
  name: nginx
spec:
  image: docker.io/library/nginx
  tag: latest
  nodeSelector:
    kubernetes.io/arch: amd64

CachedImage

CachedImage ensures a single container image is pre-cached on cluster nodes.

Controller: internal/controller/cachedimage_controller.go

Spec

FieldTypeRequiredDefaultDescription
imagestringYesImage is the fully qualified image reference without tag or digest. Example: “docker.io/library/nginx”, “registry.example.com/team/app”
tagstringNoTag to pull. Mutually exclusive with Digest. Example: “1.25-alpine”, “v2.4.1”, “latest”
digeststringNoDigest to pull as an immutable reference. Mutually exclusive with Tag. Use this for reproducible deployments where the exact image layer matters. Example: “sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4”
imagePullPolicycorev1.PullPolicyNoAlwaysImagePullPolicy controls when kubelet pulls the image on each node. - Always (default): check the registry for a newer digest even if the tag exists locally. - IfNotPresent: skip the registry check when the tag already exists on the node. - Never: never pull (only useful for pre-loaded images). (Always | IfNotPresent | Never)
imagePullSecrets[]corev1.LocalObjectReferenceNoImagePullSecrets are references to Secrets in the namespace where Drop creates pull Pods. The default namespace is “drop-system” unless the controller is started with a different –pod-namespace. The Secret must contain a .dockerconfigjson key. Example: [{name: “ghcr-creds”}, {name: “ecr-creds”}]
nodeSelectormap[string]stringNoNodeSelector restricts which nodes to cache the image on. Only nodes matching ALL key-value pairs will be targeted. Example: {“node-role.kubernetes.io/build”: “true”}
tolerations[]corev1.TolerationNoTolerations allow the pull pod to be scheduled on tainted nodes. Example: [{key: “node-role.kubernetes.io/build”, operator: “Exists”, effect: “NoSchedule”}]
priority*int32NoPriority is a pull ordering hint. Lower values are pulled first. Images with the same priority are pulled in alphabetical order. Default: 0 (no priority). Example: 10 (low priority), -10 (high priority)
policyRef*PolicyReferenceNoPolicyRef references a PullPolicy resource that controls pacing (concurrency, backoff, delays). If unset, the operator uses built-in defaults (1 concurrent node, 10s delay, 30s initial backoff). Example: {name: “conservative”}

Status

FieldTypeDescription
observedGenerationint64ObservedGeneration is the last generation reconciled.
phasestringPhase summarizes the overall state.
readystringReady is a human-readable “nodesReady/nodesTargeted” fraction for display.
resolvedDigeststringResolvedDigest is the sha256 digest of the image as reported by the container runtime after pull.
nodesTargetedint32NodesTargeted is the number of nodes that should have this image.
nodesReadyint32NodesReady is the number of nodes that have successfully pulled the image.
nodesPullingint32NodesPulling is the number of nodes currently pulling the image.
cachedNodes[]stringCachedNodes is the list of node names that have successfully cached the image.
consecutiveFailuresint32ConsecutiveFailures counts sequential reconcile failures for backoff calculation.
lastPulledAt*metav1.TimeLastPulledAt is the timestamp of the most recent successful pull.
lastAttemptedAt*metav1.TimeLastAttemptedAt is the timestamp of the most recent pull attempt (success or failure).
conditions[]metav1.ConditionConditions represent the latest available observations. Condition types: Ready, PullProgress.

CachedImageSet

CachedImageSet manages a group of images to cache, optionally backed by a DiscoveryPolicy.

Controller: internal/controller/cachedimageset_controller.go

Spec

FieldTypeRequiredDefaultDescription
policyRef*PolicyReferenceNoPolicyRef references a PullPolicy for pacing controls. Propagated to all child CachedImages. Example: {name: “conservative”}
discoveryPolicyRef*DiscoveryPolicyReferenceNoDiscoveryPolicyRef references a DiscoveryPolicy that provides a dynamic image list. When set, the operator reads status.discoveredImages from the referenced DiscoveryPolicy and creates/deletes child CachedImages accordingly. Can be combined with static images. Example: {name: “popular-build-images”}
imagePullPolicycorev1.PullPolicyNoAlwaysImagePullPolicy controls when kubelet pulls images. Propagated to all child CachedImages. Default: “Always”. See CachedImage.spec.imagePullPolicy for details. (Always | IfNotPresent | Never)
imagePullSecrets[]corev1.LocalObjectReferenceNoImagePullSecrets for private registries. Propagated to all child CachedImages. Secrets must exist in the namespace where Drop creates pull Pods (default: “drop-system”). Example: [{name: “ghcr-creds”}]
nodeSelectormap[string]stringNoNodeSelector restricts which nodes to cache images on. Propagated to all child CachedImages. Example: {“node-role.kubernetes.io/build”: “true”}
tolerations[]corev1.TolerationNoTolerations for tainted nodes. Propagated to all child CachedImages. Example: [{key: “node-role.kubernetes.io/build”, operator: “Exists”, effect: “NoSchedule”}]
images[]ImageEntryNoImages is a static list of images to cache. Each entry creates one child CachedImage. Can be used alone or combined with discoveryPolicyRef (both lists are merged).

Status

FieldTypeDescription
observedGenerationint64ObservedGeneration is the last generation reconciled.
phasestringPhase summarizes the overall state.
imagesManagedint32ImagesManaged is the number of CachedImage children managed by this set.
imagesReadyint32ImagesReady is the number of children in Ready phase.
conditions[]metav1.ConditionConditions represent the latest available observations.

DiscoveryPolicy

DiscoveryPolicy automatically discovers images from registries or Prometheus metrics.

Controller: internal/controller/discoverypolicy_controller.go

Spec

FieldTypeRequiredDefaultDescription
sources[]DiscoverySourceYesSources is the list of discovery backends to query. At least one source is required. Multiple sources are merged and ranked together before maxImages is applied.
imageFilterstringNoImageFilter is a regex applied to discovered image references. Only matching images are kept. Example: “registry.example.com/team/.*” (only keep images from that registry path)
syncIntervalmetav1.DurationNo30mSyncInterval is how often the operator re-queries all sources and updates status.discoveredImages. Default: “30m”. Example: “1h”, “15m”
maxImagesint32No50MaxImages caps the total number of images stored in status.discoveredImages. Images are ranked by score; lowest-scoring images are dropped when the cap is exceeded. Default: 50. Example: 30, 100

Status

FieldTypeDescription
lastSyncTime*metav1.TimeLastSyncTime is the timestamp of the last successful sync.
discoveredImages[]DiscoveredImageDiscoveredImages is the list of discovered images from all sources.
imageCountint32ImageCount is the number of discovered images.
sourceCountint32SourceCount is the number of configured sources.
conditions[]metav1.ConditionConditions represent the latest available observations.

PullPolicy

PullPolicy controls the pacing and retry behavior for image pulls across cluster nodes. It is a configuration-only resource with no status.

Spec

FieldTypeRequiredDefaultDescription
maxConcurrentNodesint32No1MaxConcurrentNodes is the maximum number of nodes pulling simultaneously for images that reference this policy. Increase for large clusters; keep low for bandwidth-constrained nodes. Default: 1. Example: 3 (pull on up to 3 nodes at once)
minDelayBetweenPullsmetav1.DurationNo10sMinDelayBetweenPulls is the minimum wait time between starting a pull on one node and starting the next pull on another node. Prevents burst traffic to the registry. Default: “10s”. Example: “30s”, “1m”
failureBackoff*BackoffConfigNoFailureBackoff configures exponential retry delays when a pull fails. If unset, defaults to initial=30s, max=5m.
repullInterval*metav1.DurationNoRepullInterval defines how often to re-pull already-cached images to pick up digest changes. Unset or zero means never re-pull (rely on imagePullPolicy=Always on the CachedImage instead). Example: “24h” (re-pull daily), “6h”
nodeSelectormap[string]stringNoNodeSelector scopes this policy to a specific node pool. Only relevant when the same PullPolicy should only pace pulls on a subset of nodes. Example: {“node-role.kubernetes.io/build”: “true”}
tolerations[]corev1.TolerationNoTolerations allow the pull pods created under this policy to schedule on tainted nodes. Example: [{key: “dedicated”, value: “ci”, effect: “NoSchedule”}]

Helper Types

BackoffConfig

BackoffConfig defines exponential retry backoff behavior for failed pulls.

FieldTypeRequiredDefaultDescription
initialmetav1.DurationNo30sInitial delay before the first retry attempt after a failure. Default: “30s”. Example: “1m”
maxmetav1.DurationNo5mMax is the upper bound on backoff delay. Retries will never wait longer than this. Default: “5m”. Example: “10m”

DiscoveredImage

DiscoveredImage represents a single discovered image with metadata.

FieldTypeRequiredDefaultDescription
imagestringYesImage is the fully qualified image reference.
scoreint64YesScore is the ranking score from the source (higher = more relevant).
sourcestringYesSource identifies which discovery source produced this image.

DiscoveryPolicyReference

DiscoveryPolicyReference is a reference to a DiscoveryPolicy resource.

FieldTypeRequiredDefaultDescription
namestringYesName of the DiscoveryPolicy resource.

DiscoverySource

DiscoverySource defines a single discovery backend.

FieldTypeRequiredDefaultDescription
typestringYesType identifies the discovery backend. Must be “prometheus” or “registry”.
prometheus*PrometheusSourceNoPrometheus contains the configuration when type=prometheus.
registry*RegistrySourceNoRegistry contains the configuration when type=registry.
secretRef*corev1.LocalObjectReferenceNoSecretRef references a Secret in the namespace where Drop creates pull Pods. The default namespace is “drop-system” unless the controller is started with a different –pod-namespace. Supported Secret keys: token, username, password, ca.crt, tls.crt, tls.key, headers.. Example: {name: “prometheus-creds”}

ImageEntry

ImageEntry defines a single image to include in a set.

FieldTypeRequiredDefaultDescription
imagestringYesImage is the fully qualified image reference without tag or digest. Example: “docker.io/library/nginx”, “registry.example.com/team/app”
tagstringNoTag to pull. Mutually exclusive with Digest. Example: “1.25-alpine”, “v2.4.1”
digeststringNoDigest to pull as an immutable reference. Mutually exclusive with Tag. Example: “sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4”

PolicyReference

PolicyReference is a reference to a PullPolicy resource.

FieldTypeRequiredDefaultDescription
namestringYesName of the PullPolicy resource.

PrometheusSource

PrometheusSource defines Prometheus query configuration for image discovery.

FieldTypeRequiredDefaultDescription
endpointstringYesEndpoint is the Prometheus-compatible API URL (Prometheus, Thanos, Mimir, VictoriaMetrics). Example: “http://prometheus.monitoring.svc:9090”, “https://mimir.example.com
querystringYesQuery is the PromQL expression. It MUST return results with an “image” label — that label value is used as the discovered image reference. The query result value is used as the ranking score (higher = more relevant). Example: count(container_memory_working_set_bytes{container!="",container!=“POD”,namespace=“gitlab-runner”}) by (image)
lookback*metav1.DurationNoLookback is the time window for aggregation. When set, the operator uses query_range (start=now-lookback, end=now) and sums all returned values per image to produce a score. When unset, uses an instant query (/api/v1/query) and the point-in-time value is the score. Example: “168h” (7 days), “24h”, “72h”
stepstringNo5mStep is the resolution step for range queries (only used when lookback is set). Smaller steps = more data points = more accurate sums but higher Prometheus load. Default: “5m”. Example: “1m”, “15m”

RegistrySource

RegistrySource defines OCI registry tag listing configuration for image discovery.

FieldTypeRequiredDefaultDescription
urlstringYesURL is the registry base URL (without repository path). Example: “https://registry.example.com”, “https://ghcr.io
repositories[]stringYesRepositories is the list of repository paths to list tags from. Example: [“team/app”, “team/worker”, “infra/tools”]
tagFilterstringNoTagFilter is a regex applied to tag names. Only matching tags are discovered. Example: “^v[0-9]+\.” (semver tags only), “^main-” (main branch builds)
topXint32NoTopX limits the number of tags kept per repository after tagFilter is applied. The registry API does not provide creation timestamps here; Drop keeps the last N tags returned by the registry. Example: 3 (keep the last 3 matching tags returned per repo)
imageTemplatestringNoImageTemplate is a Go text/template for constructing the full image reference from discovered tags. Available variables: {{.Registry}}, {{.Repository}}, {{.Tag}} Default (when unset): “{{.Registry}}/{{.Repository}}:{{.Tag}}” Example: “{{.Registry}}/{{.Repository}}@{{.Tag}}” (if tags are actually digests)
Last updated on