Hacker News new | past | comments | ask | show | jobs | submit login
Docker and Go: why did we decide to write Docker in Go? (slideshare.net)
129 points by sylvainkalache on Nov 11, 2013 | hide | past | favorite | 62 comments

For me it is Go vs Erlang. I see both solving similar set of problems (for me!).

The slides said Go is easier than Erlang. That is true in some aspects, namely syntax (Elixir to the rescue here!). Go is also easier because of static typing. Speed of compilation is awesome. Building to an executable that only depends on libc -- yes please! love that about Go.

I am scared about safety and fault tolerance. Ability to share memory is good for performance but a shared heap in a large concurrent application is scary to me. Not sure what I think about multiple channels and running select over them. Then it pseudo-randomly choosing one channel among those that can receive. Erlang's focus on processes/actors vs channel and each actor having a single mailbox somehow makes more sense to me. Having a shared heap mean faster data processing but GC cannot be fully concurrent.

Now passing channels inside other channels is cool, but also kind of scary to me. You can pass channels, inside channels, inside channels, can make some kind of a lazy computation chain.

Also I have been wondering, but couldn't find it by doing a quick search, is it possible to build supervision trees out of goroutines like one builds supervision trees in Erlang's OTP. Say I want to have a chat client goroutine to keep the chat up. But I want to monitor it in case it crashes (panics?) then then spawn another one perhaps. Is that possible?

As someone who has shipped production software in both Erlang and Go. They are very different beasts. Regarding error handling, Go is far closer to C than Erlang. If Erlangs slogan is "let it fail" and gives you the power to avoid writing error handling for every single thing, Go's is "don't let it fail" ... and you really need to write error handlers for everything, reducing the "unexpected" footprint.

There is no real way to grab a goroutine from the outside and tell it what to do -- you have to use its channels, which if bad things have happened are probably broken.. there are some systems built that catch exceptions and send messages (this is from inside the goroutine of course) on the channel, but I haven't used them.

That might come across an unduly negative of Go, but Go has major upsides. Great tooling, easy to understand after a tiny amount of time, a culture of explicit (even at times non-DRY) code, amazing deploy model, and generally just very understandable even to newcomers.

Interesting, thank you for explaining. The lack of monitoring of goroutines is certainly different.

> which if bad things have happened are probably broken.

It reminds me of Joe Armstrong's quote about how it is hard to perform surgery on yourself. In other words having the component that is failing trying to fix itself. I guess I would have to read more about design patterns. I saw a presentation about concurrency patterns in go, but it is about very simple toy examples, I am more interested in a larger concurrent applications, handling multiple connections for example.

Yeah... so far my Go stuff has had exceptional reliability, I verified I handled all error known conditions with errcheck (https://github.com/kisielk/errcheck) and just generally took the slow and plodding approach of handling everything explicitly. My app handles hundreds of thousands of concurrent connections, each one often using and/or spawning 4 or more goroutines.

Thanks for the errcheck link, I will be using that. Would Go authors consider building that into the compiler? That would make quite a bit of sense.

As soon as I first used errcheck, I thought the exact same thing... "this should be included as warnings"

I've found net/http package source code to be useful on this matter, as the package contains production-ready servers and clients implemented in Go itself.

Yes Erlang also has good libraries for that. My question wasn't as much about libraries as about supervision trees.

Having a part of your program fail and restarted if needed. For what I understand so far that isn't possible. It would have to be done at the OS process level instead.

When I'm using Go and have a goroutine which could possibly fail, I also return an error channel allowing the caller to handle errors from inside the goroutine.

I share the exact same sentiments as you, and, would also love to know if there is anyway to mimic something like the OTP supervision tree. One-for-one? One-for-all?

Not on the Go level. You can't guarantee memory safety after a panic since it's shared between the goroutines. It's also not possible to do code live-reload.

On the unix level it would be possible if your process manager supports dependencies between processes and you're able to connect pipes between them. This would also be much more heavy than erlang threads in terms of memory.

I love Go and want to see it succeed, but as long as "why I wrote X in Go" is a novel thing, Go maybe hasn't made it yet. There are probably thousands of wonderful Python libraries and sure sometimes people decide to talk about why those chose Python, but all of these "Why Go?" posts feel a bit like a forced explanation to the question "Why did you write X in some new language that almost nobody else is using?"

But that isn't true anymore. Lots of people and teams are using Go. You don't need to explain yourself. Just write stuff in Go. Maybe even write about the process of how you wrote your app in Go, but stop making it about the language. It's there, it works. No need to apologize, evangelize or explain yourself.

No, it is totally relevant. Sure you can write docker in Perl in Bash or even in lolcode if you really want to. Each language has its strength and weakness. If everyone is language agnostic why do we bother to invest in Rust when C++ is just good enough in the first place? Why do people here keep inventing a new language? Why Javascript if we could just use Java back in the 90s?

Does the language provide some facility that allows docker developers to make docker easier to write and easier to scale than writing docker in Python? Totally relevant. People experiment with new language and hearing Go is scalable and Go is about concurrency - what do these things mean to docker inventors? As a library writer I want to understand what makes Go their choice when Ruby, Python, C and Java seems to the primary languages people use to write system tool.

If I were to write a similar tool like docker in Go, what patterns can I learn from reading docker?

If anything, I'd like to see more 'why I wrote X in Python', and 'why I wrote Y in Java' pieces.

I suspect in many cases the answer is 'because I've invested time in learning it' rather than technical benefits. Not that this is a bad reason.

I would love to see more articles like this. Not just for Go, but for all kinds of technologies. A lot of real world case studies would make it easier to evaluate new technologies, and help justify decisions to management.

Wouldn't it be great if audio of a presentation were also available and the slides were played in sync with it?

Imagine if presentation software generated a coded tone for each transition that could be used later on to merge the recorded audio of the speaker and the slides into an audio slideshow.

Then having a video of your presentation would just be a side effect of your presentation. And it would focus on the material you wanted to present, not your image.

Although videos of speakers are nice, often the material the speaker is referring to isn't visible. It really should be the visual focus.

I wish people would post their notes and not their slides. If I can understand your talk from your slides, your slides are way too detailed, and it might be more beneficial to just give everyone the text and not bother with the speaking, since it's so much slower than reading.

And if there's a video, I'm going to immediately go somewhere else. I don't have time to be watching hour-long videos when the content could be summarized in something I could read in 5 minutes.

Not everyone has notes. When I lecture, I do so from notes, but I usually do other presentations without them. I'll likely have created an outline, but it has less information than the slides.

InfoQ does this pretty well. Sadly, their website isn't the pinnacle of user experience.

My university uses [Mediasite](http://www.sonicfoundry.com/mediasite) to record our lectures. It does a pretty good job of syncing slides to video, though it is Silverlight-based.

The only real problem is that it seems to detect slides based on delta with previous slide instead of getting information from the actual presentation. This means that if you switch to the lecturer's camera (which allows the lecturer to display text written on paper on a big screen) or write on the slide then it counts as a new slide.

This is a ridiculously easy to solve problem. Timecode, click tracks, or even just recording the output of the presentation machine are all viable and simple options. Conference organizers just have to do it.

And if presentation software played the tones, anybody could record the audio at even an informal meeting and tie it to the slides. The speaker could just do it with their phone.

If the presentation software makers wanted to close the loop, they could just give you an app that records the audio, listens for the tones, uploads it to their site where you've saved your slides and automatically put it all together where anybody can see the final product.

Yep, this would be so great.

I've wished for so long that slides and presentations were synced, the best I've seen are videos like DEFCON where they have a small window for the presenter then slideshow.

Something within the range of microphones but nothing that'll be annoying when the speaker changes slides?

That's a cool idea.

It isn't a new idea, it just may not be common. I've seen video/presentations for a decade. The implementation I remember used WMVs as the video source, but I'm sure it could have just as easily been WMA or another media format.

I wish were more common though.

Yes, its not new. My old company, Mentorware, created content from syncing slides and audio for the Java One conference starting in 2000.

But putting these together was a manual effort. This idea would eliminate that.

You'd only really need to synchronize the audio and slides at a single point (perhaps this could happen backstage, before the presentation begins). After this, you can just record relative timestamps for each slide transition.

Comments on slide 28:

"go get, can't pin a particular revision"

- There's an elegant solution by now, see https://github.com/kr/godep

"must deal with private repos manually"

- go get can get them via ssh using key auth, just do https://gist.github.com/shurcooL/6927554


godep is definitely cool. But it's a bit sad that it has to be an add-on. Don't get me wrong -- it's a great thing that go gives us a good build system, a good test system, a good dependency system, etc. But if we end up using another build system, another test system, another dependency system, because the stock ones aren't powerful enough, it kind of ruins it :-)

Regarding private repos: IMHO it's much simpler to go to your $GOPATH/src/github.com/blahblah and `git clone git@github.com:blahblah/repo`. But if you know a difference between both approaches I would be happy to hear it!

> it's a great thing that go gives us a good build system, a good test system, a good dependency system, etc. But if we end up using another build system, another test system, another dependency system, because the stock ones aren't powerful enough, it kind of ruins it :-)

