-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Expand file tree
/
Copy pathNRI.md
More file actions
167 lines (135 loc) · 7.57 KB
/
NRI.md
File metadata and controls
167 lines (135 loc) · 7.57 KB
Edit and raw actions
OlderNewer
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 repository](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 (`/internal/nri/*`) to integrate to
27
NRI and CRI-specific bits (`/internal/cri/nri`) 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.
46
47
### NRI Support for Other Container 'Domains'
48
49
The main reason for this split of functionality is to allow
50
NRI plugins for other types of sandboxes and for other container clients other than just for CRI containers in the "k8s.io" namespace.
51
52
## Disabling NRI Support in Containerd
53
54
Enabling and disabling NRI support in containerd happens by enabling or
55
disabling the common containerd NRI plugin. Starting with containerd 2.0
56
The plugin, and consequently NRI functionality, is enabled by default.
57
It can be disabled by editing the `[plugins."io.containerd.nri.v1.nri"]`
58
section in the containerd configuration file, which by default is
59
`/etc/containerd/config.toml`, and changing `disable = false` to
60
`disable = true`. The NRI section to disable NRI functionality should
61
look something like this:
62
63
```toml
64
[plugins."io.containerd.nri.v1.nri"]
65
# Disable NRI support in containerd.
66
disable = true
67
# Allow connections from externally launched NRI plugins.
68
disable_connections = false
69
# plugin_config_path is the directory to search for plugin-specific configuration.
70
plugin_config_path = "/etc/nri/conf.d"
71
# plugin_path is the directory to search for plugins to launch on startup.
72
plugin_path = "/opt/nri/plugins"
73
# plugin_registration_timeout is the timeout for a plugin to register after connection.
74
plugin_registration_timeout = "5s"
75
# plugin_request_timeout is the timeout for a plugin to handle an event/request.
76
plugin_request_timeout = "2s"
77
# socket_path is the path of the NRI socket to create for plugins to connect to.
78
socket_path = "/var/run/nri/nri.sock"
79
```
80
81
There are two ways how an NRI plugin can be started. Plugins can be
82
pre-registered in which case they are automatically started when the NRI
83
adaptation is instantiated (or in our case when containerd is started).
84
Plugins can also be started by external means, for instance by systemd.
85
86
Pre-registering a plugin happens by placing a symbolic link to the plugin
87
executable into a well-known NRI-specific directory, `/opt/nri/plugins`
88
by default. A pre-registered plugin is started with a socket pre-connected
89
to NRI. Externally launched plugins connect to a well-known NRI-specific
90
socket, `/var/run/nri/nri.sock` by default, to register themselves. The only
91
difference between pre-registered and externally launched plugins is how
92
they get started and connected to NRI. Once a connection is established
93
all plugins are identical.
94
95
NRI can be configured to disable connections from externally launched
96
plugins, in which case the well-known socket is not created at all. The
97
configuration fragment shown above ensures that external connections are
98
enabled regardless of the built-in NRI defaults. This is convenient for
99
testing as it allows one to connect, disconnect and reconnect plugins at
100
any time.
101
102
Note that you can't run two NRI-enabled runtimes on a single node with the
103
same default socket configuration. You need to either disable NRI or change
104
the NRI socket path in one of the runtimes.
105
106
## Testing NRI Support in Containerd
107
108
You can verify that NRI integration is properly enabled and functional by
109
configuring containerd and NRI as described above, taking the NRI
110
logger plugin from the [NRI repository](https://github.com/containerd/nri/tree/main/plugins/logger)
111
on github, compiling it and starting it up.
112
113
```bash
114
git clone https://github.com/containerd/nri
115
cd nri
116
make
117
./build/bin/logger -idx 00
118
```
119
120
You should see the logger plugin receiving receiving a list of existing pods
121
and containers. If you then create or remove further pods and containers
122
using crictl or kubectl you should see detailed logs of the corresponding NRI
123
events printed by the logger.
124
125
## NRI Compatibility With v0.1.0 Plugins
126
127
You can enable backward compatibility with NRI v0.1.0 plugins using the
128
[v010-adapter plugin](https://github.com/containerd/nri/tree/main/plugins/v010-adapter).
129
130
```bash
131
git clone https://github.com/containerd/nri
132
cd nri
133
make
134
sudo cp build/bin/v010-adapter /usr/local/bin
135
sudo mkdir -p /opt/nri/plugins
136
sudo ln -s /usr/local/bin/v010-adapter /opt/nri/plugins/00-v010-adapter
137
```
138
139
## Default Validator
140
141
The built-in default NRI validator plugin can be used to selectively lock
142
down some of the container controls available in NRI. You can enable and
143
configure the default validator using the following toml fragment in the
144
containerd configuration file:
145
146
```toml
147
[plugins.'io.containerd.nri.v1.nri'.default_validator]
148
enable = <true|false>
149
reject_oci_hook_adjustment = <true|false>
150
reject_runtime_default_seccomp_adjustment = <true|false>
151
reject_unconfined_seccomp_adjustment = <true|false>
152
reject_custom_seccomp_adjustment = <true|false>
153
reject_namespace_adjustment = <true|false>
154
required_plugins = [ <list of required NRI plugins> ]
155
tolerate_missing_plugins_annotation = <annotation key name for toleration>
156
```
157
158
Using this configuration you can selectively disable
159
- OCI hook injection
160
- adjustment of the default seccomp policy
161
- adjustment of an unconfined seccomp policy
162
- adjustment of a custom seccomp policy
163
- adjustment of linux namespace adjustment
164
165
Additionally, you can require a set of NRI plugins to always be present for
166
container creation to succeed, and an annotation key which can be used to
167
annotate containers otherwise.