This episode takes Flannel into the GitOps era: managing manifests and Helm values as code through Argo CD or Flux, applying versioning and a review flow, and a staged deployment strategy for upgrades that are safe and can be rolled back.

So far you have applied Flannel directly through kubectl. In production teams, that approach leaves questions unanswered: who changed the configuration, when, and how do you revert it? GitOps answers all of these with a single principle: git is the source of truth.
Episode 18 brings Flannel into a GitOps workflow. You will manage manifests and Helm values as code through Argo CD or Flux, apply versioning and a review flow, and deploy changes in stages.
There are two forms of Flannel as code: the raw kube-flannel.yml manifest stored directly in the repository, or a Helm chart with a values file. Manifests are simple and transparent; Helm makes it easy to override per-cluster values in a single file.
mkdir -p clusters/prod/flannel
cp kube-flannel.yml clusters/prod/flannel/
git add clusters/prod/flannel/
git commit -m "chore(flannel): pin manifest v0.28.8"The git add and git commit commands mark Flannel changes as part of history that can be reviewed like code.
Store the configuration that is consistent per cluster: the image tag, backend, MTU, and CIDR. If there are differences between clusters — for example production uses host-gw while staging uses vxlan — represent them as separate per-environment values.
Argo CD deploys Flannel from a repository through an Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: flannel
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/infrastructure.git
path: clusters/prod/flannel
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: kube-flannel
syncPolicy:
automated:
prune: trueThe Application above syncs the clusters/prod/flannel folder from the main branch to the kube-flannel namespace. Changes in git are applied to the cluster automatically.
Flux uses a Kustomization with a similar approach:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flannel
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: infrastructure
path: ./clusters/prod/flannel
prune: trueBoth Argo CD and Flux point Flannel at the same namespace and manage its lifecycle from git.
The first principle of GitOps: no direct changes in the cluster. Every change goes through a pull request. The key to success is a clear image tag so the diff is easy to read during review.
git commit -m "feat(flannel): upgrade flanneld ke v0.28.8"
git push origin mainThe git push command sends the changes to the repository. The rest of the team reviews the diff before approving it, and Argo CD or Flux applies it once it lands on the target branch.
Don't store secrets in manifests. Flannel's ConfigMap contains net-conf.json, which is not a secret, but if a backend uses keys — for example IPsec — use a Kubernetes Secret and reference it through a secure mechanism.
Always apply changes in a staging cluster before production. Upgrade Flannel in staging, verify connectivity, then promote it to production by changing the branch or folder value in the repository.
kubectl -n kube-flannel rollout restart ds/kube-flannel-ds
kubectl -n kube-flannel rollout status ds/kube-flannel-dsThe kubectl -n kube-flannel rollout status command makes sure the DaemonSet is done before moving to the next step.
GitOps' biggest advantage shows during rollback: just revert the commit or reset the targetRevision in the Application, and Argo CD or Flux returns Flannel to the previous version automatically. No manual guessing about what changed.
Episode 18 changed how you manage Flannel: from direct commands to code that is reviewed, versioned, and applied automatically through GitOps.
Key takeaways:
In the next episode, episode 19, we will sharpen our diagnostics: performance and troubleshooting — a set of commands such as ip route, ip -d link, and journalctl, plus common problem-solving like Pods failing to connect, a down VXLAN, dead br_netfilter, MTU mismatch, and subnet lease conflicts.