LXD-Container per Ansible erstellen lassen

Datum

Ich werde hier nicht weiter auf die grundlegende Bedienung von Ansible oder LXD eingehen, sondern setze ein gewissen Basiswissen voraus.

Das Testfeld

ich habe eine Maschine mit Ansible vorbereitet und eine neu installierte VM mit Ubuntu 18.04.

Auf der VM mit Ubuntu 18.04, welche als LXD-Host fungieren soll und auf der die unterschiedlichen Container dann ausgerollt werden, sollte der Ansible-Host volle Zugriffsrechte haben.
Des weiteren sollte auf dem LXD-Host soweit alles eingerichtet sein, dass der Ansible-Benutzer problemlos Container erstellen kann, dh. lxd init wurde durchlaufen und der Ansible-Benutzer ist Mitglied der Benutzergruppe lxd.

Erstellen der Container-Gruppen

wie bei allen Hosts in Ansible können wir auch Container entsprechend kategorisieren.

Bei dem folgenden Beispiel sollen 2 Ubuntu18.04-Container und 2 Container mit Alpine-Linux erstellt werden.
Alpine-Linux wird gerne aufgrund seiner geringen Imagegröße eingesetzt.

zum Vergleich:

$ lxc image list
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
| ALIAS | FINGERPRINT  | PUBLIC |                 DESCRIPTION                 |  ARCH  |   SIZE   |         UPLOAD DATE          |
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
|       | 353b1a2c367e | no     | ubuntu 16.04 LTS amd64 (release) (20180427) | x86_64 | 156.95MB | May 4, 2018 at 12:24pm (UTC) |
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
|       | caaa29e9e73f | no     | Alpine 3.7 amd64 (20180503_17:50)           | x86_64 | 1.80MB   | May 4, 2018 at 12:25pm (UTC) |
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+

Bei dem erstellen meiner Konfigurationsdateien gehe ich von /etc/ansible/ als Basisordner aus.

ansible@ansible01:~$ pwd
/etc/ansible

Nun geht es an das Gruppieren der neuen Container…
Hierzu legen wir uns das Verzeichnis inventory an und darin erstellen wir die Datei containers mit folgendem Inhalt:

[lxd]
ubuntu02

[ubuntu-container]
test03
test04

[alpine-container]
blog01
db03

Dabei gibt die Gruppe [lxd] an auf welchen LXD-Host die Container erstellt werden sollen. Und die Gruppen [ubuntu-container] und [alpine-container] beinhalten die Aliase für die späteren Container welche dann mit dem entsprechenden Image gebaut werden sollen.

Auch hierbei sollte der DNS-Name (in meinem Fall: ubuntu02) auf eine passende IP auflösen.

Erstellen des Playbooks

Der Name des neuen Playbooks, welches wir für die Erstellung der Container erstellen wollen lautet: create_playbook.yml und hat den folgenden Inhalt:

---
- hosts: lxd
  become: false
  tasks:
  - name: Erstellen von Ubuntu16.04 LXD Container
    lxd_container:
      name: "{{item}}"
      state: started
      source:
        type: image
        mode: pull
        server: https://cloud-images.ubuntu.com/releases
        protocol: simplestreams
        alias: 16.04/amd64
      profiles: ['default']
      wait_for_ipv4_addresses: true
      timeout: 600
    with_items:
    - "{{groups['ubuntu-container']}}"

- hosts: lxd
  become: false
  tasks:
  - name: Erstellen von Alpine LXD Container
    lxd_container:
      name: "{{item}}"
      state: started
      source:
        type: image
        mode: pull
        server: https://images.linuxcontainers.org
        protocol: simplestreams
        alias: alpine/3.7
      profiles: ['default']
      wait_for_ipv4_addresses: true
      timeout: 600
    with_items:
    - "{{groups['alpine-container']}}"

Ganz oben stehen natürlich die obligatorischen 3 —- gefolgt von der Angabe des Hosts auf dem der nachfolgende Task ausgeführt werden soll.
become: false – wir benötigen keine Sudo-Rechte für die Ausführung
tasks: – Beschreibung der eigentlichen Ausführung folgen nun
- name: – Name des Arbeitsschrittes
lxd_container: – gibt an um welche Art Container es sich handelt
name: "{{item}}" – Der Name/Alias des Containers ist hierbei ein Platzhalter, welcher später durch with_items: beschrieben wird, die Namen werden dann aus der entsprechenden Gruppe entnommen
state: started – der Container soll nach der Erstellung gleich gestartet werden
source: – Beschreibt nachfolgend woher das Image für die Container hergenommen werden soll
type: image – Es handelt sich (typischerweise) um ein Image
mode: pull – Das Image wird vom nachfolgenden server: herunterladen und dabei wird das mit protocol: angegebene Protokoll verwendet.
alias: – Welchen Alias hat das gewünschte Image auf dem Remote-Server
profiles: ['default'] – Sofern gewünscht kann hier ein eigenes LXD-Profil angegeben werden
wait_for_ipv4_addresses: – Hier wird festgelegt ob erst nach der Zuweisung einer IP-Adresse mit der Erstellung weiterer Container weitergemacht werden soll
timeout: – Solange wird im Zweifelsfall auf eine entsprechende Reaktion der Gegenseinte gewartet.

Playbook starten

Um die gewünschten Container auf dem entsprechenden LXD-Host zu erstellen verwendet wir:
$ ansible-playbook create_playbook.yml -i inventory/containers

ansible@ansible01:~$ ansible-playbook create_playbook.yml -i inventory/containers

PLAY [lxd] ********************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [ubuntu02]            

TASK [Erstellen von Ubuntu16.04 LXD Container] ********************************************************************************************************************************************************************
changed: [ubuntu02] => (item=test03)              
changed: [ubuntu02] => (item=test04)

PLAY [lxd] ********************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [ubuntu02] 

TASK [Erstellen von Alpine LXD Container] ************************************************************************************************************************************************************************$
changed: [ubuntu02] => (item=blog01)
changed: [ubuntu02] => (item=db03)

PLAY RECAP ********************************************************************************************************************************************************************************************************
ubuntu02                   : ok=4    changed=2    unreachable=0    failed=0

ubuntu02                   : ok=2    changed=1    unreachable=0    failed=0

Nachdem es keine Probleme bei der Durchführung gab, sollten die 4 LXCs auf dem LXD-Host laufen…

$ lxc list
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+
|  NAME  |  STATE  |         IPV4          |                     IPV6                      |    TYPE    | SNAPSHOTS |
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+
| blog01 | RUNNING | 10.101.210.117 (eth0) | fd42:d7c3:eddc:f33f:216:3eff:fef6:afc7 (eth0) | PERSISTENT | 0         |
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+
| db03   | RUNNING | 10.101.210.189 (eth0) | fd42:d7c3:eddc:f33f:216:3eff:fee6:d767 (eth0) | PERSISTENT | 0         |
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+
| test03 | RUNNING | 10.101.210.99 (eth0)  | fd42:d7c3:eddc:f33f:216:3eff:fe6b:fd24 (eth0) | PERSISTENT | 0         |
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+
| test04 | RUNNING | 10.101.210.66 (eth0)  | fd42:d7c3:eddc:f33f:216:3eff:fe19:d60c (eth0) | PERSISTENT | 0         |
+--------+---------+-----------------------+-----------------------------------------------+------------+-----------+

Da mir leider kein Befehl bekannt ist um sich die Linux-Version jedes Containers anzeigen zu lassen, verwende ich einen OneLiner:

$ for i in $(lxc list | awk '{print $2}' | grep -v NAME | grep -v ^$); do echo $i && lxc exec $i -- /bin/cat /etc/issue | head -n1 && echo ""; done
blog01
Welcome to Alpine Linux 3.7

db03
Welcome to Alpine Linux 3.7

test03
Ubuntu 16.04.4 LTS \n \l

test04
Ubuntu 16.04.4 LTS \n \l

Damit stehen die Container für die weitere Bearbeitung bereit.

Autor
Kategorien Ansible, LXC/LXD

PRTG Map