mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add a tutorial on CNI
This commit is contained in:
committed by
Fabricio Voznika
parent
039f309bc9
commit
eae7c2f6bd
@@ -0,0 +1,175 @@
|
||||
+++
|
||||
title = "Using CNI"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
This tutorial will show you how to set up networking for a gVisor sandbox using
|
||||
the [Container Networking Interface (CNI)](https://github.com/containernetworking/cni).
|
||||
|
||||
## Install CNI Plugins
|
||||
|
||||
First you will need to install the CNI plugins. CNI plugins are used to set up
|
||||
a network namespace that `runsc` can use with the sandbox.
|
||||
|
||||
Start by creating the directories for CNI plugin binaries:
|
||||
|
||||
```
|
||||
sudo mkdir -p /opt/cni/bin
|
||||
```
|
||||
|
||||
Download the CNI plugins:
|
||||
|
||||
```
|
||||
wget https://github.com/containernetworking/plugins/releases/download/v0.8.3/cni-plugins-linux-amd64-v0.8.3.tgz
|
||||
```
|
||||
|
||||
Next, unpack the plugins into the CNI binary directory:
|
||||
|
||||
```
|
||||
sudo tar -xvf cni-plugins-linux-amd64-v0.8.3.tgz -C /opt/cni/bin/
|
||||
```
|
||||
|
||||
## Configure CNI Plugins
|
||||
|
||||
This section will show you how to configure CNI plugins. This tutorial will use
|
||||
the "bridge" and "loopback" plugins which will create the necessary bridge and
|
||||
loopback devices in our network namespace. However, you should be able to use
|
||||
any CNI compatible plugin to set up networking for gVisor sandboxes.
|
||||
|
||||
The bridge plugin configuration specifies the IP address subnet range for IP
|
||||
addresses that will be assigned to sandboxes as well as the network routing
|
||||
configuration. This tutorial will assign IP addresses from the `10.22.0.0/16`
|
||||
range and allow all outbound traffic, however you can modify this configuration
|
||||
to suit your use case.
|
||||
|
||||
Create the bridge and loopback plugin configurations:
|
||||
|
||||
```
|
||||
sudo mkdir -p /etc/cni/net.d
|
||||
|
||||
sudo sh -c 'cat > /etc/cni/net.d/10-bridge.conf << EOF
|
||||
{
|
||||
"cniVersion": "0.4.0",
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"bridge": "cni0",
|
||||
"isGateway": true,
|
||||
"ipMasq": true,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.22.0.0/16",
|
||||
"routes": [
|
||||
{ "dst": "0.0.0.0/0" }
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF'
|
||||
|
||||
sudo sh -c 'cat > /etc/cni/net.d/99-loopback.conf << EOF
|
||||
{
|
||||
"cniVersion": "0.4.0",
|
||||
"name": "lo",
|
||||
"type": "loopback"
|
||||
}
|
||||
EOF'
|
||||
```
|
||||
|
||||
## Create a Network Namespace
|
||||
|
||||
For each gVisor sandbox you will create a network namespace and configure it
|
||||
using CNI. First, create a random network namespace name and then create
|
||||
the namespace.
|
||||
|
||||
The network namespace path will then be `/var/run/netns/${CNI_CONTAINERID}`.
|
||||
|
||||
```
|
||||
export CNI_PATH=/opt/cni/bin
|
||||
export CNI_CONTAINERID=$(printf '%x%x%x%x' $RANDOM $RANDOM $RANDOM $RANDOM)
|
||||
export CNI_COMMAND=ADD
|
||||
export CNI_NETNS=/var/run/netns/${CNI_CONTAINERID}
|
||||
|
||||
sudo ip netns add ${CNI_CONTAINERID}
|
||||
```
|
||||
|
||||
Next, run the bridge and loopback plugins to apply the configuration that was
|
||||
created earlier to the namespace. Each plugin outputs some JSON indicating the
|
||||
results of executing hte plugin. For example, The bridge plugin's response
|
||||
includes the IP address assigned to the ethernet device created in the network
|
||||
namespace. Take note of the IP address for use later.
|
||||
|
||||
```
|
||||
export CNI_IFNAME="eth0"
|
||||
sudo -E /opt/cni/bin/bridge < /etc/cni/net.d/10-bridge.conf
|
||||
export CNI_IFNAME="lo"
|
||||
sudo -E /opt/cni/bin/loopback < /etc/cni/net.d/99-loopback.conf
|
||||
```
|
||||
|
||||
Get the IP address assigned to our sandbox:
|
||||
|
||||
```
|
||||
POD_IP=$(sudo ip netns exec ${CNI_CONTAINERID} ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||||
```
|
||||
|
||||
## Create the OCI Bundle
|
||||
|
||||
Now that our network namespace is created and configured, we can create the OCI
|
||||
bundle for our container. As part of the bundle's `config.json` we will specify
|
||||
that the container use the network namespace that we created.
|
||||
|
||||
The container will run a simple python webserver that we will be able to
|
||||
connect to via the IP address assigned to it via the bridge CNI plugin.
|
||||
|
||||
Create the bundle and root filesystem directories:
|
||||
|
||||
```
|
||||
sudo mkdir -p bundle
|
||||
cd bundle
|
||||
sudo mkdir rootfs
|
||||
sudo docker export $(docker create python) | sudo tar --same-owner -pxf - -C rootfs
|
||||
sudo mkdir -p rootfs/var/www/html
|
||||
sudo sh -c 'echo "Hello World!" > rootfs/var/www/html/index.html'
|
||||
```
|
||||
|
||||
Next create the `config.json` specifying the network namespace.
|
||||
```
|
||||
sudo /usr/local/bin/runsc spec
|
||||
sudo sed -i 's;"sh";"python", "-m", "http.server";' config.json
|
||||
sudo sed -i "s;\"cwd\": \"/\";\"cwd\": \"/var/www/html\";" config.json
|
||||
sudo sed -i "s;\"type\": \"network\";\"type\": \"network\",\n\t\t\t\t\"path\": \"/var/run/netns/${CNI_CONTAINERID}\";" config.json
|
||||
```
|
||||
|
||||
## Run the Container
|
||||
|
||||
Now we can run and connect to the webserver. Run the container in gVisor. Use
|
||||
the same ID used for the network namespace to be consistent:
|
||||
|
||||
```
|
||||
sudo runsc run -detach ${CNI_CONTAINERID}
|
||||
```
|
||||
|
||||
Connect to the server via the sandbox's IP address:
|
||||
|
||||
```
|
||||
curl http://${POD_IP}:8000/
|
||||
```
|
||||
|
||||
You should see the server returning `Hello World!`.
|
||||
|
||||
## Cleanup
|
||||
|
||||
After you are finished running the container, you can clean up the network
|
||||
namespace .
|
||||
|
||||
```
|
||||
sudo runsc kill ${CNI_CONTAINERID}
|
||||
sudo runsc delete ${CNI_CONTAINERID}
|
||||
|
||||
export CNI_COMMAND=DEL
|
||||
|
||||
export CNI_IFNAME="lo"
|
||||
sudo -E /opt/cni/bin/loopback < /etc/cni/net.d/99-loopback.conf
|
||||
export CNI_IFNAME="eth0"
|
||||
sudo -E /opt/cni/bin/bridge < /etc/cni/net.d/10-bridge.conf
|
||||
|
||||
sudo ip netns delete ${CNI_CONTAINERID}
|
||||
```
|
||||
@@ -1,5 +1,6 @@
|
||||
+++
|
||||
title = "WordPress with Kubernetes"
|
||||
weight = 11
|
||||
+++
|
||||
|
||||
## Deploy a WordPress site using GKE Sandbox
|
||||
@@ -235,4 +236,4 @@ a look at the [documentation][gke-sandbox-docs].
|
||||
[gke-sandbox-docs]: https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods
|
||||
[gke-sandbox]: https://cloud.google.com/kubernetes-engine/sandbox/
|
||||
[project-selector]: https://console.cloud.google.com/projectselector/kubernetes
|
||||
[wordpress]: https://wordpress.com/
|
||||
[wordpress]: https://wordpress.com/
|
||||
|
||||
@@ -43,7 +43,7 @@ Finally run the container.
|
||||
sudo runsc run hello
|
||||
```
|
||||
|
||||
Next try [running gVisor using Docker](../docker/).
|
||||
Next try [using CNI to set up networking](../../../tutorials/cni/) or [running gVisor using Docker](../docker/).
|
||||
|
||||
[oci]: https://opencontainers.org/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user