Docker Images erstellen mit Packer

30. Sep. 2020DevOps, Hashicorp, Packer, Testumgebung

Wie in einem frühreren Blog-Post beschrieben, erstellen wir Test- und Schulungsumgebungen auf einer speziell dafür erstellten Plattform. Die Kernkomponente davon ist Docker. Wir ersparen uns so die manuellen Installationsschritte der Atlassian Applikationen. Wie die Images erstellt werden möchte ich in diesem Post ein wenig erläutern.

Docker

Bei Docker handelt es sich um eine Software zum Verwalten von Linux-Containern. Das ist eine Technologie, die ein wenig an virtuelle Maschinen erinnert, aber wesentlich weniger schwergewichtig ist. Bei einer virtuellen Maschine wird ein kompletter Computer in Software abgebildet. Speicher wird ihr fest zugeteilt, und Festplattenplatz wird exklusiv reserviert. Das heisst, auch nicht benötigte Ressourcen sind besetzt. Docker hingegen isoliert nur den Prozess, der darin läuft, von allen anderen Prozessen des Host-Systems. Ein Docker-Container hingegen benutzt nach Möglichkeit die Ressourcen des Hosts. Man kann z.B. Node.js in ein Docker-Image installieren ohne, dass der Host davon betroffen ist. Alle Dateien, die auf dem Host installiert sind, können in dem Image weiterverwendet werden. So enthält ein Image z.B. keinen Linux-Kernel, es wird immer der vom Host-System verwendet. Auch kann man in einem Container beliebig Dateien schreiben und verändern, der Host ist davon nicht betroffen, solange das nicht explizit konfiguriert wird.

Packer

Docker erstellt einen laufenden Container aus einem sogenannten Image. Das sind Archive, die die Dateien enthalten, die der laufende Container benutzen soll. Um diese zu erstellen, benutzt man meistens ein Docker-File. Darin kann man z.B. Shell Befehle ausführen, und Dateien in das Ziel-Image kopieren. Das ist zwar praktisch, wir wollten aber auch Synergien mit anderen Tools nutzen:

  • Vagrant ist schon im Einsatz, der Build Prozess sollte auch dafür funktionieren.
  • Der Build Prozess sollte auch für die VM Images unseres Cloud-Providers funktionieren.

Da wir schon mehrere Hashicorp-Tools im Einsatz haben, fiel die Entscheidung auf Packer.

Build-File

Der Build-Prozess mit Packer wird mit einer Datei im JSON-Format konfiguriert. Am Beispiel von Jira soll die Erstellung eines Images demonstriert werden. Die Datei besteht aus mehreren Sektionen. Die erste, die man anschauen muss, ist Builders:

"builders": [
    {
        "communicator": "ssh",
        "source_path": "bento/ubuntu-18.04",
        "provider": "virtualbox",
        "add_force": true,
        "type": "vagrant"
    },
    {
        "type": "docker",
        "image": "ubuntu:18.04",
        "commit": true,
        "changes": [
            "WORKDIR /tmp",
            "USER jirauser",
            "ENV HOSTNAME jira",
            "Volume /var/atlassian/jira",
            "EXPOSE 8080",
            "ONBUILD RUN date",
        "CMD ["/usr/local/startup.sh"]"
    ]
  }]

Hier sieht man, dass zwei Builds konfiguriert sind. Einmal für Vagrant (Virtualbox) und einmal für Docker. Bei Virtualbox passiert nicht viel, man konfiguriert ein Basisimage. In Docker müssen ein paar Sachen mehr konfiguriert werden.

Die wichtigsten Parameter:

  • image: Bei Docker geht man (fast) immer von einem Basisimage aus, auf das man aufbaut. Man findet sie auf Docker Hub.
  • CMD: Der Befehl, der beim Start des Images ausgeführt wird.
  • ENV: Man kann beim Build Umgebungsvariablen verwenden. Der ENV-Parameter kann mehrfach verwendet werden.
  • Volume: Ordner, die vom laufenden Container auf den Host verbunden werden. Dateien, die dort hinein geschrieben werden überstehen auch einen Container-Neustart, alle anderen nicht.
  • EXPOSE: Gibt die Netzwerk-Ports an, die der Container benötigt.

