How to manage servers with SaltStack on Linux
How to Manage Servers with SaltStack on Linux
SaltStack is a powerful, open-source configuration management and remote execution platform that enables system administrators to manage and automate infrastructure at scale. This comprehensive guide will walk you through everything you need to know about managing servers with SaltStack on Linux, from basic installation to advanced automation scenarios.
What is SaltStack?
SaltStack, commonly referred to as Salt, is an infrastructure automation and configuration management tool that uses a master-minion architecture. It allows you to execute commands, deploy applications, and manage configurations across thousands of servers simultaneously. Salt uses a fast, secure, and scalable communication system built on ZeroMQ and provides both remote execution capabilities and configuration management features.
Key Benefits of SaltStack
- Speed and Scalability: Can manage thousands of servers simultaneously
- Flexibility: Supports both agentless and agent-based management
- Security: Uses AES encryption for secure communication
- Extensibility: Highly customizable with Python-based modules
- Real-time Communication: Instant command execution and feedback
- Cross-platform Support: Works across various operating systems
Prerequisites and Requirements
Before diving into SaltStack implementation, ensure you have the following prerequisites in place:
System Requirements
- Operating System: Linux distribution (Ubuntu, CentOS, RHEL, Debian, SUSE)
- Python: Version 2.7 or 3.5+ (usually pre-installed on modern Linux distributions)
- Memory: Minimum 512MB RAM (2GB+ recommended for production)
- Network: Reliable network connectivity between master and minions
- Ports: TCP ports 4505 and 4506 open for Salt communication
User Requirements
- Root or sudo access on all target servers
- Basic understanding of Linux command line
- Familiarity with YAML syntax (Salt uses YAML for configuration)
- Understanding of networking concepts
Network Architecture Planning
Before installation, plan your Salt architecture:
- Salt Master: Central server that manages all minions
- Salt Minions: Managed servers that receive commands from the master
- Network Topology: Ensure proper network connectivity and firewall rules
Installing SaltStack
Installing Salt Master
The Salt Master is the central control server that manages all your infrastructure. Here's how to install it on different Linux distributions:
Ubuntu/Debian Installation
```bash
Update package repository
sudo apt update
Install required dependencies
sudo apt install -y wget curl
Add SaltStack repository
curl -fsSL https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -
echo 'deb https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest focal main' | sudo tee /etc/apt/sources.list.d/saltstack.list
Update repository and install Salt Master
sudo apt update
sudo apt install -y salt-master
```
CentOS/RHEL Installation
```bash
Install EPEL repository
sudo yum install -y epel-release
Add SaltStack repository
sudo yum install -y https://repo.saltproject.io/py3/redhat/salt-py3-repo-latest.el8.noarch.rpm
Install Salt Master
sudo yum install -y salt-master
```
Starting and Enabling Salt Master
```bash
Start Salt Master service
sudo systemctl start salt-master
Enable Salt Master to start on boot
sudo systemctl enable salt-master
Check service status
sudo systemctl status salt-master
```
Installing Salt Minions
Salt Minions are the managed servers that connect to the Salt Master. Install them on each server you want to manage:
Ubuntu/Debian Minion Installation
```bash
Add SaltStack repository (same as master)
curl -fsSL https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -
echo 'deb https://repo.saltproject.io/py3/ubuntu/20.04/amd64/latest focal main' | sudo tee /etc/apt/sources.list.d/saltstack.list
Update and install Salt Minion
sudo apt update
sudo apt install -y salt-minion
```
CentOS/RHEL Minion Installation
```bash
Add SaltStack repository
sudo yum install -y https://repo.saltproject.io/py3/redhat/salt-py3-repo-latest.el8.noarch.rpm
Install Salt Minion
sudo yum install -y salt-minion
```
Configuring Salt Minions
Each minion needs to know how to connect to the master:
```bash
Edit minion configuration
sudo nano /etc/salt/minion
Add or modify these lines:
master: YOUR_MASTER_IP_OR_HOSTNAME
id: unique-minion-name
```
Example minion configuration:
```yaml
/etc/salt/minion
master: 192.168.1.100
id: web-server-01
log_level: info
```
Start and enable the minion service:
```bash
sudo systemctl start salt-minion
sudo systemctl enable salt-minion
sudo systemctl status salt-minion
```
Initial Configuration and Setup
Accepting Minion Keys
When minions first connect to the master, their keys must be accepted for security:
```bash
List all pending keys
sudo salt-key -L
Accept a specific minion key
sudo salt-key -a minion-name
Accept all pending keys (use with caution)
sudo salt-key -A
List accepted keys
sudo salt-key -l accepted
```
Testing Connectivity
Verify that your Salt infrastructure is working:
```bash
Test connectivity to all minions
sudo salt '*' test.ping
Test connectivity to specific minion
sudo salt 'web-server-01' test.ping
Get system information from all minions
sudo salt '*' grains.items
```
Basic Salt Master Configuration
Configure the Salt Master for optimal performance:
```bash
Edit master configuration
sudo nano /etc/salt/master
```
Key configuration options:
```yaml
/etc/salt/master
interface: 0.0.0.0
auto_accept: False
file_roots:
base:
- /srv/salt
pillar_roots:
base:
- /srv/pillar
log_level: warning
```
Restart the master after configuration changes:
```bash
sudo systemctl restart salt-master
```
Core SaltStack Concepts
Salt States
Salt States are descriptions of system configuration. They define how systems should be configured and maintained:
```yaml
/srv/salt/apache.sls
apache2:
pkg.installed: []
service.running:
- enable: True
- require:
- pkg: apache2
/var/www/html/index.html:
file.managed:
- contents: |
Options FollowSymLinks
AllowOverride None
Require all denied
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
{% if grains['os'] == 'Ubuntu' %}
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
{% endif %}
```
Advanced SaltStack Features
Targeting Minions
Salt provides various ways to target specific minions:
```bash
Target by minion ID
sudo salt 'web-server-01' test.ping
Target using wildcards
sudo salt 'web*' test.ping
Target by grain
sudo salt -G 'os:Ubuntu' test.ping
sudo salt -G 'roles:webserver' test.ping
Target by pillar data
sudo salt -I 'apache:port:80' test.ping
Compound targeting
sudo salt -C 'G@os:Ubuntu and web*' test.ping
Target by subnet
sudo salt -S '192.168.1.0/24' test.ping
```
Salt Orchestration
Orchestration allows you to coordinate complex deployments:
```yaml
/srv/salt/orchestration/deploy-app.sls
deploy_database:
salt.state:
- tgt: 'role:database'
- tgt_type: grain
- sls:
- database.mysql
- database.schema
deploy_webservers:
salt.state:
- tgt: 'role:webserver'
- tgt_type: grain
- sls:
- webserver.apache
- webserver.php
- require:
- salt: deploy_database
update_load_balancer:
salt.state:
- tgt: 'role:loadbalancer'
- tgt_type: grain
- sls:
- loadbalancer.nginx
- require:
- salt: deploy_webservers
```
Run orchestration:
```bash
sudo salt-run state.orchestrate orchestration.deploy-app
```
Event System and Reactors
Salt's event system allows you to react to system events:
```yaml
/srv/salt/reactor/high-load.sls
scale_webservers:
local.state.apply:
- tgt: 'role:webserver'
- tgt_type: grain
- arg:
- webserver.scale-up
```
Configure reactor in master config:
```yaml
/etc/salt/master
reactor:
- 'custom/high_load':
- /srv/salt/reactor/high-load.sls
```
Custom Execution Modules
Create custom modules for specific tasks:
```python
/srv/salt/_modules/myapp.py
import subprocess
def deploy_version(version):
"""
Deploy a specific version of the application
"""
try:
cmd = f'/opt/myapp/deploy.sh {version}'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return {
'success': result.returncode == 0,
'stdout': result.stdout,
'stderr': result.stderr
}
except Exception as e:
return {'success': False, 'error': str(e)}
def get_app_status():
"""
Get application status
"""
try:
with open('/var/run/myapp.pid', 'r') as f:
pid = f.read().strip()
return {'running': True, 'pid': pid}
except FileNotFoundError:
return {'running': False}
```
Use custom modules:
```bash
Sync modules to minions
sudo salt '*' saltutil.sync_modules
Use custom module
sudo salt '*' myapp.get_app_status
sudo salt 'app-servers*' myapp.deploy_version v2.1.0
```
Monitoring and Logging
Salt Event Monitoring
Monitor Salt events in real-time:
```bash
Monitor all events
sudo salt-run state.event pretty=True
Monitor specific event tags
sudo salt-run state.event tag='salt/minion/*/start'
```
Logging Configuration
Configure detailed logging:
```yaml
/etc/salt/master
log_level: info
log_file: /var/log/salt/master
log_granular_levels:
'salt.loaded.int.module.publish': debug
'salt.loaded.int.module.manage': info
Rotate logs
log_rotate_max_bytes: 104857600 # 100MB
log_rotate_backup_count: 5
```
Health Checks and Monitoring
Create automated health checks:
```yaml
/srv/salt/monitoring/health-check.sls
check_disk_space:
cmd.run:
- name: |
df -h / | awk 'NR==2 {print $5}' | sed 's/%//' | \
awk '{if ($1 > 90) exit 1; else exit 0}'
- failhard: True
check_memory_usage:
cmd.run:
- name: |
free | awk '/^Mem:/ {printf "%.0f", $3/$2 * 100}' | \
awk '{if ($1 > 95) exit 1; else exit 0}'
- failhard: True
check_service_status:
service.running:
- names:
- apache2
- mysql
- redis-server
```
Troubleshooting Common Issues
Connection Problems
Issue: Minions not connecting to master
Solutions:
1. Check firewall settings:
```bash
On master, open required ports
sudo ufw allow 4505/tcp
sudo ufw allow 4506/tcp
For CentOS/RHEL
sudo firewall-cmd --permanent --add-port=4505/tcp
sudo firewall-cmd --permanent --add-port=4506/tcp
sudo firewall-cmd --reload
```
2. Verify network connectivity:
```bash
From minion, test connectivity
telnet MASTER_IP 4505
telnet MASTER_IP 4506
```
3. Check minion configuration:
```bash
Verify minion config
sudo salt-minion -l debug
```
Key Management Issues
Issue: Keys not being accepted
Solutions:
1. Clear old keys:
```bash
On master
sudo salt-key -d minion-name
On minion
sudo rm -rf /etc/salt/pki/minion/
sudo systemctl restart salt-minion
```
2. Check key fingerprints:
```bash
On master
sudo salt-key -f minion-name
On minion
sudo salt-call key.finger --local
```
State Application Failures
Issue: States failing to apply
Solutions:
1. Test states in debug mode:
```bash
sudo salt 'minion-name' state.apply statename test=True -l debug
```
2. Check state syntax:
```bash
Validate YAML syntax
python -c "import yaml; yaml.safe_load(open('/srv/salt/statefile.sls'))"
```
3. Review minion logs:
```bash
sudo tail -f /var/log/salt/minion
```
Performance Issues
Issue: Slow command execution
Solutions:
1. Optimize master configuration:
```yaml
/etc/salt/master
worker_threads: 10
timeout: 30
gather_job_timeout: 30
```
2. Use asynchronous execution:
```bash
Run commands asynchronously
sudo salt '*' cmd.run 'long-running-command' --async
```
3. Implement proper targeting:
```bash
Use specific targeting instead of '*'
sudo salt -G 'role:webserver' state.apply
```
Security Best Practices
Key Management
1. Regular Key Rotation:
```bash
Rotate minion keys periodically
sudo salt 'minion-name' saltutil.regen_keys
```
2. Secure Key Storage:
```bash
Protect key directories
sudo chmod 700 /etc/salt/pki/master
sudo chmod 600 /etc/salt/pki/master/*
```
Access Control
1. External Authentication:
```yaml
/etc/salt/master
external_auth:
pam:
saltadmin:
- '*':
- test.ping
- cmd.run
webteam:
- 'web*':
- state.apply
```
2. User Permissions:
```yaml
/etc/salt/master
client_acl:
saltadmin:
- .*
webteam:
- web.*
```
Network Security
1. SSL/TLS Configuration:
```yaml
/etc/salt/master
ssl_cert: /etc/ssl/certs/salt-master.crt
ssl_key: /etc/ssl/private/salt-master.key
```
2. Firewall Rules:
```bash
Restrict access to Salt ports
sudo ufw allow from 192.168.1.0/24 to any port 4505
sudo ufw allow from 192.168.1.0/24 to any port 4506
```
Performance Optimization
Master Optimization
1. Worker Thread Configuration:
```yaml
/etc/salt/master
worker_threads: 16
ret_port: 4506
pub_port: 4505
```
2. File Server Optimization:
```yaml
/etc/salt/master
file_buffer_size: 1048576
hash_type: sha256
```
Minion Optimization
1. Connection Settings:
```yaml
/etc/salt/minion
master_alive_interval: 30
master_tries: 3
acceptance_wait_time: 10
```
2. Module Loading:
```yaml
/etc/salt/minion
autoload_dynamic_modules: True
clean_dynamic_modules: True
```
Database Backend
For large deployments, consider using a database backend:
```yaml
/etc/salt/master
job_cache: mysql
mysql.host: 'localhost'
mysql.user: 'salt'
mysql.pass: 'salt_password'
mysql.db: 'salt'
mysql.port: 3306
```
Best Practices and Tips
State Organization
1. Directory Structure:
```
/srv/salt/
├── top.sls
├── common/
│ ├── init.sls
│ ├── users.sls
│ └── packages.sls
├── webserver/
│ ├── init.sls
│ ├── apache.sls
│ └── php.sls
└── database/
├── init.sls
└── mysql.sls
```
2. Top File Configuration:
```yaml
/srv/salt/top.sls
base:
'*':
- common
'web*':
- webserver
'db*':
- database
'role:loadbalancer':
- match: grain
- loadbalancer
```
Version Control
1. Git Integration:
```bash
Initialize Git repository
cd /srv/salt
git init
git add .
git commit -m "Initial Salt configuration"
Set up gitfs
/etc/salt/master
fileserver_backend:
- gitfs
- roots
gitfs_remotes:
- https://github.com/yourorg/salt-states.git
```
Testing and Validation
1. Test Mode:
```bash
Always test states before applying
sudo salt '*' state.apply test=True
```
2. Highstate Testing:
```bash
Test complete configuration
sudo salt '*' state.highstate test=True
```
3. State Validation:
```bash
Validate state files
sudo salt '*' state.show_sls statename
```
Documentation
1. State Documentation:
```yaml
Document your states
webserver_setup:
pkg.installed:
- name: apache2
- doc: |
Installs Apache web server
Requires: Ubuntu/Debian system
Provides: HTTP service on port 80
```
2. Pillar Documentation:
```yaml
/srv/pillar/webserver.sls
Webserver configuration pillar
Used by: webserver states
Required: apache.port, apache.admin_email
apache:
port: 80
admin_email: admin@example.com
```
Conclusion
SaltStack provides a powerful and flexible platform for managing Linux servers at scale. This comprehensive guide has covered the essential aspects of Salt deployment, from basic installation and configuration to advanced features like orchestration and custom modules.
Key Takeaways
1. Start Small: Begin with basic remote execution before implementing complex state management
2. Plan Architecture: Design your Salt infrastructure considering scalability and security
3. Use Version Control: Maintain your Salt configurations in version control systems
4. Test Thoroughly: Always test states and configurations before applying to production
5. Monitor Continuously: Implement proper logging and monitoring for your Salt infrastructure
6. Follow Security Best Practices: Implement proper authentication, authorization, and encryption
7. Document Everything: Maintain comprehensive documentation for your Salt configurations
Next Steps
To further enhance your SaltStack expertise:
1. Explore Advanced Features: Investigate Salt's orchestration, event system, and custom modules
2. Integration: Integrate Salt with CI/CD pipelines and monitoring systems
3. Community Resources: Engage with the Salt community for formulas and best practices
4. Certification: Consider pursuing SaltStack certification for professional validation
5. Automation: Develop comprehensive automation workflows for your infrastructure
SaltStack's flexibility and power make it an excellent choice for infrastructure automation. By following the practices outlined in this guide, you'll be well-equipped to manage your Linux server infrastructure efficiently and securely. Remember that mastering SaltStack is an ongoing process, and the key to success lies in continuous learning, testing, and refinement of your automation strategies.