Last active
February 20, 2022 14:21
-
-
Save kopos/8fddfdfdc30d497467b931bad6d347ab to your computer and use it in GitHub Desktop.
Building a container from scratch in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"os/exec" | |
"syscall" | |
) | |
// docker run <container> cmd args | |
// go run main.go run cmd args | |
func main() { | |
switch os.Args[1] { | |
case "run": | |
run() | |
case "child": | |
child() | |
default: | |
panic("what?") | |
} | |
} | |
func run() { | |
cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...) | |
cmd.Stdin = os.Stdin | |
cmd.Stdout = os.Stdout | |
cmd.Stderr = os.Stderr | |
cmd.SysProcAttr = &syscall.SysProcAttr{ | |
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID, | |
} | |
must(cmd.Run()) | |
} | |
func child() { | |
fmt.Printf("running %v as PID %d\n", os.Args[2:], os.Getpid()) | |
cmd := exec.Command(os.Args[2], os.Args[3:]...) | |
cmd.Stdin = os.Stdin | |
cmd.Stdout = os.Stdout | |
cmd.Stderr = os.Stderr | |
must(syscall.Chroot("/home/rootfs")) | |
must(os.Chdir("/")) | |
must(syscall.Mount("proc", "proc", "proc", 0, "")) | |
must(cmd.Run()) | |
} | |
func must(err error) { | |
if err != nil { | |
panic(err) | |
} | |
} |
With process isolation, cgroups.
Instead of the container depending on bash to spawn off a process, use the /proc/self/exe
to fork and run the executable itself in a new PID and run the command passed through run ...
With process isolation and root separation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From: Building a container from scratch in Go - Liz Rice (Microscaling Systems)
https://youtu.be/Utf-A4rODH8
Basic container. Spawn the process of the host OS via os.Args and exec.Command
so
go run build.go run /bin/bash
spawns a new bash shell