Online-Hilfe

Container

  1. Allgemeines
  2. Funktionalität von Containern
  3. Zur Verfügung stehende Ressourcen
  4. Erzeugte Container
  5. Container-Storage
  6. Dateien mit einem Container austauschen
  7. Eigene Container erstellen

Allgemeines

Auf dem Router können Linux-Container (LXC) installiert und ausgeführt werden. Ein Container ist eine Virtualisierung eines eigenes Systems, er "fühlt" sich an, wie ein eigener Rechner mit eigener

  • Prozessverwaltung
  • Benutzerverwaltung
  • Netzwerkumgebung
  • Datei- und Verzeichnisumgebung

Die Container nutzen den Linux-Kernel und Treiber der Firmware. Der direkte Zugriff auf die Hardware ist nicht gestattet, so dass die Funktionalität des Routers nicht kompromittiert werden kann.

Es können theoretisch unbegrenzt viele Container auf dem Router gespeichert und gestartet werden. Begrenzt wird die Anzahl durch endlichen RAM- und Flash-Speicher (siehe Ressourcen).

Der Inhalt von Containern wird behandelt wie Firmware-Images. Das root-Dateisystem von Containern wird im Flash-Speicher gespeichert und im Web-Interface aufgelistet. Jeder Container benötigt
  • einen Bezeichner (z.B. "container_DEMO"), der im root-Dateisystem gespeichert wird, so dass das root-Dateisystem des Containers identifiziert werden kann.
  • eine Zuordnung eines Instanz-Namens (z.B. "container1") im Profil des Routers, so dass der Container über Ereignisse und Aktionen adressiert werden kann.
Der Bezeichner kann frei gewählt werden, er wird sowohl im Profil des Routers als auch im root-Dateisystem des Containers gespeichert ("/usr/share/image_name"). Der Instanz-Name wird fest vorgegeben. Die Zuordnung von Bezeichner und Instanz-Name kann frei gewählt werden.

Funktionalität von Containern

Jeder Container kann über das Web-Interface auf den Router geladen werden. Wird ein Container auf den Router geladen, der den gleichen Bezeichner hat wie ein schon vorhandener Container, überschreibt der neue den alten Container. Soll ein und derselbe Container in mehreren Instanzen auf dem Router vorhanden sein, beispielsweise eine zweite Instanz der icom Data Suite, muss der Bezeichner des ersten Containers geändert werden, bevor der nächste Container geladen wird.

Jeder Container kann vom Router gelöscht werden. In dem Fall werden auch alle Daten gelöscht, die im Container erzeugt wurden, wie z.B. Log-Dateien. Der Container wird aus dem Profil des Routers entfernt.

Jeder Container kann in der Konfiguration aktiviert oder deaktiviert werden. Beim Systemstart werden alle aktiven Container selbständig hochgefahren. Über Ereignisse und Aktionen können aktive Container gestartet oder gestoppt werden.

Jeder Container kann in Form eines Update-Pakets wieder vom Router heruntergeladen werden. Optional kann ein Container vom Download ausgeschlossen werden, indem die Datei "/usr/share/downloadable" gelöscht wird. Somit ist ein einfacher Kopierschutz realisierbar.

Jeder Container verfügt über ein eigenes Netzwerk-Interface, dass über das Web-Interface konfiguriert werden muss. Es wird über eine Bridge mit einem der IP-Netze des Routers verbunden. Verbindungen können mit den Netzfilterregeln genauso berücksichtigt werden wie ein eigenständiges Gerät im Netzwerk. Im Container müssen Routen angelegt werden, wenn mit Maschinen in anderen Netzen kommuniziert werden soll.

Jeder Container kann Meldungen via MCIP erhalten und versenden. Dadurch wird eine Schnittstelle zur Firmware-Funktionalität geschaffen (Ereignisse und Aktionen).

Jeder Container bekommt ein Verzeichnis ("/data") gemountet, in dem eigene Daten gespeichert werden können, die ein Update des Containers überdauern (Konfiguration, Logs). Dieses Verzeichnis wird nur dann gelöscht, wenn der ganze Container gelöscht wird.

