Libcontainer - 在容器中运行多个进程

我正在尝试实现一些效果docker run并docker exec使用libcontainer.


我已经能够使用以下代码创建一个容器并在其中运行一个进程:


func Run(id string, s *specs.LinuxSpec, f *Factory) (int, error) {

    ...

    container, err := f.CreateContainer(id, config)

    if err != nil {

        return -1, err

    }


    process := newProcess(s.Process)

    tty, err := newTty(s.Process.Terminal, process, rootuid)

    defer tty.Close()

    if err != nil {

        return -1, err

    }


    defer func() {

        if derr := Destroy(container); derr != nil {

            err = derr

        }

    }()


    handler := NewSignalHandler(tty)

    defer handler.Close()

    if err := container.Start(process); err != nil {

        return -1, err

    }


    return handler.forward(process)

}

这很好用(我相信),但是当我必须在同一个容器中运行另一个进程时,问题就来了。例如,一个容器已经在运行(主进程在前台模式下运行):我怎样才能实现 Docker 允许你做的事情docker exec?


我有以下代码:


func Exec(container libcontainer.Container, process *libcontainer.Process, onData func(data []byte), onErr func(err error)) (int, error) {

    reader, writer := io.Pipe()

    process.Stdin = os.Stdin


    rootuid, err := container.Config().HostUID()

    if err != nil {

        return -1, err

    }


    tty, err := newTty(true, process, rootuid)

    defer tty.Close()

    if err != nil {

        return -1, err

    }


    handler := NewSignalHandler(tty)

    defer handler.Close()


    // Redirect process output

    process.Stdout = writer

    process.Stderr = writer


    // Todo: Fix this, it waits for the main process to exit before it starts

    if err := container.Start(process); err != nil {

        return -1, err

    }


    go func(reader io.Reader) {

        scanner := bufio.NewScanner(reader)

        for scanner.Scan() {

            onData(scanner.Bytes())

        }

        if err := scanner.Err(); err != nil {

            onErr(err)

        }

    }(reader)


    return handler.forward(process)

}

这也有效,但问题是:它在运行之前等待主进程退出。有时它会运行,但是100%在运行一个简单的whoami命令5 到 7 次调用该函数后,我的记忆就会消失。


我很确定我做错了什么,我只是不知道是什么。还是我对容器的理解让我失望?


我用这个项目作为参考:https : //github.com/opencontainers/runc


慕尼黑8549860
浏览 191回答 1
1回答

繁星点点滴滴

最好使用 docker 作为您的案例的参考,因为它使用相同的libcontainer.Container对象在容器中启动和执行新进程。你可以在这里找到与 libcontainer 交互的代码:https : //github.com/docker/docker/tree/master/daemon/execdriver/native此外,最好发布整个代码,以便人们可以尝试对其进行调试以帮助您。编辑:这是运行多个容器的示例代码:https : //gist.github.com/anonymous/407eb530c0cb6c87ec9f我运行它就像go run procs.go path-to-busybox您可以看到ps容器中确实有多个进程。如果您有任何问题,请随时提问。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go