You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- the runtime: launches plugins or allows manual launched plugins to connect
4
+
- the plugin(s): registers to the runtime and is domain expert for a specific secret provider
5
+
6
+
From the plugin system perspective, the runtime is a lifecycle management server for plugins.
7
+
However, from the secrets engine perspective, the runtime is a client that can request secrets from a plugin.
8
+
9
+
To avoid having a socket per plugin, we multiplex the socket.
10
+
```mermaid
11
+
flowchart TD
12
+
Socket[(Multiplexed<br>Socket)]
13
+
14
+
subgraph PluginBlock [Plugin]
15
+
direction TB
16
+
PSrv["Provider (Server)"]
17
+
PC["Plugin (Client)"]
18
+
end
19
+
20
+
subgraph ResolverBlock [Resolver]
21
+
direction TB
22
+
RPC["Resolver (Provider Client)"]
23
+
PServ[Plugin Server/Runtime]
24
+
end
25
+
26
+
Socket -->|register plugin| PServ
27
+
Socket -->|get secret| PSrv
28
+
PC -->|register plugin| Socket
29
+
RPC -->|get secret| Socket
30
+
31
+
```
32
+
33
+
## Choosing a multiplexer
34
+
The multiplexer adds a custom layer on top of the socket that allows running servers on both ends of the socket.
35
+
36
+
### nri/net/multiplex - a minimal multiplexer
37
+
The plugin system in [containerd/nr](https://github.com/containerd/nri) implements its own simple frame-based multiplexer [nri/net/multiplex](https://github.com/containerd/nri/tree/main/pkg/net/multiplex).
38
+
It provides two streams on each side that need to be re-used for all communication.
39
+
This works well for [ttrpc](https://github.com/containerd/ttrpc) which uses its own length-prefixed framing.
40
+
However, the standard Go HTTP server inside `Server(net.Listener)` does one `Accept()`, gets one `net.Conn`, and then loops inside serveConn to decode requests.
41
+
But because that sub-connection isn’t a real socket—and because the mux delivers no further “new connections” and any pipelined data after the first request can get lost or stuck in the mux’s framing, and the server never sees it.
42
+
43
+
Alternatively, HTTP/2 without TLS could be used as it has gives control over the framing.
44
+
Unfortunately, Go's `net/http` package does not easily support HTTP/2 without TLS and getting it work comes with its own set of challenges, such as requiring a custom `net.Listener` implementation that handles the HTTP/2 framing.
45
+
46
+
TLDR: [nri/net/multiplex](https://github.com/containerd/nri/tree/main/pkg/net/multiplex) is not ideal for general HTTP servers.
47
+
48
+
### Yamux
49
+
50
+
Yamux is a full-featured, multiplexing protocol that allows multiple streams to be sent over a single TCP connection, actively maintained by Hashicorp and e.g. used in Hashicorp's Nomad.
51
+
I.e., using Yamux, Go's `net/http` works out-of-the-box.
0 commit comments