Mastering GitOps Workflows in 2025: From "Click-Ops" Chaos to Immutable Infrastructure
If you are still SSHing into servers to run docker-compose up or manually firing kubectl apply from your laptop, you are actively sabotaging your infrastructure. I have seen production clusters in Oslo fail during Black Friday traffic not because of load, but because a junior dev applied a hotfix manually three months prior that was overwritten by the CI pipeline.
Manual operations—"Click-Ops"—is the enemy of stability. In 2025, the standard for managing infrastructure in Norway and across Europe is GitOps. It is not just a buzzword; it is the rigorous application of version control to infrastructure state.
This guide isn't about theory. We are going to build a reconciliation loop that enforces state, handles secrets securely under Norwegian privacy standards, and leverages high-performance infrastructure to minimize convergence time.
The Architecture: Pull vs. Push
Traditionally, CI/CD pipelines (Jenkins, GitLab CI) utilized a "Push" model. The CI runner had full cluster-admin access to your production environment to deploy changes. From a security standpoint, this is a nightmare. If your CI provider is compromised, your entire production environment is exposed.
GitOps utilizes a "Pull" model. An agent inside the cluster (the controller) monitors a Git repository. When it detects a change (commit), it pulls the manifest and applies it. The cluster creates the connection outbound; no external entity needs admin access to your K8s API.
Pro Tip: For Norwegian companies adhering to strict Datatilsynet requirements, the Pull model is superior. It keeps the "act" of deployment within your sovereign infrastructure (e.g., a CoolVDS instance in Oslo) rather than an external SaaS runner.
Tooling Selection: ArgoCD on KVM
While Flux v2 is excellent for headless operations, ArgoCD remains the industry standard for visibility. However, running a GitOps controller requires resources. It is constantly hashing Git repos, caching manifests, and querying the Kubernetes API.
I strictly advise against running your control plane on shared, oversold VPS hosting. If your etcd latency spikes due to a noisy neighbor, your reconciliation loops stall. We use CoolVDS KVM instances because the NVMe I/O isolation ensures the controller can process hundreds of application manifests without lag.
Step 1: The Bootstrap
Let's install ArgoCD. Do not use the default manifest blindly. We need high availability (HA) if this is production.
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.12.0/manifests/ha/install.yaml
Once running, we define an AppProject. This is crucial for multi-tenant isolation, restricting what the Argo application can actually touch.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production-core
namespace: argocd
spec:
description: "Production Core Infrastructure"
sourceRepos:
- "https://github.com/your-org/infra-live.git"
destinations:
- namespace: "prod-*"
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: '*'
kind: '*'
Handling Secrets: The "No Text" Rule
You cannot check passwords into Git. In 2025, the debate is largely between External Secrets Operator (fetching from Vault/AWS SSM) and SOPS (Mozilla's Sealed Operations). For a lean, latency-sensitive setup on CoolVDS, I prefer SOPS with Age encryption. It allows you to store encrypted secrets in Git that are decryptable only by the cluster key.
Here is how a SOPS encrypted file looks before the controller decrypts it:
apiVersion: v1
kind: Secret
metadata:
name: database-creds
stringData:
# ENC[AES256_GCM,data:...] indicates encrypted payload
password: ENC[AES256_GCM,data:supersecret...]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1...
enc: |
-----BEGIN AGE ENCRYPTED FILE-----...
The CI Pipeline: Updating the State
Your CI pipeline (GitHub Actions, GitLab CI) effectively stops at "Build and Push Docker Image." Its final step is not helm upgrade, but rather a Git commit to the infrastructure repository updating the image tag.
Here is a battle-hardened script snippet to handle the semantic versioning update safely:
name: Update Manifests
run: |
git config user.name "CoolVDS-Bot"
git config user.email "ops@coolvds.com"
cd k8s-manifests/overlays/production
# Kustomize edit to update the tag precisely
kustomize edit set image backend-api=eu.gcr.io/myorg/backend:${{ github.sha }}
git add kustomization.yaml
git commit -m "chore: deploy backend ${{ github.sha }}"
git push origin main
Performance Tuning: Reducing Drift Latency
By default, ArgoCD polls Git every 3 minutes. In a high-velocity environment, that is too slow. You can configure Webhooks from GitHub/GitLab to trigger an instant refresh, but the controller must be able to handle the burst.
This is where infrastructure choice dictates success. On a CoolVDS instance with dedicated CPU cores, we can tune the repo-server to handle high concurrency without CPU throttling (steal time). If you are on cheap shared hosting, increasing these limits will often get your instance flagged or throttled by the hypervisor.
Optimize your argocd-cm ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
timeout.reconciliation: "180s"
# High performance setting for CoolVDS NVMe instances
reporpo.server.parallelism.limit: "50"
status.processors: "20"
Local Compliance and Data Sovereignty
Running GitOps in Norway offers a distinct legal advantage. When your cluster reconciles state, it pulls data. If you are using US-based cloud providers for your control plane, you are creating a grey area regarding data processing location under GDPR.
By hosting your Kubernetes control plane and GitOps operator on CoolVDS servers in Oslo, you ensure that the "brain" of your infrastructure resides within the EEA. The data flows from your Git provider (encrypted) directly to a Norwegian server, where it is decrypted in memory. This reduces the attack surface and simplifies your Record of Processing Activities (ROPA) for Datatilsynet.
Final Thoughts
GitOps is binary: you are either doing it, or you are gambling with state. The combination of declarative code (YAML) and robust infrastructure (KVM/NVMe) provides a safety net that manual intervention cannot match.
Don't let slow I/O or noisy neighbors break your reconciliation loop. For a GitOps controller that responds instantly and respects data sovereignty, deploy your control plane on CoolVDS. Stability is not an accident; it is architecture.
Ready to lock down your production? Deploy a high-frequency CoolVDS instance today and stop the configuration drift.