Console Login

GitOps in 2025: Stop 'kubectl apply' and Start Sleeping at Night

GitOps Protocols for High-Stakes Production Environments

If you are still SSHing into servers to pull code, or running kubectl apply -f . from your laptop, you are the single greatest risk to your company's uptime. I've spent the last decade cleaning up after "cowboy deployments" where a single typo in a YAML file took down critical payment gateways in Oslo. It stops today.

By December 2025, GitOps isn't just a buzzword; it is the baseline for survival. The concept is simple: Git is the single source of truth. If it's not in the repo, it doesn't exist in the cluster. This approach solves configuration drift, provides an instant audit trail for auditors (like Datatilsynet), and perhaps most importantly, lets you revert a catastrophic failure with a simple git revert.

The Architecture: Pull vs. Push

In the old days (circa 2020), we relied heavily on CI pipelines pushing changes to clusters. This required giving your CI runner (often hosted in the US or a random cloud) admin credentials to your production environment in Norway. From a security standpoint, this is a nightmare.

The standard in 2025 is the Pull Model. An agent inside your cluster (ArgoCD or Flux v2) watches the Git repository. When it detects a change, it pulls the new state and applies it. No inbound ports open, no cluster credentials exposed to the CI server.

Pro Tip: When hosting in Norway to comply with strict GDPR or data residency requirements, the Pull Model ensures that external CI systems (which might process metadata abroad) never touch the internal state of your cluster directly.

Structuring Your Repository for Sanity

I have seen teams bury themselves by mixing application source code with infrastructure manifests. Don't do it. Use a separate repository for your infrastructure (config repo). Within that, Kustomize is the standard for managing environment differences without duplicating thousands of lines of YAML.

Here is the directory structure that scales from a single CoolVDS instance to a multi-region cluster:

β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ base/
β”‚   β”‚   β”œβ”€β”€ deployment.yaml
β”‚   β”‚   β”œβ”€β”€ service.yaml
β”‚   └── overlays/
β”‚       β”œβ”€β”€ dev/
β”‚       β”‚   β”œβ”€β”€ kustomization.yaml
β”‚       β”‚   └── patch-replicas.yaml
β”‚       └── prod/
β”‚           β”œβ”€β”€ kustomization.yaml
β”‚           └── patch-resources.yaml
β”œβ”€β”€ cluster-config/
β”‚   β”œβ”€β”€ namespaces.yaml
β”‚   └── quotas.yaml

The Engine: ArgoCD Configuration

ArgoCD has won the UI war, while Flux is often preferred for headless setups. For teams managing complex state, the visual feedback of ArgoCD is invaluable. However, simply installing it isn't enough. You need to configure it to handle high-availability requirements.

Here is a production-grade Application manifest. Notice the sync policyβ€”we automate the sync but require manual approval for pruning (deleting) resources in production to prevent accidents.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nordic-payment-gateway
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'git@github.com:my-org/infra-repo.git'
    targetRevision: HEAD
    path: apps/overlays/prod
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: payments
  syncPolicy:
    automated:
      prune: false
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Secrets Management: The "Check It In" Paradox

You cannot check raw secrets into Git. If you do, your repository is burned. In 2025, the debate is largely between External Secrets Operator (fetching from Vault/AWS Secrets Manager) and Sealed Secrets (asymmetric encryption).

For a lean setup on a VPS where you want self-sufficiency, Bitnami's Sealed Secrets is unbeatable. You encrypt the secret with a public key locally, commit the encrypted YAML, and only the controller inside the cluster (which holds the private key) can decrypt it.

Encrypting a Secret

# Create a raw secret (never commit this)
kubectl create secret generic db-creds \
  --from-literal=password=SuperSecureP@ssw0rd \
  --dry-run=client -o yaml > secret.yaml

# Seal it (safe to commit)
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml

The resulting sealed-secret.yaml looks like this and is safe for public repositories:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: db-creds
  namespace: payments
spec:
  encryptedData:
    password: AgBy3......==
  template:
    metadata:
      name: db-creds

Infrastructure Performance: The Hidden Bottleneck

Here is the uncomfortable truth: GitOps controllers are resource hogs.

ArgoCD and Flux constantly poll your Git repositories and query the Kubernetes API server to calculate diffs. On a cheap, oversold VPS with "noisy neighbors," this results in reconciliation loops that hang. I've seen ArgoCD UI freeze for 30 seconds because the underlying hypervisor was stealing CPU cycles.

This is where hardware choice becomes architectural. When we deploy control planes on CoolVDS, we rely on the KVM virtualization to guarantee that our reserved CPU cores are actually ours. Furthermore, the NVMe storage is critical. Kubernetes relies heavily on etcd, which is extremely sensitive to disk write latency. If your disk fsync latency spikes, your entire cluster becomes unstable.

Benchmarking Etcd Readiness

Before installing your GitOps operator, verify your storage speed. On a CoolVDS instance, we expect these results:

fio --rw=write --ioengine=sync --fdatasync=1 \
    --directory=test-data --size=22m --bs=2300 \
    --name=mytest

If your 99th percentile fsync latency is above 10ms, your GitOps workflow will be sluggish. Our benchmarks on CoolVDS consistently show sub-2ms latency, which is why we recommend it for production control planes.

Compliance and Recovery

In Norway, data sovereignty is paramount. By hosting your GitOps controller on a local VPS (like CoolVDS in Oslo), you ensure that the "brain" of your infrastructure resides within legal jurisdiction. Additionally, GitOps provides the ultimate Disaster Recovery plan.

If your datacenter burns down, you spin up a new CoolVDS instance, install Kubernetes and ArgoCD, point it at your Git repo, and go grab a coffee. By the time you return, your entire infrastructure state is restored. No manual config restoration, no missing scripts.

Flux v2 Kustomization Example

For those preferring Flux, here is how you enforce that reconciliation loop:

apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: backend
  namespace: flux-system
spec:
  interval: 5m0s
  sourceRef:
    kind: GitRepository
    name: infra-src
  path: ./apps/backend/prod
  prune: true
  wait: true
  timeout: 3m0s

Final Thoughts

GitOps is not optional for serious engineering teams in 2025. It separates the amateurs from the professionals. It gives you stability, security, and an audit trail that makes compliance lawyers weep with joy. But software is only as good as the hardware it runs on.

Don't let a 2€ budget VPS sabotage your Kubernetes cluster. Deploy your GitOps control plane on infrastructure that respects your need for raw I/O and CPU stability.

Ready to stabilize your stack? Deploy a high-performance CoolVDS KVM instance in Oslo today and push your first commit.