Flux v2
repository·main·Indexed 11 days ago
https://github.com/fluxcd/flux2A CNCF graduated project for keeping Kubernetes clusters in sync with configuration sources like Git repositories and OCI artifacts via GitOps. It features the GitOps Toolkit, a set of composable APIs and controllers including Source, Kustomize, Helm, Notification, and Image Automation controllers. Supports advanced synchronization patterns such as Impersonation, Remote Apply, and OCI Helm repository authentication.
What's inside Flux
- The GitOps Toolkit is the core runtime of Flux v2. It consists of a set of composable APIs and specialized controllers that run on Kubernetes. These APIs are exposed as Kubernetes Custom Resources (CRDs), which users or automation tools can create and update to drive continuous delivery. The toolkit is designed to be extensible, allowing developers to build their own continuous delivery systems on top of its components.
Use the Artifact Digest field
mainThe
Digestfield in thesource.toolkit.fluxcd.iogroup'sArtifacttype contains the checksum of the file advertised in thePath, prefixed by the algorithm alias. This field is intended to replace the deprecatedChecksumfield.Format:
<algo>:<checksum>Example:
sha256:1111f92aba67995f108b3ee3ffdc00edcfe206b11fbbb459c8ef4c4a8209fca8
sha256:1111f92aba67995f108b3ee3ffdc00edcfe206b11fbbb459c8ef4c4a8209fca8Resilient Span Management in Flux Tracing
mainFlux's OpenTelemetry implementation is designed to handle the asynchronous and potentially unreliable nature of distributed controllers. It ensures trace continuity through two main mechanisms:
- Asynchronous Event Processing: The system does not assume events arrive in sequential order. Each event independently calculates its Trace ID to either locate an existing parent span or create a new root span.
- Fault Tolerance & Recovery: If the
notification-controllerexperiences downtime or latency, it uses a recovery mechanism during event processing:- It attempts to locate an existing root span using the calculated ID.
- If the root span is found, the new span is attached as a child.
- If the root span is not found (due to out-of-order arrival or previous failures), it automatically creates a new root span to ensure the event is still traced.
This approach maintains a coherent span hierarchy even when controllers are stateless or events are delayed.
Implement Multi-Tenant Workload Identity using ServiceAccounts
mainTo support multi-tenant workload identity at the object level, Flux associates Flux resources (like
OCIRepository,GitRepository,Bucket,Kustomization, etc.) with KubernetesServiceAccounts.By specifying a
serviceAccountNamein the resource'sspec, the Flux controller can exchange a token for thatServiceAccountfor a short-lived cloud provider access token. This allows different tenants to have isolated permissions for cloud resources (e.g., different AWS IAM roles or GCP Service Accounts) even when using the same Flux controllers.Key Requirements:
- The Flux controller's
ServiceAccountmust have RBAC permissions to create tokens for otherServiceAccountsin the cluster. - The target
ServiceAccountmust be annotated with the appropriate cloud provider identity metadata (e.g., AWS IAM role ARN, Azure Client ID, or GCP Service Account email).
# Example: Associating an OCIRepository with a specific ServiceAccount apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: OCIRepository metadata: name: tenant-a-repo namespace: tenant-a spec: provider: aws serviceAccountName: tenant-a-ecr-sa --- apiVersion: v1 kind: ServiceAccount metadata: name: tenant-a-ecr-sa namespace: tenant-a annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789123:role/tenant-a-ecr- The Flux controller's
Understand Flux CLI plugin discovery and execution
mainThe Flux CLI uses a plugin system that integrates directly into the existing command structure:
- Discovery: On startup, the CLI scans the plugin directory (or the path in
FLUXCD_PLUGINS). It performs a lightweight scan of directory entries and metadata. No plugin binaries are executed during this discovery phase. - Registration: Discovered plugins are registered as Cobra subcommands. Built-in Flux commands always take priority over plugin commands if names collide.
- Execution: Plugins are standalone binaries. They do not support dependencies; each plugin must be self-contained.
- Shell Completion: The system supports shell completion via the Cobra
__completeprotocol.
- Discovery: On startup, the CLI scans the plugin directory (or the path in
Understand the technical basis of Kubernetes workload identity
mainWorkload identity relies on OpenID Connect (OIDC) discovery. The Kubernetes API acts as an OIDC issuer, providing a discovery document at
https://kubernetes.default.svc.cluster.local/.well-known/openid-configurationand a JSON Web Key Set (JWKS) at the URI specified in that document.Cloud providers (AWS, GCP, Azure) use these endpoints to verify the
sub(subject) claim in a KubernetesServiceAccounttoken. This allows the cloud provider's Security Token Service (STS) to exchange the Kubernetes token for a short-lived cloud access token.Key differences in implementation:
- GCP: Can host the JWKS document directly in IAM, and GKE automatically manages the trust relationship.
- AWS: Requires the issuer URL to be reachable by AWS STS; EKS users must manually create an OIDC provider for each cluster (unless using EKS Pod Identity, which is not supported for Flux multi-tenant identity).
- Azure: Typically uses token volume projection where the kubelet mounts a rotating token file into the pod.
Use Remote Apply for multi-cluster synchronization
mainThe Kustomize and Helm controllers can apply configurations to a cluster other than the one they are running in. To do this, provide a Secret containing a valid
kubeconfigfile in theKustomizationorHelmReleaseobject.When using Remote Apply, the controller uses the identity provided in the
kubeconfigto perform all operations (including impersonation and health-checks). The permissions applied will be those of the user defined in thatkubeconfig.Format the Artifact Revision field
mainThe
Revisionfield of anArtifactcan represent either a named pointer or a specific content digest.- Digest only: Use the format
<algo>:<checksum>(e.g.,sha256:abcdef...). - Named pointer with Digest: Use the format
<named pointer>@<algo>:<checksum>. The@symbol acts as the separator between the pointer and the digest.
Parsing Logic: When extracting a digest, Flux treats everything after the last
@character as the digest, and everything preceding it as the named pointer.Truncation Rules: When displaying in limited UI spaces, the
<checksum>part may be truncated to 7 or more characters, but the<algo>part must never be truncated.[ <named pointer> ] [ [ "@" ] <algo> ":" <checksum> ]- Digest only: Use the format
How Trace Identity and Correlation work in Flux
mainFlux uses a deterministic approach to generate Trace IDs to ensure reliable correlation across multiple controllers in a stateless, distributed environment. This allows events from different controllers (like
GitRepositoryandKustomization) to be grouped into a single coherent trace view in your tracing backend.Trace ID Generation
The Trace ID is created by concatenating two specific values and passing them through a checksum algorithm (SHA-256 by default):
- Alert Object UID: A unique identifier guaranteed by Kubernetes.
- Source's revision ID: Extracted from event payloads (e.g., a Git commit SHA).
Trace Lifecycle Example
- A
GitRepositoryreconciliation event occurs with a specific revision. Thenotification-controllercaptures this, calculates the Trace ID, and starts a new trace/span. - A
Kustomizationthen acts on that same revision. It calculates the same Trace ID, allowing it to attach its span as a child of the original trace. - The tracing backend displays all these spans as a single, continuous trace.
# Input values Alert UID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" Source Revision: "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" # Concatenated value format: # "<Alert-UID>:<source-revision>" # "a1b2c3d4-e5f6-7890-abcd-ef1234567890:sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" # Resulting Trace ID (after SHA-256): # "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650"Use Impersonation to control sync permissions
mainThe Kustomize and Helm controllers can apply Kubernetes configurations using a specific service account instead of the controller's own service account. This is achieved by setting the
.spec.serviceAccountNamefield in aKustomizationorHelmReleaseobject.Security Warning: If this field is left empty, the controller defaults to its own service account. In default Flux installations, this service account has
cluster-adminprivileges. To prevent privilege escalation in multi-tenant environments, consider using an admission controller (like Kyverno) to make.spec.serviceAccountNamemandatory.# Example: Kustomization using impersonation apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 kind: Kustomization metadata: name: my-app namespace: my-namespace spec: serviceAccountName: my-limited-sa # This enables impersonation # ... other spec fieldsRestrict ImagePolicy access with accessFrom
mainWhen anImagePolicyrefers to anImageRepositoryin a different namespace, Flux applies an additional layer of security. Access is denied by default unless theImageRepositoryexplicitly grants permission to the requesting namespace using the.spec.accessFromfield.How the Flux RFC process works
mainThe Request for Comments (RFC) process is used for substantial changes to Flux, such as API additions, breaking changes, security updates, or impactful UX changes. This process ensures a consistent and controlled path for evolution through public discussion and maintainer review.
Substantial changes include:
- API additions (new resource kinds or relationships).
- API breaking changes (field removals or new required fields).
- Security-related changes (permissions, tenant isolation, impersonation).
- Impactful UX changes (e.g., new required inputs to the bootstrap process).
- Dropping capabilities (e.g., sunsetting external service integrations).
The workflow follows these steps:
- Discussion: Propose the idea via GitHub Discussions and seek feedback at weekly dev meetings.
- Sponsorship: You must find a maintainer willing to sponsor your RFC.
- Submission: Open a pull request using the RFC-0000 template.
- Review: The sponsor labels the PR with
area/RFCand initiates a review. At least two maintainers must approve the proposal. - Finalization: An RFC number is assigned, and the branch must be rebased with
mainbefore merging. - Implementation: Once merged, the proposal is implemented. Progress is tracked using the RFC number as a prefix for issues and PRs.