Jeder Container verfügt über die Konfigurationsoption, das spezielle Unterverzeichnis "/data/etc" als Konfiguration für Container-Applikationen zu betrachten. Dann wird beim Herunterladen eines Profil diese Konfiguration als Anhang mit in das Update-Paket aufgenommen, so dass das Router-Profil und die Einstellungen der Applikationen in einem Container gesammelt gespeichert werden können. Im Manifest wird der Bezeichner des Containers mit angegeben, so dass das Profil diesem Container beim Upload wieder zugeordnet werden kann, ohne abhängig vom internen Containernamen (z.B. container1) zu sein. Die Konfigurationsdatei des Containers kann ein beliebiges Format haben, kann also z.B. aus einer Datenbank bestehen oder auch nur ein einfaches ASCII-File darstellen.

Jeder Container erhält die freigegebenen Hardware-Ressourcen als Device-Nodes angelegt, unabhängig davon, welche Dienste diese Device-Nodes schon benutzen. Ressourcen sind z.B. serielle Schnittstellen.

Jeder Container kann seine Konsolenausgaben in ein Log schreiben. Damit kann eventuell der Grund für einen nicht startenden Container herausgefunden werden.

Jedem Container kann optional eine auf dem Router gespeicherte Lizenz zugeordnet werden, die von der Applikation im Container verwendet werden kann, um Funktionalität freizuschalten.

Zur Verfügung stehende Ressourcen und Applikationen

Die Firmware des Routers reserviert für sich 64 MByte RAM. Der Rest wird gleichteilig auf die zu startenden Container-Instanzen aufgeteilt.

Die Hälfte der CPU-Rechenzeit wird der Router-Firmware garantiert. Die restliche Rechenzeit erhalten anteilig die Container-Instanzen. Die Anteile an Rechenzeit sind jedoch nur dann begrenzt, wenn sie von den einzelnen Berechtigten auch angefordert werden. Führen die Firmware und alle gestarteten Container-Instanzen keine Berechnungen aus, steht die komplette Rechenzeit zur Verfügung.

Der Flash-Speicher ist nicht limitiert. Die Firmware und alle Container-Instanzen müssen sich den verfügbaren Speicherplatz teilen. Es gibt kein Quota, da eine Aufteilung wie bei den flüchtigen Ressourcen RAM oder CPU-Rechenzeit nicht nachträglich verändert werden kann, sollte ein weiterer Container hinzugefügt werden.

Erzeugte Container

Container, die von der Firmware erstellt wurden, stellen eine minimale Umgebung zur Verfügung, die als Ausgangsbasis für eigene Anwendungen genutzt werden kann. In den Containern existiert ein Benutzer "root", dessen Passwort "root" lautet. Aus Sicherheitsgründen soll das Passwort nach dem Erstellen des Containers sofort geändert werden. Es können beliebige neue Benutzer und Gruppen erstellt werden.

Ein von der Firmware erstellter Container enthält:

  • das init-System "finit"
  • die Werkzeugsammlung "busybox"
  • einen SSH-Server "dropbear", der auf Port 22 auf Verbindungen wartet
  • den Log-Daemon "metalog"
  • das Authentifizierungssystem "PAM"
  • grundlegende Bibliotheken (libc, libm, libpam, usw.)
  • den Lua-Interpreter und die dazu gehörende Bibliothek
  • ein gemountetes TMPFS
  • den MCIP-Server und die libmcip
  • die Werkzeugsammlungen "mcip-tool", "get-input" und "get-pulses" zum Empfang von Ereignissen von der Router-Firmware.
  • die Werkzeugsammlung "sms-tool" zum Versand und Empfang von SMS
  • die Werkzeugsammlung "cli-cmd" für den einfachen Zugang zur CLI (Command Line Interface) des Routers

