Docker-Container mit Ansible konfigurieren

Traumpartner

IT-Automatisierung und Container sind aktuelle Themen in allen Datacentern. Ideal wäre es, wenn sich diese beiden Themen miteinander kombinieren ließen. Mit Ansible-Container steht eine solche Lösung zur Verfügung, mit der auch das umständliche Schreiben von Dockerfiles entfällt.
'Datenbanken' lautet der Schwerpunkt der Dezember-Ausgabe des IT-Administrator. Darin werfen wir einen Blick auf den Firewall-Schutz und das ... (mehr)

In der Container-Welt ist zwischen Containern und Images zu unterscheiden. Images stellen eine bestimmte Zielkonfiguration für einen Container zur Verfügung. Der Container selbst ist dabei sozusagen eine Instanz eines Container-Images. In einer Software-Supply-Chain können Images dabei durchaus mehrere Iterationen durchlaufen.

Hier ein typisches Beispiel: Der OS-Distributor stellt ein Image für das Basis-Betriebssystem zur Verfügung. Innerhalb des Unternehmens kümmert sich das Operationsteam darum, aus dem Default-OS-Image ein angepasstes Corebuild-Image zu erzeugen. Entwickler schließlich fügen mit ihrer Anwendung den letzten Layer hinzu. Das so erzeugte Image enthält somit alle notwendigen Software-Layer, um die eigentliche Anwendung in einem Container zu betreiben. Wird ein neuer Container auf Basis eines solchen Images erzeugt, sollte die darin enthaltene Anwendung fehlerfrei ablaufen.

In der Praxis zeigt sich jedoch, dass dieser Prozess in den allermeisten Fällen wesentlich komplexer ist. Einer der Gründe hierfür ist, dass Container-Images lediglich auf Basis eines Dockerfiles erzeugt werden. Eine Desired State Configuration (DSC) lässt sich hiermit nur schwer umsetzen. Gerade das Einbinden der notwendigen Konfigurationsdateien für System- und Applikationspakete gestaltet sich oftmals als nur sehr umständlich. Daher kommt bei vielen Admins eine umfangreiche Skriptsammlung zum Erzeugen von Containern zum Einsatz. Über diese werden dann zusätzliche Konfigurationsdateien in den Build-Prozess eingebunden, sodass sie dann im Container zur Verfügung stehen.

Besser wäre es, wenn die zu installierende Software und auch die Konfigurationsdateien über ein Konfigurationsmanagement-Tool wie beispielsweise Puppet, Chef, Ansible oder ähnliche Tools in den Container eingebunden werden könnten. Hiermit könnte man dann auf alle Vorteile eines solchen Tools zurückgreifen. Beispielsweise genügt zur Installation einer Software dann lediglich die Anweisung, welches Paket im Container installiert werden soll. Welcher Paketmanager hierfür zum Einsatz kommen soll, bleibt dann dem Konfigurationsmanagement-Tool überlassen. Gleiches gilt natürlich auch für Konfigurationsdateien und deren Pfade, die sich zwischen den eingesetzten Distributionen ja oftmals gewaltig unterscheiden.

Ansible hilft bei der Container-Produktion

Zum Glück verfügen mittlerweile die meisten der gängigen Konfigurationsmanagement-Tools über entsprechende Hooks, um auch mit Containern umzugehen. Besonders interessant ist das Projekt Ansible-Container [1], das Teil der Ansible-Automatisierungssoftware ist. Hiermit lässt sich der gesamte Lifecycle eines Containers mit Hilfe von Ansible steuern. Dies umfasst neben einer Desired State Configuration für die Container auch den Build-Prozess von Container-Images sowie den Upload der Images in die gewünschte Zielumgebung, sodass Container auf Basis der erzeugten Images innerhalb von unterschiedlichen Umgebungen erzeugt werden können. Auch das Starten von lokalen Containern übernimmt Ansible auf Wunsch.

Ansible greift hierfür auf zwei Dateien im YAML-Format zurück. Die Datei "container.yml" entspricht dabei im Wesentlichen dem docker-compose-Format [2] und definiert die zu installierenden Container und die dafür notwendigen Images. Wie bei docker-compose ist die Idee dabei, dass moderne Anwendungen aus mehreren Komponenten bestehen, die in unterschiedlichen Containern zum Einsatz kommen sollen. Diese Information und die Beziehung zwischen diesen Microservices werden in der Datei "container.yml" definiert. Ein typisches Beispiel hierfür ist eine Multitier-Anwendung, bestehend aus einem Anwendungsserver, einer Backend-Datenbank und einem Webserver. In "container.yml" würden hierfür also drei Services definiert werden, wobei für jeden Service ein eigenes Container-Image erzeugt wird.

Listing 1: Projekt initialisieren



# mkdir myproject && cd myproject
# ansible-container init
Ansible Container initialized.
# tree .
.
└── ansible
         ├── ansible.cfg
         ├── container.yml
         ├── main.yml
         ├── meta.yml
         ├── requirements.txt
         └── requirements.yml
1 directory, 6 files