That's the thing, godep isn't another build system. It's built on _top_ of the existing Go build system. It augments it, doesn't replace it or replicate what's already there.

Go has tools for building at master; godep adds a file that keeps track of explicit commits and creates a sandbox GOPATH with those revisions checked out. Nothing you couldn't do by hand; godep simply automates the task, making it reproducible.

The reason Go doesn't have everything is because the developers haven't found a very good solution for everything. So instead of providing something crappy, they just don't include it... Until a later time. This gives the community time to experiment and find a good solution in the meantime.

Honestly, I'm very glad they're taking this approach.

GOPATH can be a list of paths. `cd $GOPATH` doesn't always work.

if you are running latest versions of Ubuntu or Linux kernels, it is a PITA to get Docker running because of its dependence on AUFS - which is deprecated on the kernel side.

The better (but unknown) way of running it is to install Docker 0.7-RC4 through curl http://test.docker.io | sudo sh.

Just FYI.

Why would anyone downvote this?

probably someone who doesn't like the whole "blindly execute untrusted shell scripts from the internet as root" thing

Because it is unrelated, the focus here is Go, neither Ubuntu or AUFS.

Devs not aware of where and how is their software running, while ops are not aware what they're running? That sound like a recipe for a disaster. You don't need to know everything, that's why there are separate teams... but the way it's described in the slides is slightly scary to me. I've seen people caring only about their own area and lobbing things over the wall for other teams to take out over. It never ended well.

I think it was more "I want to write my code without how it ends up packaged or deployed having influence on how I write it", and vice versa.

We definitely don't have that at my job. We have to be conscious of the dev, test, build and production environments when coding. Ops has to be more conscious of what they are deploying than they'd like. It's not that either team doesn't care about the other's work or the big picture.

If how it's deployed doesn't influence the way you write software, you're either: a) developing something trivial, or b) deploying something that's not going to work well in the long run.

I can't really argue with that. Just giving my interpretation of the slide. I still don't know Docker very well, maybe it's not as revolutionary as it seems to be.

The solution I've found to the "package main" problem is to put the "main" as a sub package.

That way main can import "myapp/shared_code". Yes, the packaging standard is being broken for the main programs, but that's ok, nothing needs to import them.

Maybe I missed it, but I didn't find anything on http://golang.org/doc/code.html#PackagePaths that seems to forbid what you're doing. In fact, it says "in practice you can choose any arbitrary path name, as long as it is unique to the standard library and greater Go ecosystem." But rather than main1 and main2, surely it makes sense to name those directories after the binaries you're building?

I actually kind of like Go's scheme here. One thing I never quite liked in C/C++ was huge directories full of source files where it wasn't clear what code was part of what binaries. If something is only part of one binary, why not make that obvious by putting it in another package?

Yeah, main1 and main2 are not real names, just a way of showing on my ASCIIgram where the mains are relative to the libraries they import.

What do they mean by Go is neutral?

If they chose ruby, python coders might not like it. If they chose python, ruby coders might not like it, etc.

By using Go, it avoids a lot of existing biases. I think that's what that slide is referring to.

That's the weakest reason to choose Go. I think the other comment made it pretty solid that here on HN we have a lot of top-rated comments and topic involving building an app or rewriting an app in Go.

If the reason is neither Python nor Ruby can do concurrency right out of the box like Go does, then sure this could be a good reason because people in Python and Ruby world would argue which set of tools to use.

