Debugging mit Docker

docker
Docker ist uns allen als leichtgewichtige Lösung bekannt mit deren Hilfe man Anwendungen in Containern bereitstellen kann. Ist man etwas kreativ, kann man mit Docker aber viel mehr “verbrechen”. So kann man beispielsweise Docker sehr gut zum debuggen von Applikationen verwenden.
Jetzt fragt ihr euch sicher: “Was ist den bei dem kaputt? Zum debuggen brauch ich in 90 % aller Fälle eine Konsole”. Aber warum den nicht!? Es ist zwar gegen die Idee von Docker, aber man kann damit natürlich auch einen kleine Debugging-Container mit SSH betreiben.
 
 
Hier ein kurzes Beispiel in Form eines Dockerfiles:
FROM debian:8.4
MAINTAINER $your_name $your_email


# install needed packages
RUN apt-get update && apt-get install -y openssh-server rsync rsnapshot vim git sudo ntpdate ethtool screen dnsutils shorewall curl unzip telnet net-tools ntp ntpdate


# prepare root account and login
RUN mkdir /var/run/sshd

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile


# prepare user
RUN groupadd -g 10000 $your_name
RUN useradd -g 10000 -u 10000 -s /bin/bash -m $your_name
RUN mkdir /home/$your_name/.ssh && chmod 750 /home/$your_name/.ssh && chown $your_name. /home/$your_name/.ssh
RUN echo "<$your_ssh_key>" > /home/$your_name/.ssh/authorized_keys && chmod 600 /home/$your_name/.ssh/authorized_keys && chown $your_name. /home/$your_name/.ssh/authorized_keys
RUN echo "$your_name ALL=NOPASSWD: ALL" > /etc/sudoers.d/$your_name && chmod 640 /etc/sudoers.d/$your_name


# map ssh port and run ssh
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

Wenn ihr jetzt alle $your_name durch euren Benutzernamen ersetzt (Variablen funktionieren bei Docker leider nicht in der RUN-Umgebung) erhaltet ihr ein aktuelles Debian 8.4 mit einem SSH Zugang. Dieses Dockerfile mit SSH kann man nun z. B. sehr einfach um Icinga2 Pakete erweitern. Etwas weiter gesponnen könnte man noch verschiedene Betriebssystemversionen oder die Auswahl Icinga2 Stable oder Snapshot mit einbauen.
Alles in allem erhält man einen sehr leichtgewichtigen Container der das Debuggen ermöglicht, der sehr schnell provisioniert ist und man mit der entsprechenden Storage Config sogar anwendungsspezifische Konfigurationen und Dateien mit schleppen kann.

Tobias Redel
Tobias Redel
Head of Professional Services

Tobias hat nach seiner Ausbildung als Fachinformatiker bei der Deutschen Telekom bei T-Systems gearbeitet. Seit August 2008 ist er bei NETWAYS, wo er in der Consulting-Truppe unsere Kunden in Sachen Open Source, Monitoring und Systems Management unterstützt. Insgeheim führt er jedoch ein Doppelleben als Travel-Hacker, arbeitet an seiner dritten Millionen Euro (aus den ersten beiden ist nix geworden) und versucht die Weltherrschaft an sich zu reißen.

Besserer Python-Debugger gefällig?

Welcher Python-Programmierer hat sich nicht schon einmal über die kleinen Macken des builtin-debuggers (im folgenden der “Normale”) geärgert oder schmerzlich Syntax-highlightning und TAB-Vervollständigung vermisst? Nun, ich bin so einer und möchte euch deshalb heute pdb++ vorstellen. Einmal installiert ersetzt dieser Debugger den normalen aus der stdlib und wartet mit einigen sehr nützlichen Features auf. (mehr …)

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Weekly Snap: Puppet 2.5, Python Debugger, OSDC Partners & Icinga/Nagios Training


26 – 30 March ended the month with a good mix of Python and Puppet tips, MySQL lessons and events.
Eva started by thanking our sponsors, Linux Magazin, Admin Magazin and SuSE in the lead up to the Open Source Data Center Conference on 25 – 26 April.
Sebastian then encountered a strange MySQL master-master cluster error while Eric explained how to use the Python Debugger and Bernd forwarded news of the latest Puppet Enterprise 2.5 release.
Lastly, Phillipp celebrated our inaugural Icinga/Nagios Availability Monitoring training course in Düsseldorf, with a second to come on 21 – 25 May.

Weekly Snap: GDB for Debugging, ispCP for Web Server Admin, 1 New Job & 3 New Hardware

