Skip to content

Commit a0daf1c

Browse files
klihubmikebrow
andcommitted
docs: add NRI-related documentation.
Co-authored-by: Mike Brown <[email protected]> Signed-off-by: Krisztian Litkey <[email protected]>
1 parent 02f0a8b commit a0daf1c

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

docs/NRI.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# NRI Support In Containerd
2+
3+
## Node Resource Interface
4+
5+
NRI, the Node Resource Interface, is a common framework for plugging
6+
extensions into OCI-compatible container runtimes. It provides basic
7+
mechanisms for plugins to track the state of containers and to make
8+
limited changes to their configuration.
9+
10+
NRI itself is agnostic to the internal implementation details of any
11+
container runtime. It provides an adaptation library which runtimes
12+
use to integrate to and interact with NRI and plugins. In principle
13+
any NRI plugin should be able to work with NRI-enabled runtimes.
14+
15+
For a detailed description of NRI and its capabilities please take a
16+
look at the [NRI respository](https://github.com/containerd/nri).
17+
18+
## Containerd NRI Integration
19+
20+
<details>
21+
<summary>see the containerd/NRI integration diagram</summary>
22+
<img src="./containerd-nri-integration.png" title="Containerd/NRI Integration">
23+
</details>
24+
25+
NRI support in containerd is split into two parts both logically and
26+
physically. These parts are a common plugin (/nri/*) to integrate to
27+
NRI and CRI-specific bits (/pkg/cri/server/nri-api) which convert
28+
data between the runtime-agnostic NRI representation and the internal
29+
representation of the CRI plugin.
30+
31+
### Containerd NRI Plugin
32+
33+
The containerd common NRI plugin implements the core logic of integrating
34+
to and interacting with NRI. However, it does this without any knowledge
35+
about the internal representation of containers or pods within containerd.
36+
It defines an additional interface, Domain, which is used whenever the
37+
internal representation of a container or pod needs to be translated to
38+
the runtime agnostic NRI one, or when a configuration change requested by
39+
an external NRI plugin needs to be applied to a container within containerd. `Domain` can be considered as a short-cut name for Domain-Namespace as Domain implements the functions the generic NRI interface needs to deal with pods and containers from a particular containerd namespace. As a reminder, containerd namespaces isolate state between clients of containerd. E.g. "k8s.io" for the kubernetes CRI clients, "moby" for docker clients, ... and "containerd" as the default for containerd/ctr.
40+
41+
### NRI Support for CRI Containers
42+
43+
The containerd CRI plugin registers itself as an above mentioned NRI
44+
Domain for the "k8s.io" namespace, to allow container configuration to be customized by external
45+
NRI plugins. Currently this Domain interface is only implemented for
46+
the original CRI `pkg/cri/server` implementation. Implementing it for
47+
the more recent experimental `pkg/cri/sbserver` implementation is on
48+
the TODO list.
49+
50+
### NRI Support for Other Container 'Domains'
51+
52+
The main reason for this split of functionality is to allow
53+
NRI plugins for other types of sandboxes and for other container clients other than just for CRI containers in the "k8s.io" namespace.
54+
55+
## Enabling NRI Support in Containerd
56+
57+
Enabling and disabling NRI support in containerd happens by enabling or
58+
disabling the common containerd NRI plugin. The plugin, and consequently
59+
NRI functionality, is disabled by default. It can be enabled by editing
60+
the `[plugins."io.containerd.nri.v1.nri"]` section in the containerd
61+
configuration file, which by default is `/etc/containerd/config.toml`,
62+
and changing `disable = true` to `disable = false`. Once enabled, the
63+
NRI section should look something like this:
64+
65+
```toml
66+
[plugins."io.containerd.nri.v1.nri"]
67+
config_file = "/etc/nri/nri.conf"
68+
disable = false
69+
plugin_path = "/opt/nri/plugins"
70+
socket_path = "/var/run/nri.sock"
71+
```
72+
73+
In addition to this, you need to put a runtime agnostic NRI configuration
74+
file in place, to let NRI itself know that it is enabled. You can do this
75+
by creating `/etc/nri/nri.conf` with the following content:
76+
77+
```yaml
78+
disableConnections: false
79+
```
80+
81+
This enables externally launched NRI plugins to connect and register
82+
themselves.
83+
84+
There are two ways how an NRI plugin can be started. Plugins can be
85+
pre-registered in which case they are automatically started when the NRI
86+
adaptation is instantiated (or in our case when containerd is started).
87+
Plugins can also be started by external means, for instance by systemd.
88+
89+
Pre-registering a plugin happens by placing a symbolic link to the plugin
90+
executable into a well-known NRI-specific directory, `/opt/nri/plugins`
91+
by default. A pre-registered plugin is started with a socket pre-connected
92+
to NRI. Externally launched plugins connect to a well-known NRI-specific
93+
socket, `/var/run/nri.sock` by default, to register themselves. The only
94+
difference between pre-registered and externally launched plugins is how
95+
they get started and connected to NRI. Once a connection is established
96+
all plugins are identical.
97+
98+
NRI can be configured to disable connections from externally launched
99+
plugins, in which case the well-known socket is not created at all. The
100+
configuration fragment shown above ensures that external connections are
101+
enabled regardless of the built-in NRI defaults. This is convenient for
102+
testing as it allows one to connect, disconnect and reconnect plugins at
103+
any time.
104+
105+
For more details about pre-registered and externally launched plugins
106+
107+
## Testing NRI Support in Containerd
108+
109+
You can verify that NRI integration is properly enabled and functional by
110+
configuring containerd and NRI as described above, taking the NRI
111+
logger plugin either from the NRI repository or
112+
[this fork](https://github.com/klihub/nri/tree/pr/proto/draft/plugins/logger)
113+
on github, compiling it and starting it up.
114+
115+
```bash
116+
git clone https://github.com/klihub/nri
117+
cd nri
118+
git checkout pr/proto/draft
119+
make
120+
./build/bin/logger -idx 00
121+
```
122+
123+
You should see the logger plugin receiving receiving a list of existing pods
124+
and containers. If you then create or remove further pods and containers
125+
using crictl or kubectl you should see detailed logs of the corresponding NRI
126+
events printed by the logger.
127+
128+
## NRI Compatibility With v0.1.0 Plugins
129+
130+
You can enable backward compatibility with NRI v0.1.0 plugins using the
131+
[v010-adapter plugin](https://github.com/klihub/nri/tree/pr/proto/draft/plugins/v010-adapter).
132+
133+
```bash
134+
git clone https://github.com/klihub/nri
135+
cd nri
136+
git checkout pr/proto/draft
137+
make
138+
sudo cp build/bin/v010-adapter /usr/local/bin
139+
sudo mkdir -p /opt/nri/plugins
140+
sudo ln -s /usr/local/bin/v010-adapter /opt/nri/plugins/00-v010-adapter
141+
```

docs/containerd-nri-integration.png

130 KB
Loading

0 commit comments

Comments
 (0)