Die Konfiguration der einzelnen Container findet über die Datei "main.yml" statt. Hierbei handelt es sich um ein Ansible-Playbook, das während des Build-Prozesses zum Einsatz kommt. Mit Hilfe von Ansible-Roles werden die Container mit der gewünschten Konfiguration versehen, worunter auch die Installation der gewünschten Software fällt. Hierbei lassen sich vordefinierte Rollen aus dem Ansible Galaxy Repository verwenden.

Wer sich das Ganze einmal ansehen möchte, findet auf Github das Software-Repository des Ansible-Container-Projekts. Mit Hilfe von "git clone" holen Sie dieses auf das eigene System und installieren im Anschluss die Software mit Hilfe des mitgelieferten Setup-Skripts:

# git clone https://github.com/ansible/ansible-container.git ansible-container
# cd ansible-container
# python setup.py install

Da Ansible-Container den Build-Prozess für die Container-Images in einem Container durchführt und zur Kommunikation mit den anderen Containern auf Docker zurückgreift, ist der Docker-Service an eine IP-Adresse statt lediglich an einen Unix-Socket zu binden:

# cat - <EOF | sudo tee /etc/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/docker daemon -H 0.0.0.0:2375
EOF
 
# systemctl daemon-reload && sudo service docker restart

Die geänderte Konfiguration machen Sie über die das folgende Kommando und der Umgebungsvariablen "DOCKER_ HOST" auf dem System bekannt, da ansonsten die Docker-Kommandozeilen-Tools nicht mehr funktionieren würden:

# export DOCKER_HOST="tcp://Host-IP:2375"

An dieser Stelle sei erwähnt, dass der Docker-Dienst ab nun natürlich aus dem Netzwerk heraus zu erreichen ist. Es bietet sich daher an, entweder ein eigenes VLAN für Docker einzurichten oder aber zumindest die Kommunikation mit Hilfe von TLS abzusichern. Eine entsprechende Dokumentation, wie die hierfür notwendige Konfiguration aussehen könnte, findet sich unter [3].

Um nun ein Container-Projekt zu starten, legen Sie zuerst einen neuen Projekt-Ordner an. Idealerweise befindet sich dieser zusammen mit dem Code der Applikationen in einem Versionskontrollsystem wie beispielsweise git. Die notwendige Verzeichnisstruktur wird dann mittels »ansible-container init« erzeugt. Listing 2 zeigt eine einfache "container.yml" zur Orchestrierung von zwei Containern.

Listing 2: container.yml



version: "1"
services:
    apache:
       image: "fedora/apache"
       ports:
          - "80:80"
       command: ["/usr/sbin/httpd", "-D", "FOREGROUND"]
       links:
          - couchdb
couchdb:
       image: "fedora/couchdb"
       ports:
          - "5984:5984"
       command: ["/bin/sh", "-e", "/usr/bin/ couchdb", "-a", "/etc/couchdb/ default.ini", "-a", "/etc/couchdb/ local.ini", "-b", "-r", "5", "-p", "/var/run/couchdb/couchdb.pid", "-o", "/dev/null", "-e", "/dev/null", "-R"]

Da eine Beschreibung der "main.yml"-Datei den Rahmen dieses Artikels sprengen würde, verweisen wir an dieser Stelle auf die vorhandene Dokumentation [4]. Der Build-Prozess der Container-Images wird mittels »ansible-container build« angestoßen. In der Ausgabe des Build-Prozesses ist zu sehen, dass das Ansible-Playbook direkt während des Builds ausgeführt wird. Die einzelnen Container lassen sich dann mit »ansible-container run« starten. Sind Sie mit dem Ergebnis zufrieden, können Sie die neuen Images mittels »ansible-container push« in die gewünschte Registry laden beziehungsweise mittels »ansible-container shipit« in eine Open­Shift- oder Kubernetes-Umgebung importieren.

Fazit

Ansible-Container steuert den kompletten Lifecycle einer Container-Umgebung für eine Anwendung. Mit Hilfe von Playbooks wird die gewünschte Konfiguration eines Containers definiert und nach einem Build-Prozess stehen die Images mit der gewünschten Konfiguration zur Verfügung. Sie lassen sich dann entweder innerhalb der Entwicklungsumgebung starten oder in die gewünschte Zielumgebung hochladen. Das umfangreiche Repository Ansible Galaxy hilft dabei, die gewünschte Zielkonfiguration mit bereits vordefinierten Rollen umzusetzen.

(of)

Link-Codes

[1] Ansible-Container-Projekt: https://www.ansible.com/ansible-container/

[2] docker-compose: https://docs.docker.com/compose/

[3] Docker-TLS-Konfiguration: https://docs.ansible.com/ansible-container/installation.html/

[4] Ansible-Container Getting Started: https://docs.ansible.com/ansible-container/getting_started.html/

Ähnliche Artikel

comments powered by Disqus
Mehr zum Thema

Quellcode von Ansible Tower verfügbar

Red Hat hat geraume Zeit nach der Akquisition von Ansible den Quellcode des Management-Tools veröffentlicht. 

Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023