The document discusses containerization using Docker. It begins with an overview of Docker commands to run containers with increasing levels of isolation for hostname, process ID, and filesystem/mounting. It then demonstrates how to execute commands in a container using Linux namespaces to isolate processes and filesystems. The document aims to show how Docker containers can isolate and sandbox processes running on a machine.
11. ----- opens shell to “container process”
------ can check hostname
------ can CHANGE hostname!!!
12.
13.
14. func run() {
fmt.Pintf("running %vn", os.Args[2:])
cmd := exec.Command(os.Args[2],
os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS,
}
must(cmd.Run())
}
cmd will be executed with linux flag for calling a child process, which runs in a new UTS
namespace
16. func run() {
fmt.Printf("running %vn", os.Args[2:])
cmd := exec.Command(os.Args[2],
os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |
syscall.CLONE_NEWPID,
}
must(cmd.Run())
}
why can we still the parent namespace?
----- execute cmd in new PID and new UTS namespace
17. func run() {
cmd := exec.Command("/proc/self/exe", append([]string{"child"},
os.Args[2:]...)...)
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
}
must(cmd.Run())
}
func child() {
fmt.Printf("running %v as pid %vn", os.Args[2:], os.Getpid())
cmd := exec.Command(os.Args[2], os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
must(cmd.Run())
}
----- let’s try this again but fork off a child process
18. ----- child process has a PID of one!
can still see processes on host machine
‘ps’ is looking in the /proc directory
19. func run() {
md := exec.Command("/proc/self/exe", append([]string{"child"},
os.Args[2:]...)...) // link to currently running process
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID |
syscall.CLONE_NEWNS,
}
must(cmd.Run())
}
------ NEWNS flag for mount namespace is creating a
“mount table” for the process, allowing it to have it’s own
filesystem
20.
21. func child() {
fmt.Printf("running %v as pid%vn", os.Args[2:], os.Getpid())
cmd := exec.Command(os.Args[2], os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
must(syscall.Chroot("/home/rootfs"))
must(os.Chdir("/"))
must(syscall.Mount("proc", "proc", "proc", 0, ""))
must(cmd.Run())
}
TODO
Need a new root filsystem
w/ empty /proc directory