SaltStack — zarządzanie konfiguracją serwerów z master/minion
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS / Automatyzacja
Gdy zarządzasz dziesiątkami lub setkami serwerów, SSH i ręczne skrypty przestają wystarczać. SaltStack (Salt) oferuje scentralizowane zarządzanie konfiguracją z architekturą master/minion i komunikacją przez ZeroMQ — wysłanie polecenia do tysiąca serwerów zajmuje tyle samo czasu co do jednego. W odróżnieniu od Ansible (agentless), Salt wymaga instalacji agenta (minion) na każdym serwerze, ale zyskujesz szybkość, asynchroniczność i reaktory zdarzeń. Ten artykuł prowadzi przez instalację, pisanie States i zaawansowane targeting.
Instalacja Salt Master i Minion
# === Na serwerze Master === # Dodaj repozytorium Salt (Ubuntu 22.04) curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public \ | sudo gpg --dearmor -o /usr/share/keyrings/salt-archive-keyring-2023.gpg echo "deb [signed-by=/usr/share/keyrings/salt-archive-keyring-2023.gpg] \ https://packages.broadcom.com/artifactory/saltproject-deb stable main" \ | sudo tee /etc/apt/sources.list.d/salt.list sudo apt update && sudo apt install salt-master -y sudo systemctl enable --now salt-master # Konfiguracja /etc/salt/master # interface: 0.0.0.0 # IP mastera (lub konkretny interface) # file_roots: # base: # - /srv/salt # pillar_roots: # base: # - /srv/pillar # === Na każdym serwerze Minion === sudo apt update && sudo apt install salt-minion -y # Skonfiguruj adres mastera w /etc/salt/minion echo "master: 10.0.0.1" | sudo tee -a /etc/salt/minion echo "id: web-prod-01" | sudo tee -a /etc/salt/minion # Opcjonalne ID sudo systemctl enable --now salt-minion # === Na Masterze — akceptuj klucze minionów === salt-key -L # Wylistuj klucze (Accepted/Unaccepted/Rejected) salt-key -A # Akceptuj WSZYSTKIE (tylko w trusted network!) salt-key -a web-prod-01 # Akceptuj konkretny minion # Test połączenia salt '*' test.ping # web-prod-01: # True
Targeting minionów — globy, grainy, compound
Targeting to wybór minionów do których wysyłasz polecenie. Salt oferuje kilka metod, od prostych globów po złożone zapytania compound:
# Glob — wzorzec nazwy minionów (domyślny) salt '*' test.ping # Wszystkie miniony salt 'web-*' test.ping # Wszystkie zaczynające się od "web-" salt 'web-prod-0[1-3]' test.ping # web-prod-01, web-prod-02, web-prod-03 # Grain — metadane systemowe miniona (OS, hostname, IP, role) salt -G 'os:Ubuntu' test.ping # Wszystkie Ubuntu salt -G 'osrelease:22.04' test.ping salt -G 'roles:webserver' test.ping # Grain zdefiniowany przez użytkownika # Lista minionów po ID salt -L 'web-prod-01,db-prod-01' test.ping # Wyrażenie regularne salt -E 'web-prod-\d+' test.ping # Compound — łączenie targetów salt -C 'G@os:Ubuntu and web-*' test.ping salt -C 'G@os:Ubuntu and not db-*' test.ping salt -C 'web-* or db-*' test.ping salt -C 'G@roles:webserver and G@env:production' test.ping # NodeGroup — predefiniowane grupy w master config # /etc/salt/master: # nodegroups: # production: 'G@env:production' # webservers: 'web-*' salt -N production test.ping
States — deklaratywna konfiguracja (SLS YAML)
States definiują pożądany stan serwera w plikach .sls (YAML). Są idempotentne i obsługują zależności między zasobami. Przykład kompletnego state dla Nginx:
# /srv/salt/nginx/init.sls — state dla Nginx
nginx_installed:
pkg.installed:
- name: nginx
nginx_config:
file.managed:
- name: /etc/nginx/nginx.conf
- source: salt://nginx/files/nginx.conf
- user: root
- group: root
- mode: 644
- require:
- pkg: nginx_installed # Wymaga instalacji nginx
nginx_service:
service.running:
- name: nginx
- enable: True
- require:
- file: nginx_config # Wymaga poprawnego konfiga
- watch:
- file: nginx_config # Restart przy zmianie konfiga
# /srv/salt/nginx/files/nginx.conf — plik kopiowany do minionów
# (zwykły plik lub szablon Jinja2 z rozszerzeniem .j2)
# top.sls — mapowanie states do minionów
# /srv/salt/top.sls
base:
'web-*':
- nginx
- php-fpm
'db-*':
- mysql
'*':
- common
# Zastosowanie states
salt 'web-*' state.apply nginx # Konkretny state
salt '*' state.apply # Wszystkie states z top.sls
salt 'web-prod-01' state.apply --pillar "port=8080" # Z pillar override
salt '*' state.highstate # Alias dla state.apply bez argumentów Pillar — bezpieczne sekrety per minion
# /srv/pillar/top.sls — mapowanie pillar do minionów
base:
'db-*':
- mysql
'web-*':
- app-secrets
# /srv/pillar/mysql.sls — sekrety dla serwerów DB
mysql:
root_password: "super-secret-password-123"
app_user: "webapp"
app_password: "app-pass-456"
database: "myapp_production"
# /srv/pillar/app-secrets.sls
app:
api_key: "sk-1234567890abcdef"
jwt_secret: "jwt-secret-xyz"
redis_password: "redis-pass-789"
# Użycie Pillar w State (Jinja2)
# /srv/salt/mysql/init.sls
mysql_root_password:
mysql_user.present:
- name: root
- password: {{ pillar['mysql']['root_password'] }}
# Sprawdzanie pillar na minionie (debugowanie)
salt 'db-prod-01' pillar.data mysql
salt 'db-prod-01' pillar.get mysql:root_password Salt SSH — tryb agentless
# /etc/salt/roster — lista hostów dla Salt SSH web-prod-01: host: 10.0.1.10 user: root priv: /root/.ssh/id_ed25519 db-prod-01: host: 10.0.2.10 user: ubuntu sudo: True priv: /root/.ssh/id_ed25519 # Używanie Salt SSH (zamiast salt używasz salt-ssh) salt-ssh 'web-prod-01' test.ping salt-ssh '*' test.ping salt-ssh 'web-*' state.apply nginx # Bootstrap miniona przez Salt SSH (jednorazowo) salt-ssh 'new-server' bootstrap-salt.sh
Porównanie Salt, Ansible i Puppet
| Funkcja | SaltStack | Ansible | Puppet |
|---|---|---|---|
| Agent wymagany | Tak (Minion) | Nie (SSH) | Tak (puppet agent) |
| Język konfiguracji | YAML + Jinja2 | YAML + Jinja2 | Puppet DSL (Ruby-like) |
| Szybkość (1000 hostów) | Sekundy (ZeroMQ PUB/SUB) | Minuty (SSH) | Minuty (HTTPS) |
| Event system | Tak (reaktory, beacons) | Nie | Ograniczony |
| Krzywa uczenia | Średnia | Niska | Wysoka |
| Dla ilu serwerów | 10 - 10 000+ | 1 - 1 000 | 100 - 10 000+ |