Just a CNI that I am writing for my homelab, currently only works (partially) on a local cluster via Kind.
- stable rust toolchains:
rustup toolchain install stable - nightly rust toolchains:
rustup toolchain install nightly --component rust-src - (if cross-compiling) rustup target:
rustup target add ${ARCH}-unknown-linux-musl - (if cross-compiling) LLVM: (e.g.)
brew install llvm(on macOS) - (if cross-compiling) C toolchain: (e.g.)
brew install filosottile/musl-cross/musl-cross(on macOS) - bpf-linker:
cargo install bpf-linker(--no-default-features --features=llvm-21on macOS) - just:
cargo install just --locked - kind: Installation
Deploy to a local Kind cluster by running just run-local. Depending on your setup, you may need to adjust the var agent.clusterURL found at charts/mesh-cni/values.yaml to match the Kubernetes endpoint for your Kind
cluster.
Changes to the BPF maps may require resetting the cluster. This can be done with a just kind-down and just run-local.
Meshes configured cluster state into the local cluster allowing for services to be routed to the local and remote cluster (if configured with multi-cluster annotation).
Example:
apiVersion: mesh-cni.dev/v1alpha1
kind: Cluster
metadata:
name: cluster2
spec:
secret:
name: mesh-remote-cluster2-kubeconfig
key: configThe referenced Secret must exist in the controller namespace and contain kubeconfig bytes under data.config.
MeshEndpoint are controller-derived and should not be manually created. Created when a Service is annotated with the multi-cluster annotation.
Contains backend endpoint information from the owned cluster and represents state that should be programmed into the service BPF map.
To include a Service in multi-cluster mesh endpoint generation, set:
metadata:
annotations:
mesh-cni.dev/multi-cluster: "true"Example:
apiVersion: mesh-cni.dev/v1alpha1
kind: MeshEndpoint
metadata:
name: web-cluster2
namespace: app
labels:
kubernetes.io/service-name: web
mesh-cni.dev/cluster-owner: cluster2
spec:
backend_port_mappings:
- ip: 10.242.0.21
service_port: 80
backend_port: 8080
protocol: TCPMeshEndpoint no longer carries service_ips; the service BPF controller always reads local
Service ClusterIPs from the in-cluster Service resource.
Identity and CIDRIdentity are controller-derived and should not be manually created. Identity are created from unique sets of pods based on labels. CIDRIdentity is generated based on
ipBlock present in NetworkPolicy resources in the cluster. Both are used to program the policy related BPF maps.
Example generated Identity:
apiVersion: mesh-cni.dev/v1alpha1
kind: Identity
metadata:
name: web-identity
namespace: app
spec:
id: 2599738693
namespaceLabels:
kubernetes.io/metadata.name: app
podLabels:
app: webExample generated CIDRIdentity:
apiVersion: mesh-cni.dev/v1alpha1
kind: CIDRIdentity
metadata:
name: cidr-10-0-0-0-8
spec:
id: 30002
cidr: 10.0.0.0/8
except:
- 10.96.0.0/12
cidrPrefixes:
- 10.0.0.0/9
- 10.128.0.0/10
- 10.192.0.0/11
- 10.224.0.0/12For two kind clusters on the same Docker network with cross-cluster kubeconfig secrets and Cluster CRs applied:
just multi-reset-clusterWith the exception of eBPF code, mesh-cni is distributed under the terms of either the MIT license or the Apache License (version 2.0), at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
All eBPF code is distributed under either the terms of the GNU General Public License, Version 2 or the MIT license, at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the GPL-2 license, shall be dual licensed as above, without any additional terms or conditions.