Docker Compose Leitfaden: Verwaltung von Multi-Container-Anwendungen
Multi-Container-Anwendungen mit Docker Compose definieren: Service-Abhängigkeiten, Umgebungsvariablen, Health Checks, Skalierung und Production-Deployment.
Ansible Schritt für Schritt: Installation, Inventory, Playbooks, Rollen, Variablen, verschlüsselter Vault, Ad-hoc-Befehle und Serverautomatisierung.
Ansible ist ein Open-Source-Tool, mit dem Sie Server-Konfiguration, Anwendungsbereitstellung und Aufgabenautomatisierung als Code verwalten können. Dank seiner agentenlosen Architektur verbindet es sich nur über SSH mit Zielservern.
Hauptmerkmale von Ansible:
Ansible verbindet sich vom Control Node über SSH mit Zielservern. Für Windows-Server wird WinRM verwendet.
# PPA-Repository hinzufügen
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
# Version prüfen
ansible --version
# EPEL-Repository hinzufügen
sudo dnf install epel-release -y
sudo dnf install ansible -y
# Alternative: über pip installieren
pip3 install ansible
# Python-Virtual-Environment erstellen
python3 -m venv ansible-env
source ansible-env/bin/activate
# Ansible und zusätzliche Tools installieren
pip install ansible ansible-lint
# Version prüfen
ansible --version
Inventory definiert die Server, die Ansible verwalten soll:
# /etc/ansible/hosts oder benutzerdefinierte Inventory-Datei
# Einzelner Server
web1.example.com
# Gruppendefinition
[webservers]
web1.example.com
web2.example.com ansible_port=2222
192.168.1.10 ansible_user=ubuntu
[databases]
db1.example.com
db2.example.com
# Gruppenvariablen
[webservers:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3
# Übergeordnete Gruppe
[production:children]
webservers
databases
# inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
ansible_port: 22
web2.example.com:
ansible_port: 2222
vars:
ansible_user: deploy
http_port: 80
databases:
hosts:
db1.example.com:
db2.example.com:
vars:
ansible_user: dbadmin
db_port: 5432
Führen Sie Befehle ohne Playbook für schnelle Aufgaben aus:
# Ping-Test
ansible all -m ping
ansible webservers -m ping -i inventory.yml
# Befehl ausführen
ansible all -m command -a "uptime"
ansible webservers -m shell -a "df -h"
# Datei kopieren
ansible webservers -m copy -a "src=/local/file dest=/remote/path"
# Paket installieren
ansible webservers -m apt -a "name=nginx state=present" --become
# Dienst verwalten
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become
# Datei erstellen/löschen
ansible all -m file -a "path=/tmp/test state=touch"
ansible all -m file -a "path=/tmp/test state=absent"
# Facts sammeln
ansible web1.example.com -m setup
ansible all -m setup -a "filter=ansible_os_family"
# site.yml
---
- name: Webserver konfigurieren
hosts: webservers
become: yes # sudo verwenden
vars:
http_port: 80
max_clients: 200
tasks:
- name: Nginx installieren
apt:
name: nginx
state: present
update_cache: yes
- name: Nginx-Konfiguration kopieren
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Nginx neu starten
- name: Nginx-Dienst starten
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Nginx neu starten
service:
name: nginx
state: restarted
# Bedingte Tasks
- name: Paket auf Ubuntu installieren
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "Debian"
- name: Paket auf RHEL installieren
dnf:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "RedHat"
# Benutzer mit Schleife erstellen
- name: Benutzer erstellen
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
loop:
- { name: 'alice', groups: 'sudo' }
- { name: 'bob', groups: 'www-data' }
# Registrieren und Bedingung
- name: Nginx-Version prüfen
command: nginx -v
register: nginx_version
ignore_errors: yes
- name: Nginx installieren wenn nicht vorhanden
apt:
name: nginx
state: present
when: nginx_version.rc != 0
# group_vars/webservers.yml
http_port: 80
https_port: 443
app_user: www-data
app_dir: /var/www/html
# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
server_name: web1.example.com
# Variablenverwendung im Playbook
- name: Anwendungsverzeichnis erstellen
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
# Facts verwenden
- name: Systeminformationen anzeigen
debug:
msg: |
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPU: {{ ansible_processor_vcpus }} Kerne
RAM: {{ ansible_memtotal_mb }} MB
IP: {{ ansible_default_ipv4.address }}
Zum Verschlüsseln sensibler Daten:
# Verschlüsselte Datei erstellen
ansible-vault create secrets.yml
# Vorhandene Datei verschlüsseln
ansible-vault encrypt vars/passwords.yml
# Verschlüsselte Datei bearbeiten
ansible-vault edit secrets.yml
# Verschlüsselte Datei anzeigen
ansible-vault view secrets.yml
# Verschlüsselung entfernen
ansible-vault decrypt vars/passwords.yml
# Passwort ändern
ansible-vault rekey secrets.yml
# Playbook mit Vault ausführen
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
# Rolle erstellen
ansible-galaxy init roles/nginx
# Rollen-Verzeichnisstruktur
roles/nginx/
├── defaults/
│ └── main.yml # Standardvariablen
├── files/
│ └── nginx.conf # Statische Dateien
├── handlers/
│ └── main.yml # Handler
├── meta/
│ └── main.yml # Rollen-Metadaten
├── tasks/
│ └── main.yml # Hauptaufgaben
├── templates/
│ └── vhost.conf.j2 # Jinja2-Templates
└── vars/
└── main.yml # Variablen
---
- name: Nginx-Webserver-Installation
hosts: webservers
become: yes
vars:
domain: example.com
web_root: /var/www/{{ domain }}
tasks:
- name: Nginx installieren
apt:
name: nginx
state: present
update_cache: yes
- name: Web-Verzeichnis erstellen
file:
path: "{{ web_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Beispiel-index.html erstellen
copy:
content: "<h1>Hallo von {{ inventory_hostname }}</h1>"
dest: "{{ web_root }}/index.html"
owner: www-data
- name: Virtual Host konfigurieren
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: Nginx neu laden
- name: Virtual Host aktivieren
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: Nginx neu laden
- name: Standard-Site deaktivieren
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Nginx neu laden
- name: UFW Nginx-Erlaubnis
ufw:
rule: allow
name: 'Nginx Full'
handlers:
- name: Nginx neu laden
service:
name: nginx
state: reloaded
---
- name: Benutzerverwaltung
hosts: all
become: yes
vars_files:
- vars/users.yml
tasks:
- name: Sudo-Gruppe erstellen
group:
name: sudo
state: present
- name: Benutzer erstellen
user:
name: "{{ item.username }}"
comment: "{{ item.full_name }}"
groups: "{{ item.groups | join(',') }}"
shell: /bin/bash
create_home: yes
state: present
loop: "{{ users }}"
- name: SSH-Public-Key hinzufügen
authorized_key:
user: "{{ item.username }}"
key: "{{ item.ssh_key }}"
state: present
loop: "{{ users }}"
when: item.ssh_key is defined
- name: Sudo-Berechtigung erteilen
copy:
content: "{{ item.username }} ALL=(ALL) NOPASSWD:ALL"
dest: /etc/sudoers.d/{{ item.username }}
mode: '0440'
loop: "{{ users }}"
when: item.sudo | default(false)
# Grundlegende Ausführung
ansible-playbook site.yml
# Mit spezifischem Inventory
ansible-playbook -i inventory.yml site.yml
# Spezifischer Host oder Gruppe
ansible-playbook site.yml --limit webservers
ansible-playbook site.yml --limit web1.example.com
# Dry-Run (Prüfung ohne Änderungen)
ansible-playbook site.yml --check
# Verbose-Modus
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv
# Bestimmte Tags ausführen
ansible-playbook site.yml --tags "nginx,ssl"
ansible-playbook site.yml --skip-tags "debug"
# Zusätzliche Variablen
ansible-playbook site.yml -e "env=production version=1.5"
Ansible ist einer der zugänglichsten Wege, Server-Automatisierung als Code zu verwalten. Mit seiner agentenlosen Architektur, der großen Modulbibliothek und der YAML-basierten Struktur können Sie sowohl kleine als auch große Infrastrukturen einfach verwalten. Halten Sie sensible Daten mit Vault sicher, während Sie mit Rollen wiederverwendbare Konfigurationen erstellen.
Ansible arbeitet agentenlos (nur SSH erforderlich), während Puppet und Chef eine Agent-Installation auf Zielservern benötigen. Ansible ist YAML-basiert und einfacher zu erlernen. Puppet und Chef bieten leistungsfähigeres Zustandsmanagement, sind aber komplexer einzurichten und zu erlernen. Ansible wird für kleine bis mittelgroße Infrastrukturen bevorzugt.
Idempotenz bedeutet, dass das mehrfache Ausführen derselben Operation immer dasselbe Ergebnis liefert. Ansible-Module sind idempotent konzipiert: Wenn nginx bereits installiert ist, wird es nicht neu installiert; wenn eine Datei bereits korrekt ist, wird sie nicht geändert. Dadurch können Playbooks sicher erneut ausgeführt werden.
Wenn das Vault-Passwort vergessen wird, können verschlüsselte Dateien nicht wiederhergestellt werden. Daher ist es wichtig, das Vault-Passwort in einem sicheren Passwort-Manager (1Password, Bitwarden usw.) zu speichern. In Produktionsumgebungen wird empfohlen, das Vault-Passwort in eine Datei zu schreiben (--vault-password-file) und sicher aufzubewahren.
Ansible Galaxy ist die offizielle Plattform, auf der von der Community erstellte Rollen und Sammlungen geteilt werden (galaxy.ansible.com). Mit Befehlen wie 'ansible-galaxy install geerlingguy.nginx' können fertige Rollen heruntergeladen werden. So können getestete Rollen verwendet werden, anstatt von Grund auf neu zu schreiben.
Erhöhen Sie den 'forks'-Wert in ansible.cfg (Standard 5, 20-50 empfohlen). Reduzieren Sie SSH-Verbindungen mit 'pipelining = True'. Ermöglichen Sie parallele Ausführung unabhängiger Hosts mit 'strategy: free'. Kontrollieren Sie die Batch-Größe mit 'serial' in großen Inventories.
Ja, Ansible kann Windows-Server über das WinRM-Protokoll (Windows Remote Management) verwalten. Die Einstellungen 'ansible_connection: winrm' und 'ansible_winrm_transport: ntlm' sind erforderlich. Windows-Module beginnen mit dem Präfix 'win_': win_package, win_service, win_file usw.
Multi-Container-Anwendungen mit Docker Compose definieren: Service-Abhängigkeiten, Umgebungsvariablen, Health Checks, Skalierung und Production-Deployment.
CI/CD-Pipelines mit GitHub Actions erstellen: Docker Build und Push, SSH-Server-Deployment, Test-Automatisierung, Secrets-Verwaltung und Workflow-Optimierung.
Caddy-Webserver installieren: Caddyfile-Konfiguration, automatisches Let's Encrypt SSL, Reverse Proxy, statische Websites, PHP-FPM-Integration und Tuning.