3. Docker runtime adopted Go
• Promoted wider adoption of Go as a systems language
• Bug fixes in Docker produced more Go programmers
• Identifying systems level problem in Go runtime related to syscalls / threads
4. Isolation in Docker container: namespaces
• Process trees (PID Namespace)
• Mounts (MNT namespace)
• Network (Net namespace)
• Users / UIDs (User Namespace)
• Hostnames (UTS Namespace)
• Inter Process Communication (IPC Namespace)
6. Running a Go Process on Linux machine
eth0 Linux machine
Go Process
OS thread
Goroutine
7. Add new Network Namespace with lo
(loopback) only interface
eth0
net namespaces n
Linux machine
Go Process
OS thread
Goroutine
8. Adding worker goroutines to new network
namespaces
eth0
Worker
goroutines
net namespaces n
Linux machine
Go Process
OS thread
Goroutine
runtime.LockOSThread()
9. Adding worker goroutines to host network
namespace
eth0
Worker
goroutines
net namespaces n
Linux machine
Go Process
OS thread
Goroutine
runtime.LockOSThread()
10. Adding worker goroutines to host network
namespace
eth0
more
Worker
goroutines
net namespaces n
Linux machine Go Process
OS thread
Goroutine
runtime.LockOSThread()
11. Incorrect interfaces detected by goroutines
eth0
more
Worker
goroutines
net namespaces n
Linux machine Go Process
goroutine
with wrong
interface info
28. runtime.LockOSThread()
M P G
M P G
M P G G G
M P G G G G G G
Global queue
Goroutine called
LockOSThread()
M
P
G
OS thread
Processor
(Logical)
Goroutine
runtime.LockOSThread()
31. How to manage network namespaces
with Go 1.10 and beyond
ns := createNetNamespace()
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ns.Do(func(_ ns.NetNS) error {
runtime.LockOSThread()
cb()
}
If the goroutine here changes the state of the
thread, let the thread exit with goroutine
32. Bonus feature
• OS thread terminates if goroutine exits
• runtime.LockOSThread() is nested.
• UnlockOSThread must be called the same number of times in order to unlock the thread.