This repo contains the source code of Kaloom's Kubernetes Podagent
A controller that runs on each Kubernetes’ node
To dynamically add/delete a network interface(s) into a running Pod without restarting it (e.g. vrouters, VNF usecases)
Watches Pods’ network attachment annotations using Kubernetes’ apiserver and react to changes to it:
- Finds a Pod’s network namespace from the container runtime engine
- Invokes the cni-plugin to add/del network interface dynamically into the Pod’s network namespace
Let assume we started a Pod with no network attachments (i.e. just the default network on eth0), once it's RUNNING, we added a green network attachment annotation
Let assume we have a RUNNING Pod with 2 network attachements red and green, while it's RUNNING, we deleted off the network attachments annotation list the red network attachment
./build.sh
if you're adding a new dependency package to the project you need to use gradle
, otherwise running the ./build.sh
script should do
gradle
required java
to be installed, its used to generate the dependencies (using gogradle
plugin), update the gogradle.lock
, build the project and update the go vendor
directory if needed
-
update build.gradle
-
generate a new
gogradle.lock
file:./gradlew lock
-
build the project (the
build
gradle task would trigger an update to thevendor
directory using thegogradle.lock
if needed):./gradlew build
or simply
./gradlew
-
submit a merge request
- updating only the vendor directory can be done with:
./gradlew vendor
- to get a list of available
gradle
tasks:./gradlew tasks
How to deploy the podagent
kactus
Kaloom's cni-plugin which knows how to works with dynamic network attachments
-
setup kactus as the system cni-plugin in your Kubernetes cluster by having its configuration the first in lexical order
-
create a Kubernetes service account, cluster role and cluster role binding for the podagent:
$
kubectl apply -f manifests/podagent-serviceaccount-and-rbac.yaml
- deploy the podagent as a daemon set:
$
kubectl apply -f manifests/podagent-ds.yaml
for docker $kubectl apply -f manifests/podagent-cs.yaml
for crio
Currently, to deploy the podagent as DaemonSet
-
selinux should not be in enforced mode (permissive mode is okay):
#
setenforce permissive
#
sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
-
it's run as a privileged container and requires access to Docker's
/var/run/docker.sock
unix socket (Docker is the only Container Runtime Engine supported right now)
-
setup kactus as the master cni-plugin in your Kubernetes cluster
-
build the podagent rpm package
$
./scripts/build-rpm.sh
- copy and install the produced package in the step above to all the nodes in Kubernetes cluster:
$
sudo rpm -ivh podagent-*.rpm
$
sudo systemctl start podagent
$
sudo systemctl enable podagent
- create a Kubernetes service account, cluster role and cluster role binding for the podagent:
$
kubectl apply -f manifests/podagent-serviceaccount-and-rbac.yaml
- create the
podagent-kubeconfig.yaml
file:
$
./scripts/create-kubeconfig.sh
- copy the produced
/tmp/kubeconfig/podagent-kubeconfig.yaml
to each node in Kubernetes cluster under/opt/kaloom/etc/
$ sudo cp /tmp/kubeconfig/podagent-kubeconfig.yaml /opt/kaloom/etc/
We will deploy a simple application (Linux alpine) with only the default network attachment (i.e. eth0 setup by the master cni-plugin).
Than add a network attachment called data
which uses a bridge
cni-plugin
Let first provision the data
network attachment:
$
kubectl apply -f examples/data-net.yaml
Than delpoy alpine with 2 replicas:
$
kubectl run hello-multi-net --image=alpine --replicas=2 -- top
Add the data
network attachment to the first pod:
$
./scripts/add-network-annotation.sh $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1) data
Verify that a new network interface called net8d777f385d3d
is present in the pod
$
kubectl exec -t $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1) -- ip a
Verify that the pod didn't get re-started
$
kubectl get pod -l run=hello-multi-net -o wide | grep $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1)
Delete the data
network attachment off the first pod:
$
./scripts/del-network-annotation.sh $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1) data
Verify that net8d777f385d3d
is gone from the pod:
$
kubectl exec -t $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1) -- ip a
Verify that the pod didn't get re-started
$
kubectl get pod -l run=hello-multi-net -o wide | grep $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | head -1)
Repeat the same thing with the second pod:
$
./scripts/add-network-annotation.sh $(kubectl get pod -l run=hello-multi-net -o name | cut -d/ -f2 | tail -1) data
- for the above example, make sure that the
data-br
is present on all the nodes
$
brctl show data-br