Ein Container enthält folgende Verzeichnisse und Dateien:

  • /bin/mcip-tool
  • /bin/sms-tool (SMS versenden oder empfangen)
  • /bin/get-input (digitale Eingänge abfragen)
  • /bin/get-pulses (Pulse an digitalen Eingängen empfangen)
  • /bin/set-output (digitale Ausgänge schalten)
  • /bin/cli-cmd (CLI-Befehle an den Router senden)
  • /bin/container (Container starten, stoppen oder neu starten lassen)

Diese Tools haben eine eingebaute Hilfe, die mit dem Parameter "-h" abgerufen wird. Die Tools helfen beim Empfang von SMS (sms-tool), Ereignissen bei den Eingängen ("get-input" für Pegel-Änderungen und "get-pulses" für Pulse an den Eingängen). Mit "mcip-tool" können Nachrichten über MCIP gesendet und empfangen werden und so zwischen Prozessen innerhalb eines oder unterschiedlicher Container Nachrichten austauschen. Mit "set-output" können Ausgänge geschaltet werden, wenn der Zugriff auf die CLI des Routers im Container ohne Authentifizierung erlaubt ist. Mit "cli-cmd" kann die Konfiguration des Routers ausgelesen und verändert werden. Status-Informationen des Routers können abgefragt werden. Mit "container" können Container gestartet, gestoppt oder neu gestartet werden, wenn der Zugriff auf die CLI des Routers im Container ohne Authentifizierung erlaubt ist.

  • /data
    In dieses Verzeichnis wird beim Start des Containers zusätzlicher Flash-Speicherplatz gemountet. Die Daten, die hier gespeichert werden, werden von einem erneuten Import des Containers nicht überschrieben. Das Verzeichnis eignet sich für Daten, die ein Container-Update überdauern sollen. Es wird erst dann gelöscht, wenn der komplette Container gelöscht wird.

  • /data/etc
    Dieses Verzeichnis kann optional mit dem Profil gebündelt heruntergeladen werden. Wird das Profil des Routers als Binärdatei heruntergeladen und bei einem Container ist diese Option aktiviert, wird der Inhalt /data/etc als tar-Archiv gepackt und dem Update-Paket mit dem Profil des Routers hinzugefügt. Im Manifest des Update-Pakets wird der Bezeichner des Containers gespeichert, so dass bei einem erneuten Einspielen des Update-Pakets das tar-Archiv wieder dem richtigen Container zugeordnet werden kann.

  • /data/log
    Dieses Verzeichnis kann als dauerhafter Speicher benutzt werden, der Container- und Konfigurations-Updates überdauert. Optional kann das im Container enthaltene Verzeichnis /var/log gelöscht und mit einem Symlink auf /data/log ersetzt werden. Die Applikationen, die normalerweise in /var/log ihre Log-Dateien schreiben, müssen in dem Fall nicht umkonfiguriert werden.

  • /devices
    In diesem Verzeichnis werden Device-Nodes angelegt, die den Usern im Container von der Firmware des Routers zur Nutzung überlassen werden. Existiert z.B. eine Einsteckkarte mit seriellen Schnittstellen, wird ein Device-Node X_serialY angelegt. X gibt die Slot-Nummer an, in der sich die Einsteckkarte befindet. Y gibt die Instanz der seriellen Schnittstelle an.

  • /devices/mcip.socket
    Die Datei ist die Socket-Datei für den MCIP-Socket, mit dem man Nachrichten zur Router-Firmware oder in andere Container senden kann.

  • /devices/cli.socket
    Die Datei ist die Socket-Datei für den UDS (Unix-Domain-Socket) zum CLI (Command Line Interface) des Routers. Dies stellt eine Schnittstelle zur Router-Konfiguration dar, ohne im Container auf eine IP-Konfiguration angewiesen zu sein. Diese Schnittstelle eignet sich, um alternative Konfigurations-Interfaces im Container zu erstellen. Mit Tools wie z.B. "socat -u /devices/cli.socket -" kann das CLI aus der Shell bedient werden, ohne eine IP-Verbindung zum CLI herstellen zu müssen.

  • /devices/cli_no_auth/cli.socket
    Die Datei ist ebenfalls eine Socket-Datei für den UDS (Unix-Domain-Socket) zum CLI (Command Line Interface) des Routers. Im Gegensatz zu /devices/cli.socket benötigt dieser CLI-Zugang keine Authentifizierung. Die Zugangsdaten müssen deshalb im Container nicht bekannt sein. Ob der Zugang zum CLI erlaubt ist und welche Rechte gewährt werden (Status-Abfragen, nur Lesezugriff, voller Lese-Schreib-Zugriff) muss vorab im Router in der Konfiguration des Containers eingestellt werden.

  • /devices/wakeup
    Bei Routern mit Unterstützung von "Suspend to RAM" enthält diese Datei die Anzahl der Sekunden, die der Router im "Suspend to RAM" verbracht hat. Beim Routerstart wird sie mit dem Wert 0 vorinitialisiert. So kann man erkennen, dass noch kein "Suspend to RAM" erfolgt ist. Mit inotify kann sich der User im Container informieren lassen, wenn sich diese Datei verändert hat und somit erkennen, dass ein "Suspend to RAM"-Zyklus erfolgt und beendet wurde.

  • /devices/device_info.json
    Die Datei enthält Geräteinformationen wie Seriennummer und Hardware-Revision. Die Informationen werden im JSON-Format dargestellt und entsprechen den Informationen der Rückmeldung des REST-Endpunkts /api/v2_0/status/device_info.

  • /etc/finit.conf
    Als init-System wird "finit" benutzt; dies ist die Konfigurationsdatei des init-Systems. Zeilen, die mit "run" eingeleitet werden, starten beim Systemstart einmalig Programme. Zeilen, die mit "service" eingeleitet werden, starten Programme, die sofort automatisch erneut gestartet werden sollen, wenn sie sich beenden. Diese Programme dürfen sich selbst nicht in den Hintergrund schieben.

  • /licence
    In diesem Verzeichnis wird dem Container die auf dem Router gespeicherte Lizenz zugänglich gemacht, die ihm in der Container-Konfiguration zugeordnet wurde.

  • /shared
    In diesem Verzeichnis ist ein TMPFS (temporäres Filesystem) mit 20 MByte Größe gemountet, auf das jeder Container Zugriff hat. Damit können ganz einfach zwischen Containern Dateien ausgetauscht, mit "pipes" einfache Interprozesskommunikation realisiert werden oder shared memory containerübergreifend realisiert werden. Nach einem Neustart des Routers sind alle Dateien darin weg. Die Größe des TMPFS kann nicht verändert werden.

  • /usr/share/content.html
    Die Datei enthält in der Regel eine kurze Beschreibung des Inhalts des Containers oder Informationen darüber, wie der Inhalt des Containers genutzt werden kann, z.B. SSH-Login-Daten, Server-Ports usw. Diese Information wird nach einem Klick auf das Icon in einem neuen Browserfenster dargestellt, auch wenn der Container noch nicht gestartet oder konfiguriert wurde. Es bietet sich daher an, den Inhalt in HTML zu formatieren.

  • /usr/share/created
    Die Datei enthält die Firmware-Version, mit der dieser Container vom Router erzeugt wurde.

  • /usr/share/downloadable
    Existiert diese Datei, kann der Container in Form eines Update-Pakets vom Router heruntergeladen werden. Der Inhalt der Datei ist egal, sie darf auch komplett leer sein.

  • /usr/share/mount_allow
    Ist der Container nicht-herunterladbar, werden in dieser Datei die Verzeichnisse und automatisch deren Unterverzeichnise erlaubt, in denen ein Container-Storage eingebunden werden darf. Das Format ist ein Verzeichnis je Zeile.

  • /usr/share/image_name
    Diese Datei enthält den Bezeichner des Containers. Diese Datei darf niemals manuell verändert werden, denn der Bezeichner verknüpft die Konfiguration des Containers mit dem Container-Image. Der Bezeichner muss immer über die Firmware (Web-Interface bzw. CLI) verändert werden.

  • /usr/share/version
    Diese Datei ist ein Vorschlag, wie und wo eine Versionierung eines Containers gespeichert werden kann.

  • /tmp
    Dieses Verzeichnis enthält ein TMPFS. Die Größe kann in /etc/finit.conf eingestellt werden. Auf dieses Verzeichnis zeigen einige Symlinks, die typischerweise nur temporäre Dateien enthalten: /run, /var/lock, /var/run

Container-Storage

Der Container-Storage ermöglicht das Hochladen von Dateien in Form eines Update-Pakets auf den Router. Einzelne Pfade des Container-Storage können dann jedem Container in einem konfigurierbaren Pfad mit Lese- oder Lese- und Schreibrechten zur Verfügung gestellt werden. In nicht-herunterladbaren Containern müssen die Pfade im Container in der oben erklärten Datei /usr/share/mount_allow (Positivliste) explizit erlaubt werden. Die beiden Update-Paket-Dateitypen unterscheiden sich in ihrem Verhalten bei Verzeichnissen, die sowohl im Container-Storage als auch im Update-Paket enthalten sind. Bei "Full Storage" werden die Ordner und ihr Inhalt zuerst gelöscht. Bei "Incremental Storage" werden die Inhalte der Verzeichnisse zusammengeführt, vorhandene Dateien, die nicht im Update-Paket sind, bleiben somit erhalten. Die im Update-Paket gespeicherten Dateiberechtigungen werden übernommen.
Nach jedem Hochladen oder Löschen werden sämtliche Container neu gestartet und stehen nach einigen Sekunden wieder zur Verfügung. Dies erfordert eine erneute Anmeldung an den Containern.

Dateien mit einem Container austauschen

Um abgesehen vom Container-Storage Dateien vom Container oder in den Container zu kopieren, bietet sich "scp" an, da in erstellten Containern bereits ein SSH-Server installiert ist. Es wird ein SSH-Client wie z.B. "openssh" oder "putty" benötigt. Ein möglicher Aufruf lautet: "scp root@192.168.1.1:/root/readme.txt ./".