1 – 6 August started the month with blogging from across the office. First on new products from the hardware store, tips from the development and managed services teams and also a new job opening on the sales team.
Starting the week, Marcus shared a tip for web server management with isp Contol Panel Omega. A fork of the now inactive VHCS project, ispCP is an open source, multi server control and administration panel for internet service providers. He likes ispCP for its user interface and ability assign various roles to users such as ‘administrator’, ‘reseller’ and ‘user’ to apply refined user rights and principles. Installation is easy with the helpful official documentation and ispCP is available in a stable v1.0.7. However for a look at its new features Marcus recommends the v1.1.0 beta version or simply their online demos.
From the development team, Gunnar showed how to use GDB for debugging. As of v.7.0, GDB can “record” and replay program execution allowing the user to pinpoint problem areas in the source code. Handy indeed, but he cautioned that GDB significantly slows the program when “recording” and should be used for the shortest process portions possible.
Following on from Sales, Peter posted a position for a Junior Account Manager. The ideal candidate would have some experience in hosting, systems management, monitoring etc and enjoy dealing with customers. More on the position and application can be found on the jobs area of our website.
From our hardware shop, Martin announced the arrival of Kentix AlamManager, Multi Sensor LAN and the new Multi-Tech Multi Modem for SMS. The Kentis Alarm Manager Set consists of a base station and wireless multi sensor. The base station facilitates communication with the company network and sends SMS alerts through the in-built GSM modem. The sensor monitors temperature, humidity, dew point, fire/carbon monoxide and movement, communicating to the base station wirelessly via Zig Bee. For smaller environments, the Multi Sensor LAN is also available, offering a version that is integrated into the company network via a network cable (with PoE). As alway. Icinga/Nagios  plugins can be downloaded at www.netways.org
Finally, the last addition to the shop is the follower to the Multi-Tech Multi Modem MTCBA-G-EN-F4-ED-EU, known as the Multi-Tech Multi Modem MTCBA-G2-EN2-F4-ED-EU. From in-house tests, Martin noted that interceptty is no longer needed; instead communication can be set simply in the SMS server tool config.

Historisches Debuggen mit GDB

Beim Debuggen von Speicherzugriffen ist es manchmal recht schwierig, die verursachende Stelle im Quelltext zu finden, wenn das Programm an einer scheinbar zufälligen Stelle crasht oder es durch Logikfehler unerwartete Ergebnisse liefert.
Hilfsmittel wie Valgrind oder Watchpoints (“help watch” und “help rwatch” in GDB) erleichtern hierbei die Fehlersuche, können aber nicht immer den Fehler finden. Gerade bei komplexeren Bugs wünscht man sich oft, in der Programmausführung zurückgehen zu können, um Variablen vor einem bestimmten Funktionsaufruf untersuchen zu können, oder um weitere Breakpoints zu setzen.
Seit Version 7.0 ist genau das mit GDB möglich. Mit Hilfe des “record”-Targets kann die Programmausführung aufgenommen werden und schrittweise zurück- und auch wieder vorgespult werden.
Um dieses Feature zu demonstrieren, kompilieren wir folgendes Beispiel-Programm mit “gcc -ggdb -o test test.c”:

int main(int argc, char **argv) {
    int a, b;
    a = 7;
    b = a;
    return 0;
}

Danach können wir wie gewohnt gdb aufrufen:

$ gdb ./test

Zunächst müssen wir einen Breakpoint setzen, an dem wir mit der Aufnahme der Programmausführung starten wollen. Im einfachsten Falle wäre das die “main”-Funktion. Bei komplexeren Programmen kann hier eine andere Stelle im Programm verwendet werden, wo der zu untersuchende Bug noch nicht aufgetreten ist:

(gdb) break main
Breakpoint 1 at 0x4004bf: file test.c, line 4.

Danach können wir noch einen zweiten Breakpoint setzen, wenn wir wissen, an welcher Stelle der Bug schon aufgetreten ist (z.B. beim Speichern einer Datei, wenn die zu speichernden Daten zu diesem Zeitpunkt bereits fehlerhaft sind) – dies ist jedoch optional:

(gdb) break test.c:8
Breakpoint 2 at 0x4004cc: file test.c, line 8.

Nachdem wir die Breakpoints gesetzt haben, können wir das Programm starten:

(gdb) run
Starting program: /home/gunnar/test
Breakpoint 1, main (argc=1, argv=0x7fffffffe288) at test.c:4
4		a = 7;

GDB stoppt unseren Prozess an dem ersten Breakpoint. Mit dem “record”-Befehl können wir nun GDB anweisen, die weitere Programmausführung aufzuzeichnen:

(gdb) record

Wenn wir den Prozess nun weiterlaufen lassen, sollte er den zweiten Breakpoint erreichen. (Falls wir keinen gesetzt haben, fragt GDB uns nach Ausführung des Programms, ob wir den Prozess anhalten möchten – dies sollte mit “y” beantwortet werden, da GDB sonst den Prozess beendet):

(gdb) continue
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe288) at test.c:8
8		return 0;

Um nun in der Aufnahme zurückspringen zu können, bietet GDB zusätzlich zu den normalen Ausführungsbefehlen (continue, step, next, usw.) entsprechende Befehle, die in umgekehrter Richtung funktionieren:

  • reverse-continue
  • reverse-finish
  • reverse-next
  • reverse-nexti
  • reverse-step
  • reverse-stepi

Mit reverse-continue können wir z.B. zum Anfang der Aufnahme zurückspringen:

(gdb) reverse-continue
Continuing.
No more reverse-execution history.
main (argc=1, argv=0x7fffffffe288) at test.c:4
4		a = 7;

An dieser Stelle können wir z.B. weitere Breakpoints und Watchpoints setzen, oder mit “step” das Programm zeilenweise durchlaufen lassen und mit “print” Variablen untersuchen.
Abschließend wäre noch zu beachten, dass “record” das auszuführende Programm deutlich verlangsamt. Idealerweise sollten dabei die Breakpoints so gewählt werden, dass ein möglichst kleiner Teil des Prozesses aufgezeichnet werden muss.