mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Implemented a self-injecting process wrapper that runs inside the container
- Before starting the container, docker injects itself inside the container by mount binding the dockerd binary into /sbin/init - Instead of running the user process directly inside the container, we run /sbin/init targetprocess [args...] - When docker is run as /sbin/init (e.g. argv[0] == "/sbin/init"), then its own sys init code kicks in - The sys init code will be responsible for setting up the process environment prior to its execution (setuid, networking, ...). - Finally, docker's sys init will exec() the container's process, thus replacing itself with the target binary (which will be running as pid 1)
This commit is contained in:
parent
0d46006269
commit
58a2294260
5 changed files with 53 additions and 0 deletions
|
@ -16,6 +16,12 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var sysInitPath string
|
||||
|
||||
func init() {
|
||||
sysInitPath = SelfPath()
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Id string
|
||||
Root string
|
||||
|
@ -29,6 +35,7 @@ type Container struct {
|
|||
Filesystem *Filesystem
|
||||
State *State
|
||||
|
||||
SysInitPath string
|
||||
lxcConfigPath string
|
||||
cmd *exec.Cmd
|
||||
stdout *writeBroadcaster
|
||||
|
@ -58,6 +65,7 @@ func createContainer(id string, root string, command string, args []string, laye
|
|||
Filesystem: newFilesystem(path.Join(root, "rootfs"), path.Join(root, "rw"), layers),
|
||||
State: newState(),
|
||||
|
||||
SysInitPath: sysInitPath,
|
||||
lxcConfigPath: path.Join(root, "config.lxc"),
|
||||
stdout: newWriteBroadcaster(),
|
||||
stderr: newWriteBroadcaster(),
|
||||
|
@ -261,6 +269,7 @@ func (container *Container) Start() error {
|
|||
"-n", container.Id,
|
||||
"-f", container.lxcConfigPath,
|
||||
"--",
|
||||
"/sbin/init",
|
||||
container.Path,
|
||||
}
|
||||
params = append(params, container.Args...)
|
||||
|
|
|
@ -6,6 +6,13 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// Hack to run sys init during unit testing
|
||||
func init() {
|
||||
if SelfPath() == "/sbin/init" {
|
||||
SysInit()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestDocker() (*Docker, error) {
|
||||
root, err := ioutil.TempDir("", "docker-test")
|
||||
if err != nil {
|
||||
|
|
|
@ -705,6 +705,11 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout io.Writer, args ...string)
|
|||
}
|
||||
|
||||
func main() {
|
||||
if docker.SelfPath() == "/sbin/init" {
|
||||
// Running in init mode
|
||||
docker.SysInit()
|
||||
return
|
||||
}
|
||||
future.Seed()
|
||||
flag.Parse()
|
||||
d, err := New()
|
||||
|
|
|
@ -74,6 +74,9 @@ lxc.mount.entry = devpts {{$ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,no
|
|||
#lxc.mount.entry = varlock {{$ROOTFS}}/var/lock tmpfs size=1024k,nosuid,nodev,noexec 0 0
|
||||
#lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
|
||||
|
||||
# Inject docker-init
|
||||
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/sbin/init none bind,ro 0 0
|
||||
|
||||
# In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
|
||||
lxc.mount.entry = /etc/resolv.conf {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0
|
||||
|
||||
|
|
29
sysinit.go
Normal file
29
sysinit.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Sys Init code
|
||||
// This code is run INSIDE the container and is responsible for setting
|
||||
// up the environment before running the actual process
|
||||
func SysInit() {
|
||||
if len(os.Args) <= 1 {
|
||||
fmt.Println("You should not invoke docker-init manually")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(os.Args[1])
|
||||
if err != nil {
|
||||
log.Printf("Unable to locate %v", os.Args[1])
|
||||
os.Exit(127)
|
||||
}
|
||||
|
||||
if err := syscall.Exec(path, os.Args[1:], os.Environ()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue