4 ms·
> Well, Go seems to have enabled a new wave of software renaissance - Kubernetes, Docker Go turned out to be a pretty bad choice for container tech due to its
by zzzcpan 7y ago
> Well, Go seems to have enabled a new wave of software renaissance - Kubernetes, Docker
Go turned out to be a pretty bad choice for container tech due to its awful multithreaded runtime. Things could have been different if it focused on a single threaded runtime or provided control over OS threads, but it did neither.
Also neither of those projects were enabled by Go. One is a pretty low quality but strategic push into the cloud and other one is a pivot from an attempt to solve real problems of building a PaaS hosting platform.
- fpoling 7y agoModern Go solved the problem of control over native threads threads. But it is puzzling indeed that it took almost 10 years despite popularity with containers.
- cpuguy83 7y agoOnly partially... what's available at least prevents leaking the context unexpectedly to other goroutines (due to thread re-use), however anything that spins up a new goroutine from the locked goroutine will end up in a new thread in a totally different context. Even stdlib spins up new goroutines.
- otterley 7y ago> Go turned out to be a pretty bad choice for container tech due to its awful multithreaded runtime. Can you please elaborate on this? My experience with Go is that it is able to fork/exec programs and manage cgroups via sysfs on Linux at least as well as any other programming language can.
- cpuguy83 7y agoYou pretty much need to do everything from a separate process, which is the main issue. Certain things like setns(mountns) will straight up fail in a multithreaded program, so there are some nasty hacks in runc to handle such things in C prior to the go runtime firing up.
- otterley 7y ago> You pretty much need to do everything from a separate process, which is the main issue. I’m confused. fork()/spawn() are the proper means to launch child processes on Linux. What language would do things differently if the syscall determines the means here?
- cpuguy83 7y agoBecause go is always multithreaded. You literally cannot do certain system level things in Go. For instance trying to "setns" to a mount namespace will yield EINVAL from the kernel in all cases with Go. In fact, all namespace related operations are really annoying to do from Go because the runtime is always multithreaded and you have no control over the threading except for locking the active goroutine to its currently assigned thread. This also makes that thread unusable for any new goroutine (even goroutines that are spawned from code running in that thread), which has the side-effect that the new goroutine will always be in the original namespace context.
- lossolo 7y ago> Go turned out to be a pretty bad choice for container tech due to its awful multithreaded runtime. What you mean by that? What makes it a bad choice in context of containers ? I ask because I know how Go is using M:N threading model in its runtime and what linux containers really are, but I can't find a reason in which I would use word awful to describe using Go in this context.
- cpuguy83 7y agoBecause container tech is often per-thread which you have no control over in Go. There is runtime.LockOSThread(), but then if something happens to spin up a new groutine from there it will be done on a new os thread and not running in the container context. It's not totally impossible to work around, however it does make many things incredibly frustrating.