$30 off During Our Annual Pro Sale. View Details »

Creating Containers with Golang

Creating Containers with Golang

@Geeks Who Drink in Fukuoka -Go Go Golang Edition!-
2017/06/28
https://nulab.connpass.com/event/57238/

KONDO Uchio

June 28, 2017
Tweet

More Decks by KONDO Uchio

Other Decks in Technology

Transcript

  1. Introduction to Handmade Containers!! Uchio Kondo / GMO Pepabo, Inc.

    2017.06.27 Geeks Who Drink Creating Containers
 Using Golang
  2. Engineer Uchio Kondo @udzura GMO Pepabo / Dev Productivity Team

    System Programming Newbie Favorite syscall: ptrace(2) Favorite ramen: ΒʔΊΜ޻๪ཾ (in Kitakyu)
  3. libcontainer •RunC: Internal container engine of Docker, written in Golang

    •libcontainer: Internal library of RunC •Using libcontainer, you can create containers for your own purpose. • You can get GitHub 2,000 stars⭐ with your own container!!
  4. Go-native container features •Golang itself supports container features, such as:

    •syscall package: • func syscall.Chroot • func syscall.Exec •exec.Cmd’s SysProcAttr member IUUQTHPMBOHPSHQLHPTFYFD$NE IUUQTHPMBOHPSHQLHTZTDBMM
  5. Setting up root filesystems •Using docker export $ sudo su

    - # mkdir -p /tmp/gwd && docker export $(docker run -d \ debian:stretch /bin/sleep 9999) | tar xvf - -C /tmp/gwd ## Provision: name resolution in container # cp /etc/resolv.conf /tmp/gwd/etc/resolv.conf # cp `which ps` /tmp/gwd/bin/ ## installs just ps... # cp /lib/x86_64-linux-gnu/libprocps.so.4 \ /tmp/gwd/lib/x86_64-linux-gnu/
  6. Smallest implementation of chroot(1) package main import ( "os" "syscall"

    ) func must(e error) { if e != nil { panic(e) } } func main() { must(syscall.Chroot(os.Args[1])) must(syscall.Chdir("/")) must(syscall.Exec("/bin/sh", []string{}, os.Environ())) }
  7. It works!! Compiling source with GOOS=linux Move it to vagrant

    box, then kick And now I’m in the Debian!!
  8. A namespace wraps a global system resource in an abstraction

    that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource... “man 7 namespaces”
  9. In a picture Global UTS namespace hostname: foo.example.com unshared namespace

    hostname: bar.example.com hostname: xxx.example.com hostname: zzz.example.com A Process
  10. In a picture Global UTS namespace hostname: foo.example.com unshared namespace

    hostname: bar.example.com hostname: xxx.example.com hostname: zzz.example.com A Process If some of processes unshared its UTS namespace, these processes can have their own hostname even in the same machine
  11. Write some code package main import ( "os" "os/exec" "syscall"

    ) func must(e error) { if e != nil { panic(e) } } func main() { must(syscall.Chroot(os.Args[1])) must(syscall.Chdir("/")) cmd := exec.Command("/bin/sh") cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.SysProcAttr = &syscall.SysProcAttr{Cloneflags: syscall.CLONE_NEWPID} must(cmd.Run()) }
  12. See also (many in Japanese...) •Full golang source code by

    @hayajo •ʮGoͰͭ͘ΔLinuxίϯςφʯPresentation •...And his movie •Thanks @hayajo for the basic idea and implementation!!! IUUQTHJTUHJUIVCDPNIBZBKPDBCBCGECFGF IUUQTTQFBLFSEFDLDPNIBZBKPDUTUVEZ IUUQTZPVUVCFHJ2DKD:QMX