# flannel-io/flannel: a layer 3 network fabric for Kubernetes, reviewed

> flannel gives every pod a routable IP by leasing each node a subnet from one address space, and forwards packets with VXLAN or a cloud backend. It is a connectivity tool, not a policy engine, and the manifest you apply matters more than most guides admit.

**flannel-io/flannel** — flannel is a network fabric for containers, designed for Kubernetes

- Repository: https://github.com/flannel-io/flannel
- Stars: 9,547 · Forks: 2,886
- Language: Go
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/flannel-io-flannel

## The problem flannel solves, and the problem it deliberately leaves alone

Kubernetes assumes each pod has a unique, routable IP inside the cluster. That assumption removes port mapping, but something has to make it true across nodes. flannel is that something. It runs a single binary agent, flanneld, on each host, allocates a subnet lease to each host out of a larger preconfigured address space, and forwards packets between hosts using one of several backend mechanisms, including VXLAN and various cloud integrations.

The scope boundary is stated plainly in the README: flannel does not control how containers are networked to the host, only how traffic is transported between hosts. It ships a CNI plugin for Kubernetes and guidance for Docker integration, and that is where its responsibility ends. If you are looking for a dataplane that also enforces NetworkPolicy, flannel is the wrong layer. The project does offer a path: the Flannel Helm chart has a netpol.enabled option that deploys the Kubernetes SIGs network policy controller alongside Flannel, and there is documented CNI chaining with Cilium and a Calico integration path. Those are add-ons, not flanneld features.

## How flanneld allocates subnets and moves packets

The mechanism is a lease. flanneld takes a preconfigured address space and carves it into per-host subnets, then stores the network configuration, the allocated subnets and auxiliary data such as the host's public IP. Two backing stores are supported: the Kubernetes API or etcd directly. The README recommends the Kubernetes API, calling this mode the kube subnet manager, because it avoids standing up a discrete etcd cluster just for flannel. Outside Kubernetes, etcd is always the datastore, so a Docker deployment carries that extra dependency whether you want it or not.

Once the lease exists, packet forwarding is the backend's job. VXLAN is the one most readers will meet, and cloud integrations are the alternative for environments where the underlying network already knows how to route. Backend choice is not cosmetic: the README says that if a firewall is configured you must enable the right port used by the configured backend, so the backend selection reaches into your security group rules. The repository's go.mod shows the dependency footprint this implies, pulling in vishvananda/netlink, vishvananda/netns, coreos/go-iptables, sigs.k8s.io/knftables and, for WireGuard, golang.zx2c4.com/wireguard/wgctrl. That is a networking binary doing real kernel-adjacent work, not a thin API client.

## Installing flannel on Kubernetes with kubectl

The README's manual path is one command, applied before pods that use the pod network have started. It is simplest to add flannel before anything that depends on pod networking is running.

```bash
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
```

The README is explicit about which copy of the manifest to use: prefer the manifest attached to a release, or latest as above. The copy under Documentation/kube-flannel.yml on the default branch can lag or get ahead of the published container tags, and applying it directly may fail with missing binaries in the image, for example install-conf. That warning is worth taking literally, because the failure mode is a container that starts and then cannot find a binary it expects.

If your podCIDR is not the default 10.244.0.0/16, download the manifest first and change the network to match. Two host-level prerequisites also apply. flannel uses portmap as the CNI network plugin by default, so the CNI plugins must be present in /opt/cni/bin; the README gives this download sequence.

```bash
ARCH=$(uname -m)
  case $ARCH in
    armv7*) ARCH="arm";;
    aarch64) ARCH="arm64";;
    x86_64) ARCH="amd64";;
  esac
mkdir -p /opt/cni/bin
curl -O -L https://github.com/containernetworking/plugins/releases/download/v1.7.1/cni-plugins-linux-$ARCH-v1.7.1.tgz
tar -C /opt/cni/bin -xzf cni-plugins-linux-$ARCH-v1.7.1.tgz
```

Second, flannel requires the br_netfilter module to start. From version 1.30, kubeadm does not check whether the module is installed, and flannel will not rightly start if it is missing. This is the single most common silent failure on a fresh cluster, and it is a host configuration issue rather than a flannel bug.

## Installing flannel on Kubernetes with Helm, and the namespace trap

The Helm route needs a namespace created by hand first, and the README explains why: to avoid a Helm error. The namespace also needs a privileged pod security label, because the agent does privileged networking work.

```bash
kubectl create ns kube-flannel
kubectl label --overwrite ns kube-flannel pod-security.kubernetes.io/enforce=privileged

helm repo add flannel https://flannel-io.github.io/flannel/
helm install flannel --set podCidr="10.244.0.0/16" --namespace kube-flannel flannel/flannel
```

The podCidr value is passed as a Helm set flag rather than read from the cluster, so it is one more place where a custom address space can drift out of sync with the manifest. If you go the Helm route, keep podCidr aligned with whatever the cluster was built with. The chart is also where netpol.enabled lives, which is the supported way to get policy enforcement without replacing flannel.

## Where flannel stops being the right tool

The clearest limitation is policy. flanneld does not natively enforce Network Policies. If your threat model requires default-deny between namespaces enforced by the CNI dataplane, flannel alone does not deliver it, and the workaround is either the Helm chart's netpol.enabled option, which adds a separate controller, or running another project for policy and flannel only for connectivity.

