●
●
●
+ run input commands with arguments
++ add hostname limitations
+++ add process ID limitations
++++ add mount/filesystem limitations
func main() {
switch os.Args[1] {
case "run":
run()
default:
panic("what?")
}
}
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
must(cmd.Run())
}
func must(err error) {
if err != nil {
panic(err)
}
}
---- take inputs and executes them
---- panics with non-”run” command
🎉 And it successfully echoes “Hello”!
----- opens shell to “container process”
------ can check hostname
------ can CHANGE hostname!!!
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
can see all processes on the host
machine
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
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
----- child process has a PID of one!
can still see processes on host machine
‘ps’ is looking in the /proc directory
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
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
● ✔
● ✔
●
● ✔
●
●
●
●
●
●
●
●
●
●
●
●
Source: https://docs.docker.com/engine/understanding-docker/
https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-docker
docker ecosystem
Source: https://github.com/nkhare/container-orchestration/blob/master/kubernetes/README.md
GKE
DigitalOcean k8s
CNCF (cloud native computing foundation)
Questions?
●
●
, Julien Friedman
● My demo code - @si74 on github
● An overview of the docker ecosystem
Containers: What are they, Really?

Containers: What are they, Really?

  • 5.
  • 8.
    + run inputcommands with arguments ++ add hostname limitations +++ add process ID limitations ++++ add mount/filesystem limitations
  • 9.
    func main() { switchos.Args[1] { case "run": run() default: panic("what?") } } 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 must(cmd.Run()) } func must(err error) { if err != nil { panic(err) } } ---- take inputs and executes them ---- panics with non-”run” command
  • 10.
    🎉 And itsuccessfully echoes “Hello”!
  • 11.
    ----- opens shellto “container process” ------ can check hostname ------ can CHANGE hostname!!!
  • 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
  • 15.
    can see allprocesses on the host machine
  • 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 processhas 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
  • 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
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
    CNCF (cloud nativecomputing foundation)
  • 32.
  • 33.
    ● ● , Julien Friedman ●My demo code - @si74 on github ● An overview of the docker ecosystem