Network Policies with Canal and Flannel on K3s
Tags: k3s, kubernetes, network, automation
Published: 2022-01-05 06:10:55

---
title: Network Policies with Canal and Flannel on K3s
published: true
description: 
tags: k3s, kubernetes, network, automation
//cover_image: https://direct_url_to_image.jpg
---

Flannel is a popular Container Network Interface (CNI) addon for Kubernetes, however, it does not provide (because it is Layer 3 network focused on transport between hosts, rather than container networking with the host) robust support for `NetworkPolicy` resources. Now, the policy features from another popular CNI, Calico, can be imported to Flannel using [Canal](https://projectcalico.docs.tigera.io/getting-started/kubernetes/flannel/flannel). 

I won't talk a lot about specific [NetworkPolicy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) in this post, but a little bit about why you'd want a NetworkPolicy controller is for things like creating policies around access to Ingresses, to or from port or IP ranges, things like that-- the sort of concerns you might have creating ACLs and security rules on a traditional network, but scriptable and templateable for Kubernetes like any other resource type. 

Installing Canal requires applying a single manifest (containing the Calico controller, policy agent, and service accounts), however, because the Pod CIDR may differ (and in the case of [K3s](k3s.io), it will be 10.42.0.0/24) from the Calico-expected default of 10.244.0.0/16, an environmental variable (`CALICO_IPV4POOL_CIDR`) and its accompanying value in the manifest.

You can retrieve your Pod CIDR using:

```bash
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}
```

and then modify that variable (commented out) after you download `https://docs.projectcalico.org/manifests/canal.yaml`.

Or use a CLI tool like `sed` to modify it while writing the file locally:

```bash
curl -s https://docs.projectcalico.org/manifests/canal.yaml | \
sed \
-e 's|            # - name: CALICO_IPV4POOL_CIDR|            - name: CALICO_IPV4POOL_CIDR|g' \
-e "s|            #   value: \"192.168.0.0/16\"|              value: \"$(kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}')\"|g"
```
and then (or alternatively) manage this manifest however you typically might do so (in Helm chart, or have an automation tool handle this templating for you, etc.)

If you are a K3s user, conveniently, any manifests written to `/var/lib/rancher/k3s/server/manifests` will be applied automatically, so you can have the above simply write the file for you when provisioning your cluster:

```bash
## Applies the modified manifest to K3s, which automatically applies the contents of /var/lib/rancher/k3s/server/manifests
curl -s https://docs.projectcalico.org/manifests/canal.yaml | sed -e 's|            # - name: CALICO_IPV4POOL_CIDR|            - name: CALICO_IPV4POOL_CIDR|g' -e "s|            #   value: \"192.168.0.0/16\"|              value: \"$(kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}')\"|g" | \
tee -a /var/lib/rancher/k3s/server/manifests/canal.yaml
```

after your K3s install command, if you'd like, on cluster spin-up. 

Checking the status of the `calico-controllers` Deployment will let you know when you are ready to proceed to introduce policy objects:

```bash
kubectl get deployments -n kube-system
```

Examples of common `NetworkPolicy` usage can be [found here.](https://kubernetes.io/docs/concepts/services-networking/network-policies/)