Der nächste wichtige Block sind die Provisioner. Damit kann man automatisieren, wie und mit was das Image erstellt und konfiguriert wird:

"provisioners": [{
            "type": "file",
            "source": "resources/",
            "destination": "/tmp"
        },
        {
            "type": "file",
            "source": "scripts/jira/",
            "destination": "/tmp"
        },
        {
            "type": "file",
            "source": "scripts/jira/startup.sh",
            "destination": "/usr/local/"
        },
        {
            "type": "shell",
            "inline": "chmod u+x /usr/local/startup.sh"
        },
        {
            "type": "shell",
            "inline": "chmod u+x /tmp/*.sh"
        },
        {
            "type": "shell",
            "scripts": [
                "scripts/jira/docker-base.sh",
                "scripts/common/java.sh"
            ]
        },
        {
            "type": "shell",
            "inline": "bash /tmp/jira.sh {{user `version`}} {{user `software_memory_min`}} {{user `software_memory_max`}}"
        }
    ]

Der wichtigsten Provisioner sind:

  • file: Kopiert Dateien vom Host in den Container. Kann auch ganze Verzeichnisse kopieren.
  • shell: Führt Shell Scripts oder Shell Befehle aus. Man kann entweder Dateien angeben (scripts) oder direkt ein oder mehrere Befehle (inline).

Hier tauchen auch zum ersten Mal Variablen auf. Man kann sie aber überall in der Datei verwenden.

{
    "type": "shell",
    "inline": "bash /tmp/jira.sh {{user `version`}} {{user `software_memory_min`}} {{user `software_memory_max`}}"
}

Packer ersetzt ein Konstrukt wie {{user `version`}} durch den Wert, der in der Variable version konfiguriert ist.

Variablen können auf mehrere Arten gesetzt werden. Beim Start von Packer als Kommandozeilenargument, in einer weiteren Konfigurationsdatei, oder im variables Block:

"variables": {
    "compression_level": "6",
    "software_memory_max": "2048m",
    "software_memory_min": "1024m"
}

Damit kann man Defaultwerte für die Variablen vorgeben. Sie können aber auch mit den anderen beiden Varianten überschrieben werden.

Der letzte Block sind die post-processors. Die Provisioners sind unabhängig von den Buildern. Viele Aktionen, die man gerne automatisieren möchte, sind aber abhängig vom Builder. Z.B. benutzt man für Docker und Vagrant verschiedene Repositories, Docker Hub und Vagrant Cloud. Auch kann man mit dem Virtualbox-Builder das Image kompimieren, bei Docker nicht. Beispiel Vagrant Builder:

"post-processors": [{
    "type": "vagrant",
    "compression_level": "{{user `compression_level`}}",
    "keep_input_artifact": true,
    "output": "zuara-base-{{user `version`}}-{{.Provider}}.box",
    "only": ["vagrant"]
},
{
    "type": "vagrant-cloud",
    "box_tag": "mairer/zuara-base",
    "access_token": "{{user `cloud_token`}}",
    "version": "{{user `version`}}",
    "only": ["vagrant"]
}]

Hier sind zwei Post Processors konfiguriert, einmal zum Nachbearbeiten des Images (vagrant) und einmal zum Hochladen des Images (vagrant-cloud). Auch hier können Variablen verwendet werden. Mit der Option „only“: [„vagrant“] sagt man Packer, dass der Post-Processor nur beim Vagrant-Build ausgeführt werden soll. Ein Beispiel, um nach dem Docker-Build das Image zu taggen:

{
    "type": "docker-tag",
    "repository": "zuara/jira",
    "tag": "{{user `version`}}"
    "only": ["docker"]
}

Build

Ein Build kann jetzt mit folgendem Befehl gestartet werden:

packer build --only=docker -var 'version=7.13.3' buildfile.json

Dieser Befehl erstellt das Docker Image. Der Vagrant-Build kann entsprechend mit folgendem Befehl ausgeführt werden:

packer build --only=vagrant -var 'version=7.13.3' buildfile.json

Somit können wir beliebige Jira-Versionen für verschiedene Virtualisierungstechniken mit kleinstem Aufwand erstellen.

