Support systemd in containers with podman-style --systemd flag#2785
Conversation
| cmd.Flags().StringSlice("cap-drop", []string{}, "Drop Linux capabilities") | ||
| cmd.RegisterFlagCompletionFunc("cap-drop", capShellComplete) | ||
| cmd.Flags().Bool("privileged", false, "Give extended privileges to this container") | ||
| cmd.Flags().String("systemd", "false", "Enable systemd integration (default: false)") |
There was a problem hiding this comment.
This differs from the podman flag, which has a default value of true
| return nil, nil, err | ||
| } | ||
| cOpts = append(cOpts, restartOpts...) | ||
| cOpts = append(cOpts, withStop(options.StopSignal, options.StopTimeout, ensuredImage)) |
There was a problem hiding this comment.
| systemdPaths := []string{ | ||
| "/usr/sbin/init", | ||
| "/sbin/init", | ||
| "/usr/local/sbin/init", |
There was a problem hiding this comment.
Is there any image that has /usr/local/sbin/init?
There was a problem hiding this comment.
I set these to be the same as podman:
true enables systemd mode only when the command executed inside the container is systemd, /usr/sbin/init, /sbin/init or /usr/local/sbin/init.
(But, most images I have seen use /sbin/init)
https://docs.podman.io/en/latest/markdown/podman-run.1.html#systemd-true-false-always
|
|
||
| systemdPaths := []string{ | ||
| "/usr/sbin/init", | ||
| "/sbin/init", |
There was a problem hiding this comment.
Wondering if /sbin should have higher priority over /usr/sbin
There was a problem hiding this comment.
Yeah, /sbin/init is more common. I'll move higher
|
|
||
| // See: https://github.com/containers/podman/issues/15878 | ||
| if !privilegedWithoutHostDevices { | ||
| return nil, nil, errors.New("If --privileged is used with systemd `--security-opt privileged-without-host-devices` must also be used") |
There was a problem hiding this comment.
In the podman implementation all /dev/tty* devices are unmounted to prevent causing host to crash
I could not find an easy to achieve this, so instead I return an error (also prevents causing host to crash). If that functionality is required, maybe it can be added in a future PR
| "path" | ||
| "path/filepath" | ||
| "runtime" | ||
| "slices" |
There was a problem hiding this comment.
This doesn't work with Go 1.20.
I guess we can drop the support for Go 1.20 though.
There was a problem hiding this comment.
Switch to using or statement to maintain compatibility with 1.20
| - :whale: `--cap-add=<CAP>`: Add Linux capabilities | ||
| - :whale: `--cap-drop=<CAP>`: Drop Linux capabilities | ||
| - :whale: `--privileged`: Give extended privileges to this container | ||
| - :nerd_face: `--systemd=(true|false|always)`: Enable systemd compatibility (default: false). |
There was a problem hiding this comment.
How does always differ from true?
There was a problem hiding this comment.
There was a problem hiding this comment.
Added some more to docs about the options and added a note to nerdctl specific features in README:
https://github.com/containerd/nerdctl/pull/2785/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R206
| {Type: "tmpfs", Source: "tmpfs", Destination: "/var/lib/journal"}, | ||
| }), | ||
| ) | ||
| stopSignal = "SIGRTMIN+3" |
There was a problem hiding this comment.
SIGTERM causes restart in systemd (This functionality is the same as podman)
See:
https://www.freedesktop.org/software/systemd/man/latest/systemd.html#Signals
|
Thanks,
|
| } else if len(ensured.ImageConfig.Cmd) > 0 { | ||
| entrypointPath = ensured.ImageConfig.Cmd[0] | ||
| } | ||
|
|
There was a problem hiding this comment.
There might be an easier way to determine the entrypoint executable path, if there is I am open to updating
| done | ||
| echo "signal quit"`).AssertOK() | ||
| base.Cmd("stop", testContainerName).AssertOK() | ||
| base.Cmd("inspect", "--format", "{{json .Config.Labels}}", testContainerName).AssertOutContains("SIGQUIT") |
There was a problem hiding this comment.
Saw that this test was not checking container labels, so added assert
| DockerAuthImage = mirrorOf("cesanta/docker_auth:1.7") | ||
| FluentdImage = mirrorOf("fluent/fluentd:v1.14-1") | ||
| KuboImage = mirrorOf("ipfs/kubo:v0.16.0") | ||
| SystemdImage = "ghcr.io/containerd/stargz-snapshotter:0.15.1-kind" |
There was a problem hiding this comment.
Those this image since it has a working systemd and is controlled by containerd
5cd85bf to
ed090fb
Compare
(with --systemd flag) Signed-off-by: Spencer von der Ohe <s.vonderohe40@gmail.com>
|
@AkihiroSuda I have added some tests and squashed the commits. Could you please have another look? |
| } | ||
|
|
||
| opts = append(opts, | ||
| oci.WithoutMounts("/sys/fs/cgroup"), |
There was a problem hiding this comment.
@sazzy4o I found your change while looking into supporting containers with systemd using k8s + containerd. I did the tmpfs mounts for /run, /tmp/, etc., but I was mounting the host's /sys/fs/cgroup as ready-only, which didn't work.
Here, you are removing the mount, which caught my attention. Is this so that systemd creates /sys/fs/cgroup when it initializes?
There was a problem hiding this comment.
@jfernandez Yes, this allow systemd to run inside the container and create /sys/fs/cgroup
This was based on the podman --systemd flag
Adds support for systemd to
nerdctlwith a--systemdbased on the flag used in podmanFixes #2784
Usage: