Skip to content

Commit

Permalink
integration: simplify CNI-fp and add README.md
Browse files Browse the repository at this point in the history
* Use delegated plugin call to simplify cni-bridge-cni
* Add README.md for cni-bridge-cni

Signed-off-by: Wei Fu <[email protected]>
(cherry picked from commit e6a2c07)
Signed-off-by: Qiutong Song <[email protected]>
  • Loading branch information
fuweid authored and qiutongs committed Sep 30, 2022
1 parent d89a8d2 commit a85709c
Show file tree
Hide file tree
Showing 9 changed files with 659 additions and 218 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/containerd/ttrpc v1.1.0
github.com/containerd/typeurl v1.0.2
github.com/containerd/zfs v1.0.0
github.com/containernetworking/cni v1.1.1
github.com/containernetworking/plugins v1.1.1
github.com/coreos/go-systemd/v22 v22.3.2
github.com/davecgh/go-spew v1.1.1
Expand Down Expand Up @@ -83,7 +84,6 @@ require (
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cilium/ebpf v0.7.0 // indirect
github.com/containernetworking/cni v1.1.1 // indirect
github.com/containers/ocicrypt v1.1.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/go-logr/logr v1.2.2 // indirect
Expand Down
159 changes: 159 additions & 0 deletions integration/failpoint/cmd/cni-bridge-fp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
## cni-bridge-f(ail)p(oint)

### Overview

The `cni-bridge-fp` is a CNI plugin which delegates interface-creating function
to [CNI bridge plugin][1] and allows user to inject failpoint before delegation.

Since the CNI plugin is invoked by binary call from CRI and it is short-lived,
the failpoint need to be configured by a JSON file, which can be persisted.
There is an example about failpoint description.

```json
{
"cmdAdd": "1*error(you-shall-not-pass!)->1*panic(again)",
"cmdDel": "1*error(try-again)",
"cmdCheck": "10*off"
}
```

* `cmdAdd` (string, optional): The failpoint for `ADD` command.
* `cmdDel` (string, optional): The failpoint for `DEL` command.
* `cmdCheck` (string, optional): The failpoint for `CHECK` command.

Since the `cmdXXX` can be multiple failpoints, each CNI binary call will update
the current state to make sure the order of execution is expected.

And the failpoint injection is enabled by pod's annotation. Currently, the key
of customized CNI capabilities in containerd can only be `io.kubernetes.cri.pod-annotations`
and containerd will pass pod's annotations to CNI under the that object. The
user can use the `failpoint.cni.containerd.io/confpath` annotation to enable
failpoint for the pod.

```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
annotations:
failpoint.cni.containerd.io/confpath: "/tmp/pod-failpoints.json"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
```
### Example
Let's use the following json as failpoint description.
```bash
$ cat <<EOF | tee /tmp/cni-failpoint.json
{
"cmdAdd": "1*error(try-again)",
"cmdDel": "2*error(oops)",
"cmdCheck": "1*off->1*panic(sorry)"
}
EOF
```

And use `ip netns` to create persisted net namespace named by `failpoint`.

```bash
$ sudo ip netns add failpoint
```

And then setup the following bash script for demo.

```bash
$ cat <<EOFDEMO | tee /tmp/cni-failpoint-demo-helper.sh
#!/usr/bin/env bash
export CNI_CONTAINERID=failpoint-testing
export CNI_NETNS=/run/netns/failpoint
export CNI_IFNAME=fpeni0
export CNI_PATH=/opt/cni/bin/
cat <<EOF | /opt/cni/bin/cni-bridge-fp
{
"cniVersion": "0.3.0",
"name": "containerd-net-fp",
"type": "cni-bridge-fp",
"bridge": "fp-cni0",
"isGateway": true,
"ipMasq": true,
"promiscMode": true,
"ipam": {
"type": "host-local",
"ranges": [
[{
"subnet": "10.88.0.0/16"
}],
[{
"subnet": "2001:4860:4860::/64"
}]
],
"routes": [
{ "dst": "0.0.0.0/0" },
{ "dst": "::/0" }
]
},
"runtimeConfig": {
"io.kubernetes.cri.pod-annotations": {
"failpoint.cni.containerd.io/confpath": "/tmp/cni-failpoint.json"
}
}
}
EOF
EOFDEMO
```

Let's try to setup CNI and we should get a error `try-again`.

```bash
$ sudo CNI_COMMAND=ADD bash /tmp/cni-failpoint-demo-helper.sh
{
"code": 999,
"msg": "try-again"
}

# there is no failpoint for ADD command.
$ cat /tmp/cni-failpoint.json | jq .
{
"cmdAdd": "0*error(try-again)",
"cmdDel": "2*error(oops)",
"cmdCheck": "1*off->1*panic(sorry)"
}
```

We should setup CNI successfully after retry. When we teardown the interface,
there should be two failpoints.

```bash
$ sudo CNI_COMMAND=ADD bash /tmp/cni-failpoint-demo-helper.sh
...

$ sudo CNI_COMMAND=DEL bash /tmp/cni-failpoint-demo-helper.sh
{
"code": 999,
"msg": "oops"
}

$ sudo CNI_COMMAND=DEL bash /tmp/cni-failpoint-demo-helper.sh
{
"code": 999,
"msg": "oops"
}

$ cat /tmp/cni-failpoint.json | jq .
{
"cmdAdd": "0*error(try-again)",
"cmdDel": "0*error(oops)",
"cmdCheck": "1*off->1*panic(sorry)"
}
```

[1]: <https://www.cni.dev/plugins/current/main/bridge/>
209 changes: 0 additions & 209 deletions integration/failpoint/cmd/cni-bridge-fp/main.go

This file was deleted.

Loading

0 comments on commit a85709c

Please sign in to comment.