The second limitation is operational. flannel assumes a host that can load br_netfilter and host a CNI plugin directory at /opt/cni/bin. That rules out environments where you cannot modify the node image or the kernel modules, and it makes flannel a poor fit for managed platforms that already provide their own CNI and will not let you replace it. The README's own framing supports this: the easiest way to deploy flannel with Kubernetes is to use a deployment tool or distribution that networks clusters with flannel by default, such as K3s. If you are assembling the cluster by hand, you are taking on the host prerequisites yourself.

A third, quieter issue is manifest drift. The project maintains both release-attached manifests and a default-branch copy, and the README warns that they can diverge from published container tags. Any automation that pins to the branch copy is pinning to something the project does not promise to keep consistent with its images.

## Calico and Cilium as the policy alternative, and what actually differs

The README names Calico and Cilium as the projects to reach for when policy matters, and the difference is architectural rather than cosmetic. flannel separates connectivity from policy: flanneld allocates subnets and forwards packets, and policy, if you want it, arrives as a second component (the Kubernetes SIGs network policy controller via the chart, or another CNI via chaining). Calico's documented path is to install Calico for policy on top of a flannel cluster, which keeps flannel's subnet allocation and forwarding while Calico handles enforcement. Cilium's documented path is CNI chaining, where Cilium attaches to the existing CNI rather than replacing the address management.

That split has a practical consequence. With flannel alone, the number of components you must reason about is small and the failure surface is mostly host configuration. Adding a policy controller reintroduces the second component and its own upgrade cadence. Neither approach is free, and the choice is about which component you would rather debug at 3 a.m. If you never needed policy in the first place, flannel's narrower scope is the advantage.

## Maintenance, release cadence and licence

The repository is not archived, and the last push was on 2026-09-21. Recent releases are v0.28.9 on 2026-08-07, v0.28.8 on 2026-07-22 and v0.28.7 on 2026-07-07, a patch cadence of roughly two to three weeks across that window. The project runs a maintainer community meeting on the third Thursday of each month, and the repository carries ROADMAP.md, GOVERNANCE.md, OWNERS, SECURITY.md and a DCO file, so the process scaffolding for a maintained project is present.

Upgrade cost is dominated by the host, not the binary. The README's note about br_netfilter and kubeadm 1.30 is a version-boundary issue that will bite anyone moving to newer kubeadm; the CNI plugin download is pinned in the README to v1.7.1, so that is a separate artifact to track. The Makefile shows the build pins Go 1.26 and a K8s version of 1.34.6 for its helpers, and go.mod targets k8s.io/api v0.34.10, which tells you the Kubernetes client libraries track upstream closely. Expect to rebuild or re-pull images when Kubernetes client APIs move.

Licensing is Apache-2.0, per the README and the LICENSE file. Apache-2.0 includes an explicit patent grant and requires preservation of notices; if you redistribute flannel inside a product, the notice and attribution obligations are the part to read. This is not legal advice, and your counsel should review any redistribution.

## Conclusion

Adopt flannel if you want pod-to-pod routing with the least moving parts and you accept that policy enforcement is somebody else's job or a Helm flag. Skip it if you need network policy from the dataplane itself, or if you cannot install the CNI plugins and load br_netfilter on every node. Before rollout, check whether your nodes have br_netfilter loaded, confirm podCIDR matches your cluster, and apply the manifest attached to a release rather than the copy on the default branch.

## FAQ

### What is flannel-io/flannel?

It is a layer 3 network fabric for Kubernetes, built from a single binary agent called flanneld that runs on each host. It allocates a subnet lease per host from a preconfigured address space and forwards packets between hosts using VXLAN or a cloud backend.

### How do I install flannel in a Kubernetes cluster?

The README's manual path is kubectl apply with the kube-flannel.yml manifest attached to a release, and it recommends doing this before pods that use the pod network have started. There is also a Helm chart, but you must create the kube-flannel namespace and label it privileged first.

### How do I install the flannel CNI plugin?

flannel uses portmap as its CNI network plugin by default, so the CNI network plugins must be installed in /opt/cni/bin. The README gives a curl and tar sequence that downloads the cni-plugins release, currently v1.7.1, and extracts it into that directory.

### How do I install flannel on Kubernetes?

Either apply the release-attached kube-flannel.yml manifest with kubectl, or use the Helm chart after creating the kube-flannel namespace and labeling it pod-security.kubernetes.io/enforce=privileged. The README recommends applying flannel before pods that use the pod network have started.

### How do I install flannel?

On Kubernetes, the README's simplest route is kubectl apply with the kube-flannel.yml manifest from the latest release. Outside Kubernetes, flannel is deployed with etcd as the datastore, and the README points to Documentation/running.md for Docker integration details.

## Sources

- [flannel-io/flannel on GitHub](https://github.com/flannel-io/flannel)
- [Issues](https://github.com/flannel-io/flannel/issues)
- [License: Apache-2.0](https://github.com/flannel-io/flannel/blob/master/LICENSE)
- [README](https://github.com/flannel-io/flannel/blob/master/README.md)
- [Releases](https://github.com/flannel-io/flannel/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/flannel-io-flannel
