5.4 KiB
OCI Artifacts with Flux (2024-2025)
Overview
GA Status: Flux v2.6 (June 2025) Current: Fully supported in Flux v2.7
OCI artifacts allow storing Kubernetes manifests, Helm charts, and Kustomize overlays in container registries instead of Git.
Benefits
✅ Decoupled from Git: No Git dependency for deployment ✅ Immutable: Content-addressable by digest ✅ Standard: Uses OCI spec, works with any OCI registry ✅ Signature Verification: Native support for cosign/notation ✅ Performance: Faster than Git for large repos
OCIRepository Resource
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OC IRepository
metadata:
name: my-app-oci
namespace: flux-system
spec:
interval: 5m
url: oci://ghcr.io/org/app-config
ref:
tag: v1.0.0
# or digest:
# digest: sha256:abc123...
# or semver:
# semver: ">=1.0.0 <2.0.0"
provider: generic # or azure, aws, gcp
verify:
provider: cosign
secretRef:
name: cosign-public-key
Using with Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
spec:
interval: 10m
sourceRef:
kind: OCIRepository
name: my-app-oci
path: ./
prune: true
Using with HelmRelease
OCIRepository for Helm charts:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: podinfo-oci
spec:
interval: 5m
url: oci://ghcr.io/stefanprodan/charts/podinfo
ref:
semver: ">=6.0.0"
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: podinfo
spec:
chart:
spec:
chart: podinfo
sourceRef:
kind: OCIRepository
name: podinfo-oci
Publishing OCI Artifacts
Using flux CLI:
# Build and push Kustomize overlay
flux push artifact oci://ghcr.io/org/app-config:v1.0.0 \
--path="./kustomize" \
--source="$(git config --get remote.origin.url)" \
--revision="$(git rev-parse HEAD)"
# Build and push Helm chart
flux push artifact oci://ghcr.io/org/charts/myapp:1.0.0 \
--path="./charts/myapp" \
--source="$(git config --get remote.origin.url)" \
--revision="$(git rev-parse HEAD)"
Signature Verification
Using cosign
Sign artifact:
cosign sign ghcr.io/org/app-config:v1.0.0
Verify in Flux:
spec:
verify:
provider: cosign
secretRef:
name: cosign-public-key
Using notation
Sign artifact:
notation sign ghcr.io/org/app-config:v1.0.0
Verify in Flux:
spec:
verify:
provider: notation
secretRef:
name: notation-config
Workload Identity
Instead of static credentials, use cloud provider workload identity:
AWS IRSA:
spec:
provider: aws
# No credentials needed - uses pod's IAM role
GCP Workload Identity:
spec:
provider: gcp
# No credentials needed - uses service account binding
Azure Workload Identity:
spec:
provider: azure
# No credentials needed - uses managed identity
Best Practices (2025)
-
Use digest pinning for production:
ref: digest: sha256:abc123... -
Sign all artifacts:
flux push artifact ... | cosign sign -
Use semver for automated updates:
ref: semver: ">=1.0.0 <2.0.0" -
Leverage workload identity (no static credentials)
-
Prefer OCI for generated configs (Jsonnet, CUE, Helm output)
When to Use OCI vs Git
Use OCI Artifacts when:
- ✅ Storing generated configurations (Jsonnet, CUE output)
- ✅ Need immutable, content-addressable storage
- ✅ Want signature verification
- ✅ Large repos (performance)
- ✅ Decoupling from Git
Use Git when:
- ✅ Source of truth for manifests
- ✅ Need Git workflow (PRs, reviews)
- ✅ Audit trail important
- ✅ Team collaboration
Common Pattern: Hybrid Approach
Git (source of truth)
↓
CI builds/generates manifests
↓
Push to OCI registry (signed)
↓
Flux pulls from OCI (verified)
↓
Deploy to cluster
Migration from Git to OCI
Before (Git):
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
spec:
url: https://github.com/org/repo
ref:
branch: main
After (OCI):
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: my-app-oci
spec:
url: oci://ghcr.io/org/app-config
ref:
tag: v1.0.0
Update Kustomization/HelmRelease sourceRef to point to OCIRepository
Supported Registries
- ✅ GitHub Container Registry (ghcr.io)
- ✅ Docker Hub
- ✅ AWS ECR
- ✅ Google Artifact Registry
- ✅ Azure Container Registry
- ✅ Harbor
- ✅ GitLab Container Registry
Troubleshooting
Artifact not found:
flux get sources oci
kubectl describe ocirepository <name>
# Verify artifact exists
crane digest ghcr.io/org/app:v1.0.0
Authentication failures:
# Check secret
kubectl get secret -n flux-system
# Test manually
crane manifest ghcr.io/org/app:v1.0.0
Signature verification fails:
# Verify locally
cosign verify ghcr.io/org/app:v1.0.0
# Check public key secret
kubectl get secret cosign-public-key -o yaml
2025 Recommendation
Adopt OCI artifacts for:
- Helm charts (already standard)
- Generated manifests (CI output)
- Multi-environment configs
Keep Git for:
- Source manifests
- Infrastructure definitions
- Team collaboration workflows