GitOps is an operating model for managing declarative systems through version-controlled desired state and automated reconciliation. For Kubernetes teams, that usually means application manifests, Helm values, Kustomize overlays, policy, or infrastructure configuration are stored in Git, while a controller such as Argo CD or Flux compares the repository’s declared state with the live cluster and works to remove drift.
The current KCNA curriculum includes cloud native application delivery and GitOps concepts because Kubernetes is already a declarative platform. The model becomes easier to understand once teams stop thinking of GitOps as “CI/CD with Git” and focus on four ideas: declarative state, version history, automated pulling, and continuous reconciliation.
Start with a declarative desired state
GitOps assumes the managed system can be described declaratively. Instead of writing a script that says “create a Deployment, then change this Service, then patch this ConfigMap,” a manifest describes what those objects should look like. Kubernetes controllers already work this way: they compare desired and actual state and take action to converge.
Declarative configuration improves review because the repository shows the intended end state. It also makes rebuilds easier. A new cluster can apply the same versioned state instead of relying on an operator to remember a sequence of commands.
Not every operational task belongs in Git. One-time forensic actions, emergency debugging, and secret values may need different handling. The principle applies to durable desired state.
Keep desired state versioned and reviewable
Git provides history, authorship, branches, pull requests, and review. Those properties make configuration changes auditable. A production deployment can be traced to a commit that explains what changed, who approved it, and which automated checks passed.
Repository structure should make ownership clear. Application source and deployment configuration can live together or separately, but teams need an explicit promotion workflow. Separate configuration repositories are common because deployment state has a different lifecycle and permission model from application code.
Protect important branches, require review for production changes, and use automated validation. Version control is only a governance mechanism if bypassing it is difficult.
Prefer pull-based reconciliation for cluster changes
Traditional deployment pipelines often hold cluster credentials and push changes directly with kubectl or another client. In a GitOps model, an in-cluster or trusted controller pulls the desired state and reconciles it. This reduces the need to expose powerful cluster credentials to many CI systems.
Argo CD describes itself as a declarative GitOps continuous delivery tool for Kubernetes. Flux follows a similar reconciliation model with controllers that watch sources and apply desired state. The controller becomes the deployment operator, while Git becomes the reviewed source of truth.
Pull-based does not mean CI disappears. CI still builds, tests, scans, and publishes artifacts. The handoff changes: CI updates or proposes a desired-state change, and the GitOps controller applies it.
Use reconciliation to detect and correct drift
Continuous reconciliation is what separates GitOps from simply storing YAML in a repository. The controller compares live resources with desired state and reports or corrects differences. If someone manually changes a Deployment in the cluster, the system can identify that drift.
Teams need to decide whether reconciliation is automatic or requires approval for certain resources. Aggressive auto-sync is useful for predictable application workloads, while sensitive infrastructure changes may require stronger gates.
Manual emergency changes should have a path back into Git. Otherwise the next reconciliation may undo the fix, or the repository may remain permanently inconsistent with production.
Separate CI responsibilities from CD responsibilities
Continuous integration should produce trusted artifacts: run tests, build a container image, scan it, sign it where required, and publish it to a registry. Continuous delivery through GitOps should define which artifact version belongs in which environment and let reconciliation perform the deployment.
This separation improves traceability. A commit in the application repository produces image digest X. A reviewed configuration commit changes production to digest X. The cluster controller applies it. Each stage has a clear record.
The broader comparison in DevOps and security-oriented delivery models is relevant because GitOps does not eliminate security responsibility; it gives teams a structured place to enforce policy and review change.
Design repository structure around teams and environments
A GitOps repository should be understandable to the people who operate it. Common patterns separate base application manifests from environment-specific overlays or values. Development, staging, and production may reference the same base but select different replica counts, URLs, or feature flags.
Avoid copying entire manifest trees for each environment when a small overlay can express the difference. Duplicated configuration drifts quickly and makes fixes repetitive. At the same time, do not create an abstraction so clever that only one engineer can understand how production is assembled.
Repository permissions should reflect deployment authority. Developers may propose production changes, while a platform or service owner approves them. The Git review process can encode that separation of duties.
Handle secrets outside ordinary Git history
Plaintext secrets do not belong in normal Git repositories. Even if a secret is deleted later, it can remain in history. Kubernetes Secrets are only an API object format and do not solve repository exposure by themselves.
GitOps teams commonly use external secret stores, encrypted-secret workflows, or controllers that retrieve sensitive values at runtime. The repository can contain references or encrypted material while authorization remains with the secret-management system.
Choose a method that supports rotation, auditing, environment separation, and disaster recovery. Secret handling should fit the same declarative operating model without exposing credentials to every repository reader.
Use policy and validation before reconciliation reaches production
Automated deployment increases the importance of automated checks. Validate Kubernetes schemas, run policy-as-code, scan container references, check resource limits, and verify environment-specific rules before a merge becomes deployable state.
Admission controls can provide another enforcement layer in the cluster. Repository checks prevent invalid changes from being approved; admission policy prevents unsafe resources from being created even if another path reaches the API.
The two layers reduce dependence on perfect human review. GitOps should make safe changes easier and unsafe changes harder.
Plan rollbacks as version-control operations
Because desired state is versioned, rollback can often be expressed as reverting a commit or changing an artifact reference back to a known-good version. The GitOps controller then reconciles the cluster to that state.
Rollback is not always simple for stateful systems. A previous application version may not understand a newly migrated database schema. Release design must consider data compatibility, feature flags, and irreversible external side effects.
Test rollback paths before production incidents. A version history is valuable only when the application architecture can safely use it.
Operate GitOps controllers as critical platform components
GitOps controllers require monitoring, access control, repository connectivity, and backup of their configuration. If the controller loses access to Git, reconciliation stops. If its credentials are overprivileged, a compromise can affect many workloads.
Observe sync status, reconciliation errors, source failures, and drift. Define who owns the controller and how emergency changes are handled when the normal delivery path is unavailable.
Promotion between environments should be visible in Git history. A tested image may first be referenced in development, then staging, then production through reviewed configuration changes. Avoid hidden environment switches in a CI system that leave no durable record of which version was approved. Promotion is a change to desired state and belongs in the same audit trail.
Multi-cluster GitOps needs clear ownership boundaries. A central platform repository can define shared add-ons and policy, while application teams own namespace-scoped configuration in separate repositories. Controllers can reconcile different sources into different clusters. The design should prevent one team’s repository from gaining unintended authority over another team’s environment.
Drift should be classified, not merely corrected. Some drift indicates unauthorized manual change, some comes from controllers that legitimately mutate resources, and some comes from generated fields that should not be compared. Configure ignore rules carefully so the system remains sensitive to meaningful differences without producing constant false alarms.
Progressive delivery can sit beside GitOps. A configuration change can declare a new version while a rollout controller gradually shifts traffic, evaluates health, and pauses or rolls back if metrics degrade. Git remains the desired-state record, while specialized controllers manage safe transition from old to new state.
Observability should expose repository revision, sync status, last reconciliation time, and health for each managed application. During an incident, operators need to know whether the live cluster matches the expected commit and whether reconciliation is failing because of an invalid manifest, unreachable repository, admission rejection, or runtime health problem.
Disaster recovery should include the GitOps control plane. Repositories contain desired state, but clusters also rely on controller configuration, repository credentials, signing keys, and bootstrap procedures. Document how a replacement cluster would install the controller, authenticate to sources, and reconcile foundational platform services before application workloads.
Application teams and platform teams should agree on ownership boundaries. Platform teams may manage namespaces, ingress controllers, policy, observability, and base configuration, while application teams manage Deployments, Services, and application-specific ConfigMaps. Repositories and controller permissions should reflect those boundaries so one team’s change cannot unintentionally modify another team’s platform layer.
Generated configuration needs care. Helm and Kustomize can reduce duplication, but operators should still be able to determine the rendered state that will reach the cluster. Validate rendered manifests in CI and make differences visible during review. Abstraction should not hide the actual resource changes from approvers.
Policy for manual access is still required. Even in a strong GitOps environment, cluster administrators may need direct API access for emergencies. Record those interventions, limit who can perform them, and reconcile the final intended state back into Git after the incident so emergency work does not become permanent unmanaged drift.
Repository availability is part of deployment availability. Controllers may continue running the last applied state when Git is unreachable, but new changes and reconciliation against the source can stop. Use reliable hosting, backup important repositories, and understand how controllers behave during source outages.
Audit GitOps credentials like any other production secret. Repository deploy keys, controller tokens, and cluster permissions should be scoped, rotated, and separated by environment where practical. The automation path is powerful precisely because it can change many resources consistently.
Git history is not a substitute for release notes. Important production changes should still communicate user impact, migration requirements, and rollback constraints so operators understand the meaning of a commit rather than only its diff.
Keep bootstrap instructions outside individual memory. New operators should be able to reconstruct the delivery path from documented repositories, credentials, policies, and controller dependencies.
Document who may pause reconciliation and who may resume it.
For teams across the CNCF ecosystem, GitOps is best understood as a control loop: desired state is declarative, stored with version history, pulled by software agents, and continuously reconciled. Kubernetes already uses controllers internally; GitOps extends that pattern to the way teams operate application and platform configuration.