Haben Sie Fragen oder Anregungen zum diesem Blog-Beitrag? Dürfen wir Sie unterstützen?
Schreiben Sie uns auf hallo@zuara.ch oder rufen Sie uns an: 031 302 60 00. Wir freuen uns auf Ihre Anfrage!

Der Autor:

Roman Maire

Roman Maire

roman.maire@zuara.ch

Direkt: +41 79 307 60 29

      

Weitere Fachartikel und Neuigkeiten von Zuara

Jira Software Cloud – neu mit Performance-Messungen für Dev-Teams

Jira Software Cloud bietet 4 neue Features für Entwicklungs-Teams, die es endlich erlauben, Code und Code-Repositories mit Issues zu verknüpfen und die Deployments in verschiedenen Stages zu visualisieren. Die Folge davon: weniger Kontext-Wechsel, weniger...

Kollaborationsarchitektur – weg mit dem Tool-Salat!

Im letzten Blog-Beitrag "Digital Workplace/Home-Office – wie verteilte Zusammenarbeit gut funktioniert und wie nicht" bin ich bereits kurz auf den sperrigen Begriff Kollaborationsarchitektur eingegangen. Hier soll es nun darum gehen, diesen Begriff zu erklären und...

Tabellenkalkulation in Confluence

Excel ist aufgrund der vielfältigen Möglichkeiten zur Tabellenkalkulation sowie der Flexibilität in vielen Unternehmen weit verbreitet. Deshalb taucht auch in Zusammenhang mit dem Einsatz von Confluence oft die Frage auf, welche Funktionen zur Tabellenkalkulation...

Confluence ist auch ein Content Management System

Genialer Werkzeugkasten: Die Software Atlassian® Confluence® ist ein Wiki oder neudeutsch ein Social Collaboration Hub - also eine elektronische Plattform, auf der Menschen zusammenarbeiten, Inhalte und Wissen teilen, organisieren und diskutieren. Confluence kann noch...

Vorteile für den Wechsel in die Atlassian Cloud

Der Wechsel in die Cloud ist kein einfacher und schneller Entscheid. Zu diesem Thema gebe ich Ihnen in diesem Blog eine kurze Übersicht zu den Vorteilen der Migration auf die Cloud. Atlassian Cloud ist für Unternehmen aller Grössen und zahlreiche Anwendungsfälle...

Phänomene ineffektiver Teams

Kennen Sie das? Irgendwie happert es dem Team an Drive, z.B. werden nicht alle User-Stories aufs Sprint-Ende umgesetzt oder auf dem KanBan Board stapeln sich die MMFs in der "To-Deploy"-Spalte. Und dann hat das Ganze auch noch keine Konsequenzen für die...

Wo befinden sich meine Daten bei Atlassian Cloud?

Wie im Blog «Atlassian setzt auf Cloud» beschrieben, wird ab dem 2. Februar 2021 keine neue Server-Lizenz für die Atlassian Produkte verkauft und die Lizenzen können maximal noch für 3 Jahre gelöst werden. Anschliessend stellt Atlassian das Produkt ein. Die Zeit bis...

Quo Vadis Jira Service Desk?

Ausgangslage Am 9. November hat Atlassian das neueste Produkt angekündigt: Jira Service Management. Es handelt sich dabei nicht um ein komplett neues Produkt, sondern um eine Weiterentwicklung von Jira Service Desk. Atlassian will damit auf geänderte Anforderungen und...

Jira Service Desk: Strukturierter Import mit Insight

Ausgangslage Eine häufige Anforderung für Service Desk ist es, Bestellungen darüber abwickeln zu können. Um die Daten zu managen, bietet sich die App Insight - Asset Management an, die kürzlich von Atlassian übernommen wurde. Mit ihr können Daten als Objekte mit...

KPI-Reporting in Jira

Jira ist viel mehr als nur eine Projektmanagementsoftware. Es können damit zum Beispiel auch interne Prozesse abgewickelt, Arbeitszeiten rapportiert oder - mit Jira Service Desk - ein komplettes IT Service Desk damit betrieben werden. Ein weiterer Anwendungsfall ist...

Pin It on Pinterest

Share This