mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
Merge pull request #1650 from rhatdan/systemd
Mount proper cgroup for systemd to manage inside of the container.
This commit is contained in:
@ -346,6 +346,9 @@ type ContainerConfig struct {
|
|||||||
// IsInfra is a bool indicating whether this container is an infra container used for
|
// IsInfra is a bool indicating whether this container is an infra container used for
|
||||||
// sharing kernel namespaces in a pod
|
// sharing kernel namespaces in a pod
|
||||||
IsInfra bool `json:"pause"`
|
IsInfra bool `json:"pause"`
|
||||||
|
|
||||||
|
// Systemd tells libpod to setup the container in systemd mode
|
||||||
|
Systemd bool `json:"systemd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStatus returns a string representation for users
|
// ContainerStatus returns a string representation for users
|
||||||
|
@ -1682,6 +1682,8 @@ func easyjson1dbef17bDecodeGithubComContainersLibpodLibpod2(in *jlexer.Lexer, ou
|
|||||||
}
|
}
|
||||||
case "pause":
|
case "pause":
|
||||||
out.IsInfra = bool(in.Bool())
|
out.IsInfra = bool(in.Bool())
|
||||||
|
case "systemd":
|
||||||
|
out.Systemd = bool(in.Bool())
|
||||||
default:
|
default:
|
||||||
in.SkipRecursive()
|
in.SkipRecursive()
|
||||||
}
|
}
|
||||||
@ -2344,6 +2346,16 @@ func easyjson1dbef17bEncodeGithubComContainersLibpodLibpod2(out *jwriter.Writer,
|
|||||||
}
|
}
|
||||||
out.Bool(bool(in.IsInfra))
|
out.Bool(bool(in.IsInfra))
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const prefix string = ",\"systemd\":"
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
} else {
|
||||||
|
out.RawString(prefix)
|
||||||
|
}
|
||||||
|
out.Bool(bool(in.Systemd))
|
||||||
|
}
|
||||||
out.RawByte('}')
|
out.RawByte('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,10 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.config.Systemd {
|
||||||
|
c.setupSystemd(g.Mounts(), g)
|
||||||
|
}
|
||||||
|
|
||||||
// Look up and add groups the user belongs to, if a group wasn't directly specified
|
// Look up and add groups the user belongs to, if a group wasn't directly specified
|
||||||
if !rootless.IsRootless() && !strings.Contains(c.config.User, ":") {
|
if !rootless.IsRootless() && !strings.Contains(c.config.User, ":") {
|
||||||
groups, err := chrootuser.GetAdditionalGroupsForUser(c.state.Mountpoint, uint64(g.Config.Process.User.UID))
|
groups, err := chrootuser.GetAdditionalGroupsForUser(c.state.Mountpoint, uint64(g.Config.Process.User.UID))
|
||||||
@ -294,6 +298,43 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||||||
return g.Config, nil
|
return g.Config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// systemd expects to have /run, /run/lock and /tmp on tmpfs
|
||||||
|
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
|
||||||
|
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) {
|
||||||
|
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"}
|
||||||
|
for _, dest := range []string{"/run", "/run/lock"} {
|
||||||
|
if MountExists(mounts, dest) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpfsMnt := spec.Mount{
|
||||||
|
Destination: dest,
|
||||||
|
Type: "tmpfs",
|
||||||
|
Source: "tmpfs",
|
||||||
|
Options: append(options, "tmpcopyup", "size=65536k"),
|
||||||
|
}
|
||||||
|
g.AddMount(tmpfsMnt)
|
||||||
|
}
|
||||||
|
for _, dest := range []string{"/tmp", "/var/log/journal"} {
|
||||||
|
if MountExists(mounts, dest) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tmpfsMnt := spec.Mount{
|
||||||
|
Destination: dest,
|
||||||
|
Type: "tmpfs",
|
||||||
|
Source: "tmpfs",
|
||||||
|
Options: append(options, "tmpcopyup"),
|
||||||
|
}
|
||||||
|
g.AddMount(tmpfsMnt)
|
||||||
|
}
|
||||||
|
systemdMnt := spec.Mount{
|
||||||
|
Destination: "/sys/fs/cgroup/systemd",
|
||||||
|
Type: "bind",
|
||||||
|
Source: fmt.Sprintf("/sys/fs/cgroup/systemd%s/libpod-%s", CgroupfsDefaultCgroupParent, c.ID()),
|
||||||
|
Options: []string{"bind", "private"},
|
||||||
|
}
|
||||||
|
g.AddMount(systemdMnt)
|
||||||
|
}
|
||||||
|
|
||||||
// Add an existing container's namespace to the spec
|
// Add an existing container's namespace to the spec
|
||||||
func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error {
|
func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error {
|
||||||
nsCtr, err := c.runtime.state.Container(ctr)
|
nsCtr, err := c.runtime.state.Container(ctr)
|
||||||
|
@ -349,6 +349,18 @@ func WithShmDir(dir string) CtrCreateOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSystemd turns on systemd mode in the container
|
||||||
|
func WithSystemd() CtrCreateOption {
|
||||||
|
return func(ctr *Container) error {
|
||||||
|
if ctr.valid {
|
||||||
|
return ErrCtrFinalized
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr.config.Systemd = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithShmSize sets the size of /dev/shm tmpfs mount.
|
// WithShmSize sets the size of /dev/shm tmpfs mount.
|
||||||
func WithShmSize(size int64) CtrCreateOption {
|
func WithShmSize(size int64) CtrCreateOption {
|
||||||
return func(ctr *Container) error {
|
return func(ctr *Container) error {
|
||||||
|
@ -319,6 +319,10 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||||||
if c.Interactive {
|
if c.Interactive {
|
||||||
options = append(options, libpod.WithStdin())
|
options = append(options, libpod.WithStdin())
|
||||||
}
|
}
|
||||||
|
if c.Systemd && (strings.HasSuffix(c.Command[0], "init") ||
|
||||||
|
strings.HasSuffix(c.Command[0], "systemd")) {
|
||||||
|
options = append(options, libpod.WithSystemd())
|
||||||
|
}
|
||||||
if c.Name != "" {
|
if c.Name != "" {
|
||||||
logrus.Debugf("appending name %s", c.Name)
|
logrus.Debugf("appending name %s", c.Name)
|
||||||
options = append(options, libpod.WithName(c.Name))
|
options = append(options, libpod.WithName(c.Name))
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
"github.com/docker/docker/daemon/caps"
|
"github.com/docker/docker/daemon/caps"
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
@ -261,12 +260,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
|
|||||||
addedResources = true
|
addedResources = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Systemd && (strings.HasSuffix(config.Command[0], "init") ||
|
|
||||||
strings.HasSuffix(config.Command[0], "systemd")) {
|
|
||||||
if err := setupSystemd(config, &g); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to setup systemd")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, i := range config.Tmpfs {
|
for _, i := range config.Tmpfs {
|
||||||
// Default options if nothing passed
|
// Default options if nothing passed
|
||||||
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev", "size=65536k"}
|
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev", "size=65536k"}
|
||||||
@ -408,49 +401,6 @@ func blockAccessToKernelFilesystems(config *CreateConfig, g *generate.Generator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// systemd expects to have /run, /run/lock and /tmp on tmpfs
|
|
||||||
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
|
|
||||||
|
|
||||||
func setupSystemd(config *CreateConfig, g *generate.Generator) error {
|
|
||||||
mounts, err := config.GetVolumeMounts([]spec.Mount{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"}
|
|
||||||
for _, dest := range []string{"/run", "/run/lock"} {
|
|
||||||
if libpod.MountExists(mounts, dest) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tmpfsMnt := spec.Mount{
|
|
||||||
Destination: dest,
|
|
||||||
Type: "tmpfs",
|
|
||||||
Source: "tmpfs",
|
|
||||||
Options: append(options, "tmpcopyup", "size=65536k"),
|
|
||||||
}
|
|
||||||
g.AddMount(tmpfsMnt)
|
|
||||||
}
|
|
||||||
for _, dest := range []string{"/tmp", "/var/log/journal"} {
|
|
||||||
if libpod.MountExists(mounts, dest) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tmpfsMnt := spec.Mount{
|
|
||||||
Destination: dest,
|
|
||||||
Type: "tmpfs",
|
|
||||||
Source: "tmpfs",
|
|
||||||
Options: append(options, "tmpcopyup"),
|
|
||||||
}
|
|
||||||
g.AddMount(tmpfsMnt)
|
|
||||||
}
|
|
||||||
tmpfsMnt := spec.Mount{
|
|
||||||
Destination: "/sys/fs/cgroup/systemd",
|
|
||||||
Type: "tmpfs",
|
|
||||||
Source: "tmpfs",
|
|
||||||
Options: append(options, "size=65536k"),
|
|
||||||
}
|
|
||||||
g.AddMount(tmpfsMnt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
||||||
pidMode := config.PidMode
|
pidMode := config.PidMode
|
||||||
if IsNS(string(pidMode)) {
|
if IsNS(string(pidMode)) {
|
||||||
|
Reference in New Issue
Block a user