Thanks to Docker (and Go of course) containers are applied for a broad range of use cases. They became especially important in the services world, for testing and development, and they also start to be interesting in the HPC community having specialized frameworks.
Since a year Unikernels became a topic, too. Until now it looks like the basic development of the frameworks is the main focus. Especially from companies focusing at IoT. I just stumbled over unik which allows to pack Go applications in a Unikernel.
So what are Unikernels and what differs them from containers?
Unikernels are OS machine images which are based on library operating systems. The typical case is that fully fledged operating systems are running and hosting many applications at the same time. With containers you still have the main operating system but through kernel features like namespaces, cgroups, and chroot you can isolate the containers from each other in a way that it feels like running in a different OS.
So with Unikernels you are doing something contrary: instead of sharing the same OS kernel you isolate applications within independent operating systems. Isn’t that what VMs are doing? No, since Unikernels are created for a particular application and hence only provide OS functionalities required for the particular application, they also seem to run in a single address space. Some advantages are certainly that you have real isolation between them (unlike containers), there is no specific kernel version and feature required for the shared OS under-the-hood. Also performance is certainly an aspect when it comes to HPC. No waste of context switches between privileged and unprivileged address space, IO, compute cycles, interrupts for unnecessary OS functionality. Highly specialized OS images can be tuned exactly for one use case and they are much smaller.
But how to personalize OSs without having an immense admin overhead?
This is where the library of the operating systems comes into play. The OSs are finally just created by frameworks during application development. So what we see is a movement from an admin controls everything paradigm on the compute farm (has to install libraries, applications), to devops where developers also has to think about how to ship the application like packing it with its dependencies in containers, to developer-packs-apps-with-dependencies-in-specialized-os.
Again this goes hand-in-hand with cloud computing paradigm where the infrastructure is just available (and as big and flexible as your pocket) and the developers have to deal with it directly. For running it on-premise the hypervisor approach seems to be used because of the underlying difficulty of having the right device drivers.
Great video about the actor model.
That Go (#golang) works very well accessing C libraries is widely known. The DRMAA and DRMAA2 Go wrappers for example accessing the native C shared libraries provided by the Grid Engine installation. Those libraries are not installed in the standard libraries paths by default so the Go application using the Go wrapper can only find the shared lib when the LD_LIBRARY_PATH is set to the lib/lx-am64 path of the Grid Engine installation.
But what when you want to ship an application written in Go which uses a shared library and you want to ship the shared library along with your application? Or when you want to force the application to use a shared library which is not in a default library path?
If you not place the shared lib in a system library path and you don't want to use mechanisms like LD_LIBRARY_PATH then you can think about setting the rpath for your application. This is also possible for Go applications. The rpath just adds an library search path in your binary which can be different to standard search paths. When you don't know the absolute path of the application in advance, this is most likely the common case, then you can set the rpath relatively to where your application is stored. This can be done by using the ORIGIN keyword.
Following example demonstrates how this can be done when you compile your Go application.
Let's assume you ship your Go application in a directory structure like this:
myapp/ myapp/bin/myapplication myapp/lib/mysharedlib.so
The Go myapplication needs the C mysharedlib.so which is in the lib directory ../lib. Then you can build it telling the linker you want to set the rpath to ../lib:
export CGO_LDFLAGS="-L/path/to/the/lib -Wl,-rpath -Wl,\$ORIGIN/../lib" export CGO_CFLAGS="-I/path/to/include/file/of/the/lib/include" go build
Inspecting the rpath of the executable can be done in that way:
objdump -p yourapplication | grep RPATH RPATH $ORIGIN/../lib
Collecting time series data like stock market or home automation data and storing it in InfluxDB is easy using the new Go client library of InfluxDB.
The next step is displaying the data like temperatures as continuously updated graphs.
Grafana is a nice, widely used web interface displaying data as graphs. It works well with InfluxDB but also with other backends like ElasticSearch.
In a previous post I documented how InfluxDB can be installed on the Raspberry Pi. This post summarizes my experience at installing Grafana on the Pi. Also that tool is working reliable since a while on the Pi. It comes with a web-server so you can display the graphs on any device.
For installing Grafana on the Raspberry Pi 2 it needs to be built from scratch (I couldn't find it in a repository for ARM). It appears to consist of Go and node.js. Hence you need to have the Go compiler, git, and nodes.js installed.
Building the Go backend:
$ go get github.com/grafana/grafana $ cd $GOPATH/src/github.com/grafana/grafana $ go run build.go setup $ $GOPATH/bin/godep restore && go run build.go build
Building the frontend:
$ sudo aptitude install npm $ sudo aptitude install node $ sudo npm config set registry http://registry.npmjs.org/ $ sudo npm install tap
Finally I found myself in the dependency hell of node.js - the Go part was just so simple. IIRC to get grunt installed I needed to update npm as well as install n.
$ sudo npm install npm -g $ sudo npm install n -g $ sudo npm install grunt -g
Finally the frontend can be build (you need to be in the grafana directory):
$ sudo npm install
At the beginning it resulted in version compatibility issues of some libraries. What helped is re-installing the required versions of them with sudo npm install tool@version -g and then running the npm install again.
$ grunt --force
If all that was successful Grafana can be started:
Then you can login now on port 3000 create your user and organization, adding your InfluxDB data sources, and finally your graphs based on the data you are constantly adding to InfluxDB.
Really a cool thing and a pretty useful tool for displaying all kinds of measurements you are doing.
InfluxDB is a simple time series database written entirely in Go without external dependencies. This makes it attractive to have it running on a Raspberry 24/7 to collect home automation or stock market data or anything else which is waiting for being stored locally when the laptop is closed. I installed it a while ago and it is running well. Below my notes probably useful also for others (and also for me later on). I hope it is complete.
For Influx exists pre-built packages but unfortunately none for the ARM architecture required for the Raspberry.
Since it is written in Go and the Go compiler supports ARM it can be compiled from scratch.
First we need the latest and greatest Go compiler on the Raspi (currently 1.5.1) which needs to be compiled first itself. You can cross-compile it but having a recent Go compiler on the Pi is certainly useful. Since Go is now entirely written in Go (1.5) we need to bootstrap the compilation of Go.
Over in Dave Chaneys blog there is a recipe which works well also for 1.5.1. It takes an hour for compilation, but on the old Raspberry it took the whole night.
Having the current go version and the Go paths setup you should see something like that:
$ go version go version go1.5.1 linux/arm
The next step is cloning the repository of InfluxDB and changing to its directory:
$ go get github.com/influxdb/influxdb $ cd go/src/github.com/influxdb/influxdb
Changing to a stable tag of the latest version (git tag --list) can also not harm because we want to have a stable system.
$ git checkout v0.9.4.1
Finally the dependencies have to be resolved and then it can be build (being in the influxdb source directory.
$ go get -u -f -t ./... $ go build ./... $ go install ./...
For creating a complete package the gvm tool needs to be installed. That handles Go versions on the command line. Then the package.sh script could be used. But for my purposes I skip that.
For running InfluxDB we are going to use a user named influxdb and giving it a password:
$ sudo adduser influxdb
Now we let's install the InfluxDB binary to a global location.
$ sudo mkdir /opt/influxdb $ sudo cp /home/daniel/go/bin/influxd /opt/influxdb/ $ sudo cp /home/daniel/go/bin/influx /opt/influxdb/ $ sudo chown -R influxdb /opt/influxdb $ sudo chgrp -R influxdb /opt/influxdb
Also other directories needs to have the rights for influxdb user.
$ sudo mkdir -p /etc/opt/influxdb $ sudo chown -R influxdb /etc/opt/influxdb $ sudo chgrp -R influxdb /etc/opt/influxdb $ sudo mkdir -p /var/run/influxdb $ sudo chown -R influxdb /var/run/influxdb $ sudo chgrp -R influxdb /var/run/influxdb $ sudo touch /etc/default/influxdb $ sudo chown -R influxdb /etc/default/influxdb $ sudo chgrp -R influxdb /etc/default/influxdb
As influxdb user the config needs to be created:
$ su influxdb $ /opt/influxdb/influxd config > /etc/default/influxdb
For getting the daemon booted automatically we need to install the rc script as root.
# cp <...>/src/github.com/influxdb/influxdb/scripts/init.sh /etc/initd/influx
Then we add it to the runlevels (in /etc/initd).
# insserv influx
Starting the service...
# service influx start Starting the process influxdb [ OK ] influxdb process was started [ OK ]
Now it is time to test if it is running:
# service influx status influxdb Process is running [ OK ]
You can also connect now with your browser to port 8083.
A nice presentation about how to use the Go programming language (#golang) with CUDA (from FOSDEM 2014): Scientific GPU Computing with Google's Go Language
This interesting article describes how the Hyper-Q scheduler from Nvidia is used in order to run multiple MPI processes concurrently on one GPU. Using the alarm state (in order to exclude fully loaded hosts/GPUs for new jobs in the Grid Engine job list/queue) and load values/load thresholds from the GPU and the CPUs Grid Engine should be able to handle this scenario well.
This presentation from the HPC Advisory Council Conference 2013 gives an introduction about management and monitoring of GPUs.