Kubernetes is a system for running many containers across many machines. GitOps is a way of managing what's deployed by storing the desired state in a Git repository and having an automated agent keep everything in sync. They go together because Kubernetes is built around declaring what you want, and GitOps extends that idea all the way back to your Git repo. If Cartara flagged this in your diff, you likely have Kubernetes configuration files (YAML manifests) or a GitOps tool like Argo CD in your stack.
Kubernetes in Plain Terms
Containers solve "package my app so it runs anywhere." But once you have many containers — multiple services, multiple copies for redundancy — you need something to orchestrate them: decide which machine each container runs on, restart them when they crash, scale them up under load, and route traffic to them. That's Kubernetes (often written K8s).
You describe what you want in YAML files called manifests:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 3 # Run 3 copies
selector:
matchLabels:
app: my-api
template:
spec:
containers:
- name: my-api
image: myrepo/my-api:v1.2.0
resources:
requests:
memory: "256Mi"
cpu: "250m"
```
- name: my-api
Kubernetes reads this and works to make reality match: start 3 containers, keep them running, restart any that crash, spread them across available machines.
The honest caveat for small teams: Kubernetes is powerful and complex. It's the right tool when you're running many services at scale across a team. For a single app, a managed platform like Vercel, Railway, Render, or your cloud's container service is simpler and entirely sufficient. Don't adopt Kubernetes because it sounds impressive — adopt it when you feel the actual pain it solves.
What GitOps Adds
Kubernetes is declarative — you describe desired state in YAML. GitOps takes the next logical step: store that desired state in Git, and have a controller running inside the cluster continuously pull from Git and apply changes automatically.
The workflow becomes:
- You update a YAML file (changing a container image version, scaling up replicas) and open a pull request.
- The change is reviewed and merged — normal Git workflow.
- A GitOps controller running in the cluster notices the change in Git and applies it automatically.
Crucially, this is pull-based: the cluster pulls changes to itself from Git, rather than your CI pipeline pushing changes into the cluster.
Push vs. Pull — and Why Pull Is Better
Traditional CI/CD pipelines push to your environment: the pipeline has credentials to log into your cluster and run deploy commands. In GitOps, the pipeline's job ends at building the container image. A controller inside the cluster handles the actual deployment.
Benefits:
Tighter security. Your CI system doesn't need cluster admin credentials. Nothing external needs deploy access to your production environment.
Self-healing. If someone manually changes something in the live cluster (a common mistake), the GitOps controller notices the drift from Git and reverts it. Git always wins.
Git is your audit log and rollback. Every deployment is a commit. Rolling back is git revert. You can always see exactly what's deployed, when it changed, and who approved it.
The Main Tools
Both leading GitOps tools are mature, well-supported open-source projects that run as controllers inside Kubernetes:
| Tool | Character |
|---|---|
| Argo CD | The majority choice — used in roughly 60% of Kubernetes clusters. Centralized model with a web UI, role-based access control, and good visibility into what's deployed. The friendlier starting point. |
| Flux | Decentralized, no central server or UI by default. Lightweight and fully code-driven. Favored by teams who want everything managed as code with no extra dashboard to maintain. |
Both continuously reconcile your Git repository to your cluster. Argo CD's visual interface makes it easier to see what's happening, which is why most teams start there.
What You'll See in Your Code
A typical GitOps repository structure separates application code from deployment configuration:
```
my-app/
├── src/ # Application code
├── Dockerfile
└── k8s/ # Kubernetes manifests
├── deployment.yaml
├── service.yaml
└── ingress.yaml
gitops-config/ # Separate repo Argo CD watches
└── apps/
└── my-app/
├── deployment.yaml # References specific image tag
└── kustomization.yaml
```
When your CI pipeline builds a new container image, it updates the image tag in the GitOps config repo. Argo CD or Flux detects the change and rolls out the update.
How It Connects to Everything Else
GitOps depends on declarative infrastructure — the whole model only works because the desired state is expressed in files. It's an evolution of the deploy stage in CI/CD, and pairs naturally with deployment strategies like canary releases and rolling updates, which Kubernetes supports natively. Because every change is a reviewed commit, GitOps also strengthens your supply chain security.
Do You Need This?
If you're not running Kubernetes, you don't need GitOps in this specific form. If you are adopting Kubernetes for a multi-service setup, GitOps with Argo CD is close to the standard way to manage it well. For a single application, this is firmly a "later" concern — understand that it exists and revisit when your deployment complexity actually demands it.