I mean Python coder and Ruby coder can argue that Go is not the way to go; static compilation, like whattttttt? Strict type... like what?

I am not very convinced and think that slide is pretty biased - well basically doesn't justify why Go was picked and the tone of the slide makes me think Go is the solution to all the disputes we have in other languages. We have plenty of Go vs Python vs Ruby threads.

Er, but those people tend to be for "their" language, and suspicious of others, regardless. Avoiding traditional rivalries may give them some breathing room, but Go is not somehow outside of the tribal fanboy ecosystem.

Indeed, the "OMG GO!1!" tone of many HN stories and comments on the language suggest that it's diving in headfirst...

I don't think so: I'm guessing a lot of Go programmers where Ruby/Python guys before. My main language before Go was Python (every time I needed to do some non-trivial bashy stuff I went for Python) and now unless I need some esotheric library only available in Python (or Lisp) I go straigt for Go. And still like Python, no big deal. Won't bash a language I still like!

Or, more likely, Python and Ruby developers can distrust it equally ;)

Slide 24 says "Why Go? Multi-arch build without preprocessors."

My understanding is that Docker is strongly tied to Linux by virtue of using Linux containers. So how does Docker benefit from the multi-arch build facilities of Go, if it only runs on Linux?

LXC does require Linux and x64 is the recommended architecture to run it on, however LXC can be built for other platforms (namely x86, x86-64, IA-64, PowerPC, SPARC, Itanium and ARM [1])

And just today there was a breakthrough in getting Docker running on the Raspberry Pi: https://news.ycombinator.com/item?id=6708565

[1] https://en.wikipedia.org/wiki/LXC

But the Go compiler only has backends for three out of the seven architectures you listed. So this would seem to be a strike against Go.

It looks like Docker provides binaries for only x86-64 Ubuntu. So slide 24 seems to be more of "we think this is cool in theory" rather than "this really helps us."

Yes and I don't think there are image repositories for other architectures, though perhaps the pi thing may mean an arm repository turns up.

It would be cool if IBM sponsored more powerpc ports of stuff. They do give free access to ppc machines, but they should have people who eg write go backends for ppc64.

Maybe they want to be able to add other backends. But even remaining tied to Linux: Linux runs on a huge number of different architectures - i386, x86_64, mips, ppc, arm just for starters.

But Go runs on only three architectures. If the desire is to support Linux on whatever architecture, then Go is the wrong choice.



"GCC 4.8.2 provides a complete implementation of the Go 1.1.2 release."

"[gcc] Go has been tested on GNU/Linux and Solaris platforms for various processors including x86, x86_64, PowerPC, SPARC, and Alpha. It may work on other platforms as well."

The original compiler created by the Go team at Google, doesn't work on many platform. But Go is a language with many implementations of the compiler. Currently gccgo is the only other implementation I know which would be useful, but there is work on a llvm frontend too.

Take into consideration that precisely because of the design choices behind the language as it's currently specified (focus on simplicity in the language and implementation, e.g. explicit lack of dynamic linking) it's reasonable to expect that your application will work on a different compiler (compared with c++, at least for those who remember more troubled times)

There is a trade-off between "running anywhere" and "running mostly anywhere". I.e. going from 99% to 99.99% :-)

The server-side component only runs on Linux for now, and while it's supported only on x86_64, people have confirmed that it could run on i386, and arm v6/v7/v8.

Later releases will also target FreeBSD, Solaris, and possibly OS X.

The client-side component already runs on OS X, and could possibly run on Windows as well.

However, there is currently no interest at all in running Docker on AIX, HP/UX, Plan9; or on Sparc, Power, s390, or Mips platforms.

I notice that "security" doesn't figure in the devops slide at all. Bundling a whole load of untracked, old libraries together and then exposing it on the web might not be the best idea in the world.

I am more leaning on OSv rather then Docker at the moment. Although OSv still isn;t ready yet.

I don't really know anything about docker. Do you actually have to write Go to use it effectively?

Not in the least. It has a nice command line interface to use it. No Go knowledge is required, or even useful.

It's painfully obvious these guys have never created a proper distro package in earnest.

Can you please elaborate? What do you mean?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact