运行 systemd 在 Docker 托管插件中

Running systemd in a Docker managed plugin

你如何在 Docker managed plugin? With a normal container I can run centos/systemd 和 运行 Apache 服务器中 运行 systemd 使用他们的示例 Dockerfile

FROM centos/systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD ["/usr/sbin/init"]

并且运行如下

docker build --rm --no-cache -t httpd .
docker run --privileged --name httpd -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 -d  httpd

但是,当我尝试制作托管插件时,cgroups 出现了一些问题

我试过 config.json

    {
        "destination": "/sys/fs/cgroup",
        "source": "/sys/fs/cgroup",
        "type": "bind",
        "options": [
            "bind",
            "ro",
            "private"
        ]
    }

    {
        "destination": "/sys/fs/cgroup",
        "source": "/sys/fs/cgroup",
        "type": "bind",
        "options": [
            "bind",
            "ro",
            "rprivate"
        ]
    }

    {
        "destination": "/sys/fs/cgroup",
        "source": "/sys/fs/cgroup",
        "type": "bind",
        "options": [
            "rbind",
            "ro",
            "rprivate"
        ]
    }

我还尝试了以下损坏主机 cgroup 的方法,可能需要硬重启才能恢复。

    {
        "destination": "/sys/fs/cgroup/systemd",
        "source": "/sys/fs/cgroup/systemd",
        "type": "bind",
        "options": [
            "bind",
            "ro",
            "private"
        ]
    }

    {
        "destination": "/sys/fs/cgroup",
        "source": "/sys/fs/cgroup",
        "type": "bind",
        "options": [
            "bind",
            "ro",
            "private"
        ]
    }

它看起来与 opencontainer 和 moby 的交互方式有关 https://github.com/moby/moby/issues/36861

您可以 运行 在没有 systemd 的 centos 容器中使用 httpd - 至少可以使用 docker-systemctl-replacement 脚本进行测试。

这就是我在 https://github.com/trajano/docker-volume-plugins/tree/master/centos-mounted-volume-plugin

上的做法

关键是在 systemd 开始之前保留 /run/docker/plugins 并擦除 /run 文件夹。然后确保在新文件夹中创建套接字。

mkdir -p /dockerplugins
if [ -e /run/docker/plugins ]
then
  mount --bind /run/docker/plugins /dockerplugins
fi

另一件事是 Docker 托管插件在配置中添加一个隐式 /sys/fs/cgroup AFTER 定义的挂载,因此创建只读挂载将不起作用,除非在启动systemd之前反弹。

mount --rbind /hostcgroup /sys/fs/cgroup

使用 config.json 中定义的坐骑作为

{
        "destination": "/hostcgroup",
        "source": "/sys/fs/cgroup",
        "type": "bind",
        "options": [
            "bind",
            "ro",
            "private"
        ]
}

创建套接字需要自定义,因为插件助手写入 /run/docker/plugins

l, err := sockets.NewUnixSocket("/dockerplugins/osmounted.sock", 0)
if err != nil {
    log.Fatal(err)
}
h.Serve(l)

下面展示了我是如何在我的插件上实现上面的过程的