Zehn Container von Hand aktuell zu halten, macht niemand lange. Ansible erledigt das mit einem einzigen Befehl und sorgt dafür, dass alle Container gleich eingerichtet sind.
Was ist Ansible?
Ansible ist ein Open-Source-Werkzeug zur Automatisierung. Man beschreibt in einfachen Textdateien (Playbooks, im YAML-Format), wie ein System aussehen soll: welche Pakete installiert sind, welche Benutzer es gibt, welche Dienste laufen. Ansible verbindet sich per SSH mit allen Containern und sorgt dafür, dass genau dieser Zustand hergestellt wird. Auf den Containern muss nichts installiert sein außer SSH und Python, beides steckt schon in unserer Vorlage.
- Inventar: die Liste aller Container, gern in Gruppen sortiert.
- Playbook: eine Abfolge von Aufgaben, z. B. „alle Updates einspielen“.
- Idempotent: Ein Playbook darf beliebig oft laufen. Ist schon alles richtig, ändert es nichts.
Installation
Ansible läuft auf dem Rechner, von dem aus man verwaltet, dem Control Node. Das kann der eigene Mac oder Linux-Rechner sein, oder ein eigener kleiner Container ansible aus der Vorlage.
# macOS
brew install ansible
# Debian (z. B. im Container „ansible“)
sudo apt install -y ansible
ansible --version
Das Projekt anlegen
vereins-it/
├── ansible.cfg
├── inventory.ini
├── base.yml Grundeinrichtung aller Container
└── update.yml Updates für alle
Den Ordner lege ich in ein Git-Repository. Dann ist jede Änderung an der Infrastruktur nachvollziehbar, und ein Nachfolger findet alles an einem Ort.
# ansible.cfg
[defaults]
inventory = inventory.ini
remote_user = admin
host_key_checking = True
interpreter_python = auto_silent
# inventory.ini
[infrastruktur]
proxy ansible_host=192.168.178.30
login ansible_host=192.168.178.31
status ansible_host=192.168.178.32
[anwendungen]
paperless ansible_host=192.168.178.40
medien ansible_host=192.168.178.41
mitglieder ansible_host=192.168.178.42
flows ansible_host=192.168.178.43
web ansible_host=192.168.178.44
cloud ansible_host=192.168.178.45
tresor ansible_host=192.168.178.46
[verein:children]
infrastruktur
anwendungen
Erster Test: Antworten alle Container?
ansible verein -m ping
Playbook: Updates für alle
# update.yml
- name: Alle Container aktualisieren
hosts: verein
become: true
serial: 1 # einer nach dem anderen, nie alle gleichzeitig
tasks:
- name: Paketlisten holen und alles aktualisieren
ansible.builtin.apt:
update_cache: true
upgrade: dist
autoremove: true
- name: Prüfen, ob ein Neustart nötig ist
ansible.builtin.stat:
path: /var/run/reboot-required
register: reboot_needed
- name: Neu starten, falls nötig
ansible.builtin.reboot:
when: reboot_needed.stat.exists
ansible-playbook update.yml --check # erst nur anzeigen, was passieren würde
ansible-playbook update.yml
Playbook: Grundeinrichtung
Alles, was jeder Container haben soll, steht an einer Stelle. Kommt ein neuer Container dazu, läuft das Playbook einmal über ihn, und er ist auf demselben Stand wie alle anderen.
# base.yml
- name: Grundeinrichtung
hosts: verein
become: true
vars:
admin_keys:
- "ssh-ed25519 AAAA... jan@laptop"
tasks:
- name: Basispakete
ansible.builtin.apt:
name: [sudo, curl, ca-certificates, unattended-upgrades, htop, ncdu]
state: present
update_cache: true
- name: Zeitzone
community.general.timezone:
name: Europe/Berlin
- name: SSH-Schlüssel der Verwalter
ansible.posix.authorized_key:
user: admin
key: "{{ item }}"
loop: "{{ admin_keys }}"
- name: SSH nur noch mit Schlüssel
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/10-verein.conf
create: true
line: "{{ item }}"
loop:
- "PasswordAuthentication no"
- "PermitRootLogin prohibit-password"
notify: ssh neu laden
handlers:
- name: ssh neu laden
ansible.builtin.service:
name: ssh
state: reloaded
Die Module community.general und ansible.posix sind bei einer normalen Ansible-Installation dabei. Falls nicht: ansible-galaxy collection install community.general ansible.posix.
Der nächste Schritt
Mit der Sammlung community.proxmox kann Ansible auch die Container selbst in Proxmox anlegen, klonen und starten. Dann ist die komplette Infrastruktur vom Container bis zur Anwendung beschrieben und lässt sich auf neuer Hardware in einer Stunde wieder aufbauen. Das ist das Ziel, aber kein Muss für den Anfang: Erst Updates und Grundeinrichtung automatisieren, dann Schritt für Schritt mehr.
Tipp: Vor großen Updates erst Snapshots aller Container in Proxmox anlegen und dann ansible-playbook update.yml laufen lassen. Geht etwas schief, ist jeder einzelne Container in Sekunden zurückgesetzt.