Im Container ist auch wget installiert, so dass Dateien von Web-Servern in den Container geholt werden können. Dazu loggt man sich via ssh im Container ein und ruft dann wget auf: "wget http://webserver_domain_oder_IP/applikation". Ist die heruntergeladene Datei ein Binary und soll ausgeführt werden, muss noch die Berechtigung "execute" gesetzt werden: "chmod 755 application".

Es stehen im Container u.a. die busybox-Applets zur Verfügung:

  • "ftpget" und "ftpput" zum Kontaktieren eines externen FTP-Servers
  • "tftp" zum Kontaktieren eines externen TFTP-Servers
  • ein FTP-Server "ftpd"
  • ein TFTP-Server "tftpd"
  • ein HTTP-Server "httpd"

Eigene Container erstellen

Als Ausgangsbasis kann ein von der Firmware erstellter Container dienen. Nach dem Herunterladen als Update-Paket muss dieses Paket mit "tar -xf <Dateiname"> in ein neues Verzeichnis entpackt werden. Das Manifest und der eigentliche Container liegen nun vor. Der Container ist ebenfalls ein tar-Archiv.

Um einen Container lokal entpacken und modifizieren zu können, ist es zwingend erforderlich, das tar-Archiv

  • in ein Dateisystem zu entpacken, das die Linux-Berechtigungen erhält (z.B. ext3, ext4, btrfs, nicht jedoch VFAT oder NTFS)
  • als "root" zu entpacken, damit enthaltene Device-Nodes angelegt werden können.
  • mit dem tar-Parameter "--preserve-permissions" zu entpacken

Nach dem Modifizieren der Dateien muss das root-Dateisystem wieder als tar-Archiv gepackt werden (tar cvf ../<Dateiname.tar>). Die neue MD5-Summe des neuen tar-Archivs muss in das Manifest eingetragen werden. Wenn sich der Dateiname verändert hat, muss auch dieser im Manifest angepasst werden. Das Manifest und die neue tar-Datei ergeben in einem neuen, gemeinsamen tar-Archiv das neue Update-Paket.

Zurück zur Übersicht