Skip to content

Commit b5fdf90

Browse files
committed
containerdexecutor: add network namespace callback
In order to support identity mapping and user namespaces, the Moby project needs to defer the creation of a container's network namespace to the runtime and hook into the container lifecycle to configure the network namespace before the user binary is started. The standard way to do so is by configuring a `createRuntime` OCI lifecycle hook, in which the OCI runtime executes a specified process in the runtime environment after the container has been created and before it is started. In the case of Moby the network namespace needs to be configured from the daemon process, which necessitates that the hook process communicate with the daemon process. This is complicated and slow. All the hook process does is inform the daemon of the container's PID and wait until the daemon has finished applying the network namespace configuration. There is an alternative to the `createRuntime` OCI hook which containerd clients can take advantage of. The `container.NewTask` method is directly analogous to the OCI create operation, and the `task.Start` method is directly analogous to the OCI start operation. Any operations performed between the `NewTask` and `Start` calls are therefore directly analogous to `createRuntime` OCI hooks, without needing to execute any external processes! Provide a mechanism for network.Namespace instances to register a callback function which can be used to configure a container's network namespace instead of, or in addition to, `createRuntime` OCI hooks. Signed-off-by: Cory Snider <[email protected]>
1 parent 14fa4f2 commit b5fdf90

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

executor/containerdexecutor/executor.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ type containerdExecutor struct {
4545
rootless bool
4646
}
4747

48+
// OnCreateRuntimer provides an alternative to OCI hooks for applying network
49+
// configuration to a container. If the [network.Provider] returns a
50+
// [network.Namespace] which also implements this interface, the containerd
51+
// executor will run the callback at the appropriate point in the container
52+
// lifecycle.
53+
type OnCreateRuntimer interface {
54+
// OnCreateRuntime is analogous to the createRuntime OCI hook. The
55+
// function is called after the container is created, before the user
56+
// process has been executed. The argument is the container PID in the
57+
// runtime namespace.
58+
OnCreateRuntime(pid uint32) error
59+
}
60+
4861
// New creates a new executor backed by connection to containerd API
4962
func New(client *containerd.Client, root, cgroup string, networkProviders map[pb.NetMode]network.Provider, dnsConfig *oci.DNSConfig, apparmorProfile string, selinux bool, traceSocket string, rootless bool) executor.Executor {
5063
// clean up old hosts/resolv.conf file. ignore errors
@@ -210,6 +223,12 @@ func (w *containerdExecutor) Run(ctx context.Context, id string, root executor.M
210223
}
211224
}()
212225

226+
if nn, ok := namespace.(OnCreateRuntimer); ok {
227+
if err := nn.OnCreateRuntime(task.Pid()); err != nil {
228+
return err
229+
}
230+
}
231+
213232
trace.SpanFromContext(ctx).AddEvent("Container created")
214233
err = w.runProcess(ctx, task, process.Resize, process.Signal, func() {
215234
startedOnce.Do(func() {

0 commit comments

Comments
 (0)