Set up memory limits and monitoring for containers using systemd services and cgroups v2 to prevent OOM kills and track resource usage.
Prerequisites
- Root access to Linux server
- systemd-based distribution
- Basic understanding of Linux processes
What this solves
When containers consume excessive memory, they can crash your applications or bring down entire systems through out-of-memory (OOM) kills. This tutorial shows you how to configure memory limits using systemd and cgroups v2, set up monitoring for memory pressure events, and implement automated alerts when containers approach their limits.
Step-by-step configuration
Verify cgroups v2 is enabled
Check that your system is using cgroups v2, which provides better memory management features than v1.
mount | grep cgroup
stat -fc %T /sys/fs/cgroup
If the output shows cgroup2fs, you're using cgroups v2. If not, enable it by editing the kernel boot parameters.
Install required monitoring tools
Install the tools needed for memory monitoring and pressure notifications.
sudo apt update
sudo apt install -y systemd-cgtop stress-ng mailutils
Create a test service with memory limits
Create a systemd service that demonstrates memory limiting and monitoring capabilities.
[Unit]
Description=Memory Test Service
After=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
ExecStart=/usr/bin/stress-ng --vm 1 --vm-bytes 100M --timeout 0
Restart=always
RestartSec=5
Memory limits
MemoryMax=128M
MemorySwapMax=0
MemoryHigh=100M
Enable memory accounting
MemoryAccounting=yes
TasksAccounting=yes
OOM policy
OOMPolicy=stop
[Install]
WantedBy=multi-user.target
Configure memory pressure monitoring
Create a script that monitors memory pressure using cgroups v2 pressure stall information.
#!/bin/bash
Memory pressure monitoring script
SERVICE_NAME="memory-test"
THRESHOLD=80
LOG_FILE="/var/log/memory-pressure.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
check_memory_usage() {
local cgroup_path="/sys/fs/cgroup/system.slice/${SERVICE_NAME}.service"
if [[ ! -d "$cgroup_path" ]]; then
log_message "ERROR: Service $SERVICE_NAME not found or not running"
return 1
fi
# Read current memory usage
local current_memory=$(cat "$cgroup_path/memory.current" 2>/dev/null || echo "0")
local memory_max=$(cat "$cgroup_path/memory.max" 2>/dev/null || echo "0")
if [[ "$memory_max" == "max" ]] || [[ "$memory_max" -eq 0 ]]; then
log_message "WARNING: No memory limit set for $SERVICE_NAME"
return 1
fi
# Calculate usage percentage
local usage_percent=$((current_memory * 100 / memory_max))
log_message "Memory usage: ${usage_percent}% (${current_memory} / ${memory_max} bytes)"
# Check pressure stall information
if [[ -f "$cgroup_path/memory.pressure" ]]; then
local pressure_some=$(grep "some" "$cgroup_path/memory.pressure" | cut -d' ' -f2 | cut -d'=' -f2)
local pressure_full=$(grep "full" "$cgroup_path/memory.pressure" | cut -d' ' -f4 | cut -d'=' -f2)
log_message "Memory pressure - some: ${pressure_some}, full: ${pressure_full}"
fi
# Alert if usage exceeds threshold
if [[ "$usage_percent" -gt "$THRESHOLD" ]]; then
log_message "ALERT: Memory usage ${usage_percent}% exceeds threshold ${THRESHOLD}%"
send_alert "$SERVICE_NAME" "$usage_percent" "$current_memory" "$memory_max"
fi
}
send_alert() {
local service="$1"
local percent="$2"
local current="$3"
local max="$4"
local message="Memory alert for service: $service
Usage: $percent% ($current / $max bytes)
Time: $(date)"
# Log to syslog
logger -p user.warning "Memory pressure alert: $service at $percent%"
# Optionally send email (configure postfix/sendmail first)
# echo "$message" | mail -s "Memory Alert: $service" admin@example.com
}
Main execution
check_memory_usage
sudo chmod +x /usr/local/bin/memory-pressure-monitor.sh
Set up automated monitoring with systemd timer
Create a systemd timer to run the memory monitoring script every 30 seconds.
[Unit]
Description=Memory Pressure Monitor
[Service]
Type=oneshot
ExecStart=/usr/local/bin/memory-pressure-monitor.sh
User=root
Group=root
[Unit]
Description=Run memory pressure monitor every 30 seconds
Requires=memory-monitor.service
[Timer]
OnBootSec=30
OnUnitActiveSec=30
AccuracySec=5
[Install]
WantedBy=timers.target
Configure OOM notification script
Create a script that monitors for OOM kills using kernel messages and systemd events.
#!/bin/bash
OOM kill monitoring script
LOG_FILE="/var/log/oom-monitor.log"
LAST_CHECK_FILE="/var/lib/oom-monitor-lastcheck"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
check_oom_events() {
# Get timestamp of last check
local last_check="$(cat "$LAST_CHECK_FILE" 2>/dev/null || echo "1 hour ago")"
# Check kernel messages for OOM kills
local oom_events=$(journalctl --since="$last_check" --grep="killed process" --output=json-pretty | jq -r '.MESSAGE // empty' 2>/dev/null)
if [[ -n "$oom_events" ]]; then
log_message "OOM kill detected:"
echo "$oom_events" >> "$LOG_FILE"
# Send alert
logger -p user.crit "OOM kill detected - check $LOG_FILE for details"
fi
# Check for systemd service failures due to memory
local failed_services=$(systemctl --failed --output=json | jq -r '.[] | select(.sub == "failed") | .unit' 2>/dev/null)
for service in $failed_services; do
local exit_status=$(systemctl show "$service" --property=ExecMainStatus --value)
if [[ "$exit_status" == "137" ]] || [[ "$exit_status" == "143" ]]; then
log_message "Service $service may have been OOM killed (exit status: $exit_status)"
fi
done
# Update timestamp
date > "$LAST_CHECK_FILE"
}
Main execution
check_oom_events
sudo chmod +x /usr/local/bin/oom-monitor.sh
sudo mkdir -p /var/lib
sudo touch /var/lib/oom-monitor-lastcheck
Enable and start monitoring services
Enable all monitoring services and start the test service to demonstrate memory limiting.
sudo systemctl daemon-reload
sudo systemctl enable --now memory-monitor.timer
sudo systemctl enable --now memory-test.service
Create memory usage dashboard script
Build a script to display real-time memory usage for all systemd services with memory limits.
#!/bin/bash
Memory usage dashboard for systemd services
print_header() {
printf "\n%-25s %-12s %-12s %-12s %-8s\n" "SERVICE" "CURRENT" "MAX" "HIGH" "USAGE%"
printf "%-25s %-12s %-12s %-12s %-8s\n" "-------" "-------" "---" "----" "------"
}
format_bytes() {
local bytes="$1"
if [[ "$bytes" == "max" ]] || [[ "$bytes" -eq 0 ]]; then
echo "unlimited"
elif [[ "$bytes" -gt 1073741824 ]]; then
printf "%.1fG" "$(echo "scale=1; $bytes/1073741824" | bc -l)"
elif [[ "$bytes" -gt 1048576 ]]; then
printf "%.1fM" "$(echo "scale=1; $bytes/1048576" | bc -l)"
elif [[ "$bytes" -gt 1024 ]]; then
printf "%.1fK" "$(echo "scale=1; $bytes/1024" | bc -l)"
else
echo "${bytes}B"
fi
}
get_service_memory() {
local service="$1"
local cgroup_path="/sys/fs/cgroup/system.slice/${service}"
if [[ ! -d "$cgroup_path" ]]; then
return 1
fi
local current=$(cat "$cgroup_path/memory.current" 2>/dev/null || echo "0")
local max=$(cat "$cgroup_path/memory.max" 2>/dev/null || echo "max")
local high=$(cat "$cgroup_path/memory.high" 2>/dev/null || echo "max")
local usage_percent="N/A"
if [[ "$max" != "max" ]] && [[ "$max" -gt 0 ]]; then
usage_percent="$((current * 100 / max))%"
fi
printf "%-25s %-12s %-12s %-12s %-8s\n" \
"${service%.service}" \
"$(format_bytes "$current")" \
"$(format_bytes "$max")" \
"$(format_bytes "$high")" \
"$usage_percent"
}
print_header
Find all services with memory limits
for service in /sys/fs/cgroup/system.slice/*.service; do
if [[ -f "$service/memory.max" ]]; then
service_name="$(basename "$service")"
get_service_memory "$service_name"
fi
done
echo ""
echo "Real-time monitoring: sudo systemctl status memory-monitor.timer"
echo "View pressure logs: sudo tail -f /var/log/memory-pressure.log"
echo "OOM monitoring logs: sudo tail -f /var/log/oom-monitor.log"
sudo chmod +x /usr/local/bin/memory-dashboard.sh
Configure container memory limits for production services
Apply memory limits to actual production services. This example shows configuration for a web application service.
[Unit]
Description=Web Application
After=network.target
[Service]
Type=notify
User=webapp
Group=webapp
ExecStart=/usr/local/bin/webapp-server
Restart=always
RestartSec=10
Memory management
MemoryAccounting=yes
MemoryMax=512M
MemoryHigh=400M
MemorySwapMax=128M
When memory limits are hit
OOMPolicy=stop
OOMScoreAdjust=100
CPU limits (optional)
CPUAccounting=yes
CPUQuota=80%
Task limits
TasksAccounting=yes
TasksMax=256
[Install]
WantedBy=multi-user.target
Verify your setup
Test that memory limits and monitoring are working correctly.
# Check timer status
sudo systemctl status memory-monitor.timer
View current memory usage
sudo /usr/local/bin/memory-dashboard.sh
Check monitoring logs
sudo tail -f /var/log/memory-pressure.log
Test memory pressure (in another terminal)
sudo systemctl restart memory-test
Check cgroups v2 memory stats
sudo systemd-cgtop --memory
You should see memory usage statistics, pressure information, and alerts when services approach their limits.
Understanding cgroups v2 memory hierarchy
MemoryHigh triggers reclaim before hitting hard limits, MemoryMax is the absolute ceiling, and MemorySwapMax controls swap usage separately.| Setting | Purpose | Behavior when exceeded |
|---|---|---|
MemoryHigh | Soft limit for memory reclaim | Triggers aggressive memory reclaim |
MemoryMax | Hard memory limit | OOM kill or process termination |
MemorySwapMax | Maximum swap usage | Prevents swap thrashing |
MemoryLow | Memory protection threshold | Protects memory from reclaim |
Implement advanced pressure notifications
Create pressure stall information (PSI) monitoring
Set up monitoring using the Linux PSI interface for more granular memory pressure detection.
#!/bin/bash
PSI Memory Monitor with thresholds
PSI_FILE="/proc/pressure/memory"
THRESHOLD_SOME=50.0
THRESHOLD_FULL=10.0
LOG_FILE="/var/log/psi-memory.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
check_memory_pressure() {
if [[ ! -f "$PSI_FILE" ]]; then
log_message "ERROR: PSI not available on this system"
return 1
fi
# Parse PSI values
local some_avg10=$(grep "some" "$PSI_FILE" | awk '{print $2}' | cut -d'=' -f2)
local full_avg10=$(grep "full" "$PSI_FILE" | awk '{print $2}' | cut -d'=' -f2)
log_message "Memory pressure - some avg10: ${some_avg10}%, full avg10: ${full_avg10}%"
# Check thresholds
if (( $(echo "$some_avg10 > $THRESHOLD_SOME" | bc -l) )); then
log_message "WARNING: Memory pressure 'some' exceeds threshold: ${some_avg10}% > ${THRESHOLD_SOME}%"
systemctl --user --global status || systemctl status | head -20 >> "$LOG_FILE"
fi
if (( $(echo "$full_avg10 > $THRESHOLD_FULL" | bc -l) )); then
log_message "CRITICAL: Memory pressure 'full' exceeds threshold: ${full_avg10}% > ${THRESHOLD_FULL}%"
# Emergency actions could go here
fi
}
check_memory_pressure
sudo chmod +x /usr/local/bin/psi-monitor.sh
Troubleshoot OOM kills and memory leaks
Set up comprehensive OOM analysis
Create tools to analyze and prevent out-of-memory conditions.
#!/bin/bash
OOM Analysis and Prevention Tool
REPORT_FILE="/var/log/oom-analysis.log"
generate_oom_report() {
echo "=== OOM Analysis Report $(date) ===" >> "$REPORT_FILE"
# Recent OOM kills from kernel
echo "\n--- Recent OOM Kills ---" >> "$REPORT_FILE"
journalctl --since="24 hours ago" --grep="killed process" >> "$REPORT_FILE"
# Memory usage by cgroup
echo "\n--- Memory Usage by Service ---" >> "$REPORT_FILE"
for service in /sys/fs/cgroup/system.slice/*.service; do
if [[ -f "$service/memory.current" ]] && [[ -f "$service/memory.max" ]]; then
local name=$(basename "$service")
local current=$(cat "$service/memory.current")
local max=$(cat "$service/memory.max")
if [[ "$max" != "max" ]] && [[ "$current" -gt 0 ]]; then
local percent=$((current * 100 / max))
printf "%-30s %10s / %10s (%3d%%)\n" "$name" "$(numfmt --to=iec "$current")" "$(numfmt --to=iec "$max")" "$percent" >> "$REPORT_FILE"
fi
fi
done
# System memory info
echo "\n--- System Memory ---" >> "$REPORT_FILE"
free -h >> "$REPORT_FILE"
# Top memory consumers
echo "\n--- Top Memory Consumers ---" >> "$REPORT_FILE"
ps aux --sort=-%mem | head -10 >> "$REPORT_FILE"
echo "\n" >> "$REPORT_FILE"
}
generate_oom_report
echo "OOM analysis complete. Report saved to $REPORT_FILE"
sudo chmod +x /usr/local/bin/oom-analysis.sh
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Service keeps getting OOM killed | Memory limit too low for workload | Increase MemoryMax or optimize application memory usage |
| Memory pressure alerts not triggering | Monitoring script permissions or timer not active | sudo systemctl status memory-monitor.timer and check logs |
| cgroups v2 not available | System using cgroups v1 | Add systemd.unified_cgroup_hierarchy=1 to kernel boot parameters |
| PSI interface missing | Kernel compiled without PSI support | Enable PSI in kernel config or use alternative monitoring |
| High memory usage but no reclaim | MemoryHigh set too high | Lower MemoryHigh to trigger earlier reclaim |
Next steps
- Configure Linux memory cgroups v2 with systemd for advanced process isolation and resource control
- Implement Linux resource quotas with systemd and automated enforcement
- Configure Linux process monitoring with top, htop, and btop for system performance analysis
- Set up Prometheus and Grafana monitoring stack with Docker compose
- Configure systemd container resource limits for CPU and memory
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Default values
SERVICE_NAME="${1:-memory-test}"
MEMORY_LIMIT="${2:-128M}"
MEMORY_HIGH="${3:-100M}"
THRESHOLD="${4:-80}"
print_usage() {
echo "Usage: $0 [service_name] [memory_limit] [memory_high] [alert_threshold]"
echo " service_name: Name for the test service (default: memory-test)"
echo " memory_limit: Maximum memory limit (default: 128M)"
echo " memory_high: Memory high watermark (default: 100M)"
echo " alert_threshold: Alert threshold percentage (default: 80)"
echo ""
echo "Example: $0 myapp 256M 200M 85"
}
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
cleanup_on_error() {
error "Installation failed. Cleaning up..."
systemctl stop "${SERVICE_NAME}.service" 2>/dev/null || true
systemctl disable "${SERVICE_NAME}.service" 2>/dev/null || true
systemctl stop "memory-pressure-monitor.timer" 2>/dev/null || true
systemctl disable "memory-pressure-monitor.timer" 2>/dev/null || true
rm -f "/etc/systemd/system/${SERVICE_NAME}.service"
rm -f "/etc/systemd/system/memory-pressure-monitor.service"
rm -f "/etc/systemd/system/memory-pressure-monitor.timer"
rm -f "/usr/local/bin/memory-pressure-monitor.sh"
systemctl daemon-reload
}
trap cleanup_on_error ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
exit 1
fi
# Validate arguments
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
print_usage
exit 0
fi
log "[1/8] Detecting operating system..."
# Auto-detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
MAIL_PKG="mailutils"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
MAIL_PKG="mailx"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
MAIL_PKG="mailx"
;;
*)
error "Unsupported distribution: $ID"
exit 1
;;
esac
log "Detected: $PRETTY_NAME"
else
error "Cannot detect operating system"
exit 1
fi
log "[2/8] Verifying cgroups v2..."
# Check cgroups v2
if ! mount | grep -q "cgroup2"; then
error "cgroups v2 not detected. Please enable cgroups v2 in kernel boot parameters"
exit 1
fi
if [[ $(stat -fc %T /sys/fs/cgroup 2>/dev/null) != "cgroup2fs" ]]; then
error "cgroups v2 filesystem not mounted correctly"
exit 1
fi
log "cgroups v2 is properly configured"
log "[3/8] Installing required packages..."
$PKG_UPDATE
$PKG_INSTALL systemd stress-ng $MAIL_PKG
log "[4/8] Creating memory test service..."
# Create the test service
cat > "/etc/systemd/system/${SERVICE_NAME}.service" << EOF
[Unit]
Description=Memory Test Service
After=network.target
[Service]
Type=simple
User=nobody
Group=nobody
ExecStart=/usr/bin/stress-ng --vm 1 --vm-bytes 100M --timeout 0
Restart=always
RestartSec=5
# Memory limits
MemoryMax=$MEMORY_LIMIT
MemorySwapMax=0
MemoryHigh=$MEMORY_HIGH
# Enable memory accounting
MemoryAccounting=yes
TasksAccounting=yes
# OOM policy
OOMPolicy=stop
[Install]
WantedBy=multi-user.target
EOF
chmod 644 "/etc/systemd/system/${SERVICE_NAME}.service"
log "[5/8] Creating memory pressure monitoring script..."
# Create monitoring script
cat > /usr/local/bin/memory-pressure-monitor.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
# Memory pressure monitoring script
SERVICE_NAME="${SERVICE_NAME:-memory-test}"
THRESHOLD="${THRESHOLD:-80}"
LOG_FILE="/var/log/memory-pressure.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
check_memory_usage() {
local cgroup_path="/sys/fs/cgroup/system.slice/${SERVICE_NAME}.service"
if [[ ! -d "$cgroup_path" ]]; then
log_message "ERROR: Service $SERVICE_NAME not found or not running"
return 1
fi
# Read current memory usage
local current_memory=$(cat "$cgroup_path/memory.current" 2>/dev/null || echo "0")
local memory_max=$(cat "$cgroup_path/memory.max" 2>/dev/null || echo "0")
if [[ "$memory_max" == "max" ]] || [[ "$memory_max" -eq 0 ]]; then
log_message "WARNING: No memory limit set for $SERVICE_NAME"
return 1
fi
# Calculate usage percentage
local usage_percent=$((current_memory * 100 / memory_max))
log_message "Memory usage: ${usage_percent}% (${current_memory} / ${memory_max} bytes)"
# Check pressure stall information
if [[ -f "$cgroup_path/memory.pressure" ]]; then
local pressure_some=$(grep "some" "$cgroup_path/memory.pressure" | cut -d' ' -f2 | cut -d'=' -f2 2>/dev/null || echo "0.00")
local pressure_full=$(grep "full" "$cgroup_path/memory.pressure" | cut -d' ' -f4 | cut -d'=' -f2 2>/dev/null || echo "0.00")
log_message "Memory pressure - some: ${pressure_some}, full: ${pressure_full}"
fi
# Alert if usage exceeds threshold
if [[ "$usage_percent" -gt "$THRESHOLD" ]]; then
log_message "ALERT: Memory usage ${usage_percent}% exceeds threshold ${THRESHOLD}%"
send_alert "$SERVICE_NAME" "$usage_percent" "$current_memory" "$memory_max"
fi
}
send_alert() {
local service="$1"
local percent="$2"
local current="$3"
local max="$4"
local message="Memory alert for service: $service
Usage: $percent% ($current / $max bytes)
Time: $(date)"
# Log to syslog
logger -p user.warning "Memory pressure alert: $service at $percent%"
}
# Main execution
check_memory_usage
EOF
# Substitute variables in the script
sed -i "s/\${SERVICE_NAME:-memory-test}/${SERVICE_NAME}/g" /usr/local/bin/memory-pressure-monitor.sh
sed -i "s/\${THRESHOLD:-80}/${THRESHOLD}/g" /usr/local/bin/memory-pressure-monitor.sh
chmod 755 /usr/local/bin/memory-pressure-monitor.sh
log "[6/8] Creating systemd service and timer for monitoring..."
# Create monitoring service
cat > /etc/systemd/system/memory-pressure-monitor.service << EOF
[Unit]
Description=Memory Pressure Monitor
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/memory-pressure-monitor.sh
User=root
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# Create monitoring timer
cat > /etc/systemd/system/memory-pressure-monitor.timer << EOF
[Unit]
Description=Run Memory Pressure Monitor every 30 seconds
Requires=memory-pressure-monitor.service
[Timer]
OnCalendar=*:*:0,30
Persistent=true
[Install]
WantedBy=timers.target
EOF
chmod 644 /etc/systemd/system/memory-pressure-monitor.service
chmod 644 /etc/systemd/system/memory-pressure-monitor.timer
# Create log file with proper permissions
touch /var/log/memory-pressure.log
chmod 644 /var/log/memory-pressure.log
log "[7/8] Enabling and starting services..."
# Reload systemd and enable services
systemctl daemon-reload
systemctl enable "${SERVICE_NAME}.service"
systemctl enable memory-pressure-monitor.timer
systemctl start "${SERVICE_NAME}.service"
systemctl start memory-pressure-monitor.timer
log "[8/8] Verifying installation..."
# Verification checks
sleep 5
if systemctl is-active --quiet "${SERVICE_NAME}.service"; then
log "✓ Memory test service is running"
else
error "✗ Memory test service failed to start"
exit 1
fi
if systemctl is-active --quiet memory-pressure-monitor.timer; then
log "✓ Memory monitoring timer is active"
else
error "✗ Memory monitoring timer failed to start"
exit 1
fi
# Check if memory limits are applied
CGROUP_PATH="/sys/fs/cgroup/system.slice/${SERVICE_NAME}.service"
if [[ -f "$CGROUP_PATH/memory.max" ]]; then
ACTUAL_LIMIT=$(cat "$CGROUP_PATH/memory.max")
log "✓ Memory limit applied: $ACTUAL_LIMIT bytes"
else
warn "Memory limits may not be applied correctly"
fi
# Show useful commands
log ""
log "Installation completed successfully!"
log ""
log "Useful commands:"
log " Monitor service: systemctl status ${SERVICE_NAME}.service"
log " View memory usage: systemd-cgtop"
log " Check logs: tail -f /var/log/memory-pressure.log"
log " Stop test service: systemctl stop ${SERVICE_NAME}.service"
log " Disable monitoring: systemctl stop memory-pressure-monitor.timer"
Review the script before running. Execute with: bash install.sh