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.