Setting up Smokeping in a systemd-nspawn container

Smokeping is a nifty tool that continuously performs network measurements (such as ICMP ping tests) and graphs the results in a web interface. It can help you assess performance and detect issues in not only your own but also upstream networks.

/images/smokeping_last_864000.png

This is not how your graphs should look.

This article details setup steps for running Smokeping in a systemd-nspawn container with some additional requirements:

  • IPv6 probes must work

  • The container will directly use the host network so that no routing, NAT or address assignment needs to be set up.

  • To reduce disk and runtime footprint the container will run Alpine Linux

Container setup

First we need to set up an Alpine Linux root filesystem in a folder.
Usage is simple: ./alpine-container.sh /var/lib/machines/smokeping

Next we'll boot into the container to configure everything: systemd-nspawn -b -M smokeping -U

If not already done edit /etc/apk/repositories to add the community repo.
Additionally, you have to touch /etc/network/interfaces so that the network initscript can start up later (even though there is nothing to configure).

Install all required packages: apk add smokeping fping lighttpd ttf-dejavu

Make sure that fping works by running e.g. fping ::1.

lighttpd

Next is the lighttpd configuration inside /etc/lighttpd.

Get rid of all the examples: mv lighttpd.conf lighttpd.conf.bak && grep -v '^#' lighttpd.conf.bak | uniq >lighttpd.conf

There are multiple changes to be done in lighttpd.conf:

  • change server.groupname = "smokeping", the CGI process will need access to smokeping's files.

  • add server.port = 8081 and server.use-ipv6 = "enable"

  • configure mod_fastcgi for Smokeping by appending the following:

server.modules += ("mod_fastcgi")
fastcgi.server = (
        ".cgi" => ((
                "bin-path" => "/usr/share/webapps/smokeping/smokeping.cgi",
                "socket" => "/tmp/smokeping-fastcgi.socket",
                "max-procs" => 1,
        )),
)

We also need to link smokeping's files into the webroot: ln -s /usr/share/webapps/smokeping/ /var/www/localhost/htdocs/smokeping

smokeping

Next is the smokeping configuration located at /etc/smokeping/config.

The most important change here is to set cgiurl to the URL smokeping will be externally reachable at, like so:
cgiurl = http://your_server_here:8081/smokeping/smokeping.cgi

You might also have to adjust imgurl depending on how the symlink in /usr/share/webapps/smokeping is called.

Smokeping's configuration [2] isn't super obvious if you haven't done it before so I'll provide an example here (this replaces the Probes and Targets sections):

*** Probes ***

+ FPing
binary = /usr/sbin/fping

+ FPing6
binary = /usr/sbin/fping

*** Targets ***
probe = FPing

menu = Top
title = Network Latency Grapher
remark =

+ targets
menu = IPv4 targets

++ google
menu = Google
title = Example Target: Google (IPv4)
host = 8.8.4.4

+ targets6
menu = IPv6 targets
probe = FPing6

++ google
menu = Google
title = Example Target: Google (IPv6)
host = 2001:4860:4860::8844
Lastly, grant the CGI process write access to the image folder:
chmod g+w /var/lib/smokeping/images
This must match the value of imgcache in the config, in case that ever changes.

Final container setup

Set services to run on boot: rc-update add smokeping && rc-update add lighttpd
Then shut down the container using poweroff.

We need to tell systemd-nspawn not to create a virtual network when the container is started as a service.
Do this by creating /etc/systemd/nspawn/smokeping.nspawn:
[Exec]
KillSignal=SIGTERM

[Network]
VirtualEthernet=no

Finally start up the container: systemctl start systemd-nspawn@smokeping
If this does not work due to private users you are running on an old systemd [3], try again with PrivateUsers=no in the Exec section.

You can now visit http://your_server_here:8081/smokeping/smokeping.cgi and should see a mostly empty page with a sidebar containing "Charts", "IPv4 targets" and "IPv6 targets" on the left.