Configure cgroups v2 memory subsystem to isolate container workloads with precise memory limits, monitoring, and automated enforcement for production environments.
Prerequisites
- Root or sudo access
- Linux kernel 4.5+ with cgroups v2 support
- systemd-based distribution
- Basic understanding of Linux process management
What this solves
Memory cgroups (control groups) provide essential resource isolation for containers by limiting and monitoring memory usage across different workloads. This prevents memory-intensive containers from consuming system resources and affecting other processes. You'll implement cgroups v2 memory controls to establish container boundaries, set memory limits, and monitor resource consumption in real-time.
Step-by-step configuration
Verify cgroups v2 support
Check if your system supports cgroups v2 and which version is currently active. Most modern distributions enable cgroups v2 by default.
mount | grep cgroup
cat /sys/fs/cgroup/cgroup.controllers
cat /proc/cgroups
Enable cgroups v2 memory controller
Enable the memory controller in the cgroup hierarchy to allow memory limit enforcement and monitoring.
echo '+memory' | sudo tee /sys/fs/cgroup/cgroup.subtree_control
cat /sys/fs/cgroup/cgroup.subtree_control
Install cgroup management tools
Install utilities for managing cgroups and monitoring resource usage across different distributions.
sudo apt update
sudo apt install -y cgroup-tools libcgroup-dev systemd-cgroup-utils
Create container workload cgroups
Create dedicated cgroup hierarchies for different container workloads with appropriate directory structure and permissions.
sudo mkdir -p /sys/fs/cgroup/containers/web-tier
sudo mkdir -p /sys/fs/cgroup/containers/database-tier
sudo mkdir -p /sys/fs/cgroup/containers/cache-tier
sudo chown -R root:root /sys/fs/cgroup/containers/
Configure memory limits for web tier
Set memory limits and swap controls for web application containers with 512MB memory limit and monitoring enabled.
echo '+memory' | sudo tee /sys/fs/cgroup/containers/cgroup.subtree_control
echo '536870912' | sudo tee /sys/fs/cgroup/containers/web-tier/memory.max
echo '268435456' | sudo tee /sys/fs/cgroup/containers/web-tier/memory.high
echo '0' | sudo tee /sys/fs/cgroup/containers/web-tier/memory.swap.max
Configure memory limits for database tier
Set higher memory limits for database containers with 2GB maximum and appropriate swap configuration.
echo '2147483648' | sudo tee /sys/fs/cgroup/containers/database-tier/memory.max
echo '1073741824' | sudo tee /sys/fs/cgroup/containers/database-tier/memory.high
echo '536870912' | sudo tee /sys/fs/cgroup/containers/database-tier/memory.swap.max
Configure memory limits for cache tier
Set memory limits for cache containers with 1GB maximum and disabled swap for predictable performance.
echo '1073741824' | sudo tee /sys/fs/cgroup/containers/cache-tier/memory.max
echo '805306368' | sudo tee /sys/fs/cgroup/containers/cache-tier/memory.high
echo '0' | sudo tee /sys/fs/cgroup/containers/cache-tier/memory.swap.max
Create systemd service for cgroup management
Create a systemd service to automatically configure cgroups on system startup and maintain memory limits.
[Unit]
Description=Container Memory Cgroups Setup
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-container-cgroups.sh
User=root
[Install]
WantedBy=multi-user.target
Create cgroup setup script
Create the automation script referenced by the systemd service for consistent cgroup configuration.
#!/bin/bash
set -euo pipefail
Enable memory controller
echo '+memory' > /sys/fs/cgroup/cgroup.subtree_control
echo '+memory' > /sys/fs/cgroup/containers/cgroup.subtree_control
Web tier - 512MB max, 256MB high
echo '536870912' > /sys/fs/cgroup/containers/web-tier/memory.max
echo '268435456' > /sys/fs/cgroup/containers/web-tier/memory.high
echo '0' > /sys/fs/cgroup/containers/web-tier/memory.swap.max
Database tier - 2GB max, 1GB high, 512MB swap
echo '2147483648' > /sys/fs/cgroup/containers/database-tier/memory.max
echo '1073741824' > /sys/fs/cgroup/containers/database-tier/memory.high
echo '536870912' > /sys/fs/cgroup/containers/database-tier/memory.swap.max
Cache tier - 1GB max, 768MB high, no swap
echo '1073741824' > /sys/fs/cgroup/containers/cache-tier/memory.max
echo '805306368' > /sys/fs/cgroup/containers/cache-tier/memory.high
echo '0' > /sys/fs/cgroup/containers/cache-tier/memory.swap.max
echo "Container cgroups configured successfully"
sudo chmod +x /usr/local/bin/setup-container-cgroups.sh
Enable and start the cgroup service
Enable the systemd service to automatically configure cgroups on system boot and start it immediately.
sudo systemctl daemon-reload
sudo systemctl enable container-cgroups.service
sudo systemctl start container-cgroups.service
sudo systemctl status container-cgroups.service
Create process assignment script
Create a utility script to assign processes to specific cgroups for container workload isolation.
#!/bin/bash
set -euo pipefail
if [ "$#" -ne 2 ]; then
echo "Usage: $0 "
echo "Available cgroups: web-tier, database-tier, cache-tier"
exit 1
fi
CGROUP="$1"
PID="$2"
CGROUP_PATH="/sys/fs/cgroup/containers/${CGROUP}"
if [ ! -d "$CGROUP_PATH" ]; then
echo "Error: Cgroup $CGROUP does not exist"
exit 1
fi
if ! kill -0 "$PID" 2>/dev/null; then
echo "Error: Process $PID does not exist"
exit 1
fi
echo "$PID" > "${CGROUP_PATH}/cgroup.procs"
echo "Process $PID assigned to cgroup $CGROUP"
sudo chmod +x /usr/local/bin/assign-to-cgroup.sh
Configure memory pressure notifications
Set up memory pressure monitoring to receive notifications when memory usage approaches limits.
#!/bin/bash
set -euo pipefail
CGROUPS=("web-tier" "database-tier" "cache-tier")
for cgroup in "${CGROUPS[@]}"; do
CGROUP_PATH="/sys/fs/cgroup/containers/${cgroup}"
if [ -f "${CGROUP_PATH}/memory.current" ]; then
CURRENT=$(cat "${CGROUP_PATH}/memory.current")
MAX=$(cat "${CGROUP_PATH}/memory.max")
HIGH=$(cat "${CGROUP_PATH}/memory.high")
CURRENT_MB=$((CURRENT / 1024 / 1024))
MAX_MB=$((MAX / 1024 / 1024))
HIGH_MB=$((HIGH / 1024 / 1024))
USAGE_PERCENT=$((CURRENT * 100 / MAX))
echo "${cgroup}: ${CURRENT_MB}MB / ${MAX_MB}MB (${USAGE_PERCENT}% used, high threshold: ${HIGH_MB}MB)"
if [ "$CURRENT" -gt "$HIGH" ]; then
echo "WARNING: ${cgroup} memory usage exceeds high threshold!"
logger -t cgroup-monitor "WARNING: ${cgroup} memory usage ${CURRENT_MB}MB exceeds high threshold ${HIGH_MB}MB"
fi
fi
done
sudo chmod +x /usr/local/bin/monitor-memory-pressure.sh
Set up automated monitoring with cron
Configure cron to run memory pressure monitoring every minute for proactive resource management.
echo " * /usr/local/bin/monitor-memory-pressure.sh >> /var/log/cgroup-monitor.log 2>&1" | sudo crontab -
Verify your setup
Test the cgroup configuration and verify memory limits are properly enforced.
# Check cgroup hierarchy
find /sys/fs/cgroup/containers -name "memory.*" | head -10
Verify memory limits
cat /sys/fs/cgroup/containers/web-tier/memory.max
cat /sys/fs/cgroup/containers/database-tier/memory.max
cat /sys/fs/cgroup/containers/cache-tier/memory.max
Check current memory usage
cat /sys/fs/cgroup/containers/web-tier/memory.current
cat /sys/fs/cgroup/containers/database-tier/memory.current
cat /sys/fs/cgroup/containers/cache-tier/memory.current
Test process assignment
sudo /usr/local/bin/assign-to-cgroup.sh web-tier $$
cat /sys/fs/cgroup/containers/web-tier/cgroup.procs
Run memory pressure monitoring
sudo /usr/local/bin/monitor-memory-pressure.sh
Configure container runtime integration
Integrate with systemd-run
Use systemd-run to launch processes with automatic cgroup assignment and resource limits.
# Launch process in web-tier cgroup with 256MB limit
sudo systemd-run --slice=containers/web-tier --property=MemoryMax=256M --property=MemoryHigh=128M sleep 300
Launch process in database-tier cgroup with 1GB limit
sudo systemd-run --slice=containers/database-tier --property=MemoryMax=1G --property=MemoryHigh=512M sleep 300
Check running services
systemctl list-units --type=service --state=running | grep containers
Create container wrapper script
Create a wrapper script that automatically assigns containers to appropriate cgroups based on their role.
#!/bin/bash
set -euo pipefail
if [ "$#" -lt 2 ]; then
echo "Usage: $0 "
echo "Tiers: web-tier, database-tier, cache-tier"
exit 1
fi
TIER="$1"
shift
COMMAND="$@"
case "$TIER" in
web-tier)
MEMORY_MAX="256M"
MEMORY_HIGH="128M"
;;
database-tier)
MEMORY_MAX="1G"
MEMORY_HIGH="512M"
;;
cache-tier)
MEMORY_MAX="512M"
MEMORY_HIGH="256M"
;;
*)
echo "Error: Unknown tier $TIER"
exit 1
;;
esac
echo "Starting container in $TIER with limits: max=$MEMORY_MAX, high=$MEMORY_HIGH"
systemd-run --slice="containers/$TIER" \
--property="MemoryMax=$MEMORY_MAX" \
--property="MemoryHigh=$MEMORY_HIGH" \
--property="MemorySwapMax=0" \
$COMMAND
sudo chmod +x /usr/local/bin/run-container.sh
Monitor and troubleshoot memory constraints
Create detailed monitoring script
Implement comprehensive monitoring that tracks memory statistics, pressure events, and OOM kills.
#!/bin/bash
set -euo pipefail
CGROUPS=("web-tier" "database-tier" "cache-tier")
echo "=== Container Memory Cgroup Status ==="
echo "Timestamp: $(date)"
echo
for cgroup in "${CGROUPS[@]}"; do
CGROUP_PATH="/sys/fs/cgroup/containers/${cgroup}"
if [ -d "$CGROUP_PATH" ]; then
echo "=== $cgroup ==="
# Memory usage
CURRENT=$(cat "${CGROUP_PATH}/memory.current" 2>/dev/null || echo "0")
MAX=$(cat "${CGROUP_PATH}/memory.max" 2>/dev/null || echo "0")
HIGH=$(cat "${CGROUP_PATH}/memory.high" 2>/dev/null || echo "0")
echo "Current: $((CURRENT / 1024 / 1024)) MB"
echo "High threshold: $((HIGH / 1024 / 1024)) MB"
echo "Maximum: $((MAX / 1024 / 1024)) MB"
# Memory events
if [ -f "${CGROUP_PATH}/memory.events" ]; then
echo "Memory events:"
cat "${CGROUP_PATH}/memory.events" | sed 's/^/ /'
fi
# Process count
PROC_COUNT=$(cat "${CGROUP_PATH}/cgroup.procs" 2>/dev/null | wc -l)
echo "Processes: $PROC_COUNT"
# Memory pressure
if [ -f "${CGROUP_PATH}/memory.pressure" ]; then
echo "Memory pressure:"
cat "${CGROUP_PATH}/memory.pressure" | sed 's/^/ /'
fi
echo
fi
done
sudo chmod +x /usr/local/bin/detailed-memory-monitor.sh
Configure memory pressure alerts
Set up systemd service to monitor memory pressure and send alerts when thresholds are exceeded.
[Unit]
Description=Memory Pressure Alert Monitor
After=container-cgroups.service
[Service]
Type=simple
ExecStart=/usr/local/bin/memory-pressure-daemon.sh
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
Create memory pressure daemon
Implement a daemon that continuously monitors memory pressure and logs critical events.
#!/bin/bash
set -euo pipefail
LOG_FILE="/var/log/memory-pressure.log"
CGROUPS=("web-tier" "database-tier" "cache-tier")
log_event() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG_FILE"
logger -t memory-pressure "$1"
}
log_event "Memory pressure monitoring daemon started"
while true; do
for cgroup in "${CGROUPS[@]}"; do
CGROUP_PATH="/sys/fs/cgroup/containers/${cgroup}"
if [ -f "${CGROUP_PATH}/memory.current" ]; then
CURRENT=$(cat "${CGROUP_PATH}/memory.current")
HIGH=$(cat "${CGROUP_PATH}/memory.high")
MAX=$(cat "${CGROUP_PATH}/memory.max")
# Check if we're above high threshold
if [ "$CURRENT" -gt "$HIGH" ]; then
CURRENT_MB=$((CURRENT / 1024 / 1024))
HIGH_MB=$((HIGH / 1024 / 1024))
log_event "ALERT: ${cgroup} memory usage ${CURRENT_MB}MB exceeds high threshold ${HIGH_MB}MB"
fi
# Check memory events for OOM kills
if [ -f "${CGROUP_PATH}/memory.events" ]; then
OOM_KILL=$(grep "oom_kill" "${CGROUP_PATH}/memory.events" | cut -d' ' -f2)
if [ "$OOM_KILL" -gt 0 ]; then
log_event "CRITICAL: ${cgroup} has experienced ${OOM_KILL} OOM kills"
fi
fi
fi
done
sleep 30
done
sudo chmod +x /usr/local/bin/memory-pressure-daemon.sh
sudo systemctl enable memory-pressure-alert.service
sudo systemctl start memory-pressure-alert.service
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Cannot write to memory.max | cgroups v1 active or insufficient permissions | Verify cgroups v2: mount | grep cgroup2 and run as root |
| Memory controller not available | Controller not enabled in hierarchy | echo '+memory' | sudo tee /sys/fs/cgroup/cgroup.subtree_control |
| Process assignment fails | Process doesn't exist or cgroup path wrong | Verify PID: kill -0 PID and check cgroup path exists |
| Memory limits ignored | Process not in correct cgroup | Check: cat /sys/fs/cgroup/containers/tier/cgroup.procs |
| OOM kills frequent | Memory limits too restrictive | Increase limits or optimize application memory usage |
| systemd slice errors | Slice hierarchy conflict | Use consistent naming: --slice=containers/tier |
Next steps
- Configure Linux user session limits with systemd and pam_limits for resource management
- Monitor container performance with Prometheus and cAdvisor for comprehensive metrics collection
- Implement Kubernetes resource quotas and limits for namespace isolation and workload management
- Configure Docker resource limits with cgroups v2
- Set up container orchestration with systemd and cgroups
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' # No Color
# Global variables
SCRIPT_NAME=$(basename "$0")
CGROUP_BASE="/sys/fs/cgroup"
CONTAINERS_CGROUP="$CGROUP_BASE/containers"
SETUP_SCRIPT="/usr/local/bin/setup-container-cgroups.sh"
SERVICE_FILE="/etc/systemd/system/container-cgroups.service"
# Memory limits in bytes
WEB_MAX="536870912" # 512MB
WEB_HIGH="268435456" # 256MB
DB_MAX="2147483648" # 2GB
DB_HIGH="1073741824" # 1GB
DB_SWAP="536870912" # 512MB
CACHE_MAX="1073741824" # 1GB
CACHE_HIGH="805306368" # 768MB
# Cleanup function for rollback
cleanup() {
echo -e "${RED}[ERROR]${NC} Installation failed. Cleaning up..."
systemctl disable container-cgroups.service 2>/dev/null || true
rm -f "$SERVICE_FILE" 2>/dev/null || true
rm -f "$SETUP_SCRIPT" 2>/dev/null || true
rm -rf "$CONTAINERS_CGROUP" 2>/dev/null || true
exit 1
}
trap cleanup ERR
usage() {
echo "Usage: $SCRIPT_NAME [OPTIONS]"
echo "Configure Linux memory cgroups for container workload isolation"
echo ""
echo "Options:"
echo " --web-memory MB Set web tier memory limit (default: 512MB)"
echo " --db-memory MB Set database tier memory limit (default: 2048MB)"
echo " --cache-memory MB Set cache tier memory limit (default: 1024MB)"
echo " -h, --help Show this help message"
exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--web-memory)
WEB_MAX=$((${2} * 1024 * 1024))
WEB_HIGH=$((WEB_MAX / 2))
shift 2
;;
--db-memory)
DB_MAX=$((${2} * 1024 * 1024))
DB_HIGH=$((DB_MAX / 2))
shift 2
;;
--cache-memory)
CACHE_MAX=$((${2} * 1024 * 1024))
CACHE_HIGH=$((CACHE_MAX * 3 / 4))
shift 2
;;
-h|--help)
usage
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}[ERROR]${NC} This script must be run as root"
exit 1
fi
# Detect distribution
echo -e "${YELLOW}[1/9]${NC} Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
CGROUP_PACKAGES="cgroup-tools libcgroup-dev systemd"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
CGROUP_PACKAGES="libcgroup-tools systemd"
;;
fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
CGROUP_PACKAGES="libcgroup-tools systemd"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum check-update || true"
PKG_INSTALL="yum install -y"
CGROUP_PACKAGES="libcgroup-tools systemd"
;;
*)
echo -e "${RED}[ERROR]${NC} Unsupported distribution: $ID"
exit 1
;;
esac
echo -e "${GREEN}Detected: $PRETTY_NAME${NC}"
else
echo -e "${RED}[ERROR]${NC} Cannot detect distribution"
exit 1
fi
# Verify cgroups v2 support
echo -e "${YELLOW}[2/9]${NC} Verifying cgroups v2 support..."
if ! grep -q cgroup2 /proc/filesystems; then
echo -e "${RED}[ERROR]${NC} cgroups v2 not supported by kernel"
exit 1
fi
if ! mount | grep -q "cgroup2"; then
echo -e "${YELLOW}[WARNING]${NC} cgroups v2 not mounted, attempting to mount..."
mount -t cgroup2 none /sys/fs/cgroup || {
echo -e "${RED}[ERROR]${NC} Failed to mount cgroups v2"
exit 1
}
fi
echo -e "${GREEN}cgroups v2 is available${NC}"
# Update package manager
echo -e "${YELLOW}[3/9]${NC} Updating package manager..."
$PKG_UPDATE >/dev/null 2>&1
# Install cgroup management tools
echo -e "${YELLOW}[4/9]${NC} Installing cgroup management tools..."
$PKG_INSTALL $CGROUP_PACKAGES >/dev/null 2>&1
echo -e "${GREEN}Packages installed successfully${NC}"
# Create container cgroup directories
echo -e "${YELLOW}[5/9]${NC} Creating container cgroup directories..."
mkdir -p "$CONTAINERS_CGROUP"/{web-tier,database-tier,cache-tier}
chown -R root:root "$CONTAINERS_CGROUP"
chmod -R 755 "$CONTAINERS_CGROUP"
echo -e "${GREEN}Cgroup directories created${NC}"
# Enable memory controller
echo -e "${YELLOW}[6/9]${NC} Enabling memory controller..."
if [[ -w "$CGROUP_BASE/cgroup.subtree_control" ]]; then
echo '+memory' > "$CGROUP_BASE/cgroup.subtree_control"
echo '+memory' > "$CONTAINERS_CGROUP/cgroup.subtree_control"
echo -e "${GREEN}Memory controller enabled${NC}"
else
echo -e "${RED}[ERROR]${NC} Cannot write to cgroup.subtree_control"
exit 1
fi
# Configure memory limits
echo -e "${YELLOW}[7/9]${NC} Configuring memory limits..."
# Web tier configuration
echo "$WEB_MAX" > "$CONTAINERS_CGROUP/web-tier/memory.max"
echo "$WEB_HIGH" > "$CONTAINERS_CGROUP/web-tier/memory.high"
echo '0' > "$CONTAINERS_CGROUP/web-tier/memory.swap.max"
# Database tier configuration
echo "$DB_MAX" > "$CONTAINERS_CGROUP/database-tier/memory.max"
echo "$DB_HIGH" > "$CONTAINERS_CGROUP/database-tier/memory.high"
echo "$DB_SWAP" > "$CONTAINERS_CGROUP/database-tier/memory.swap.max"
# Cache tier configuration
echo "$CACHE_MAX" > "$CONTAINERS_CGROUP/cache-tier/memory.max"
echo "$CACHE_HIGH" > "$CONTAINERS_CGROUP/cache-tier/memory.high"
echo '0' > "$CONTAINERS_CGROUP/cache-tier/memory.swap.max"
echo -e "${GREEN}Memory limits configured${NC}"
# Create setup script
echo -e "${YELLOW}[8/9]${NC} Creating cgroup setup script..."
cat > "$SETUP_SCRIPT" << 'EOF'
#!/bin/bash
set -euo pipefail
# Container Memory Cgroups Setup Script
CGROUP_BASE="/sys/fs/cgroup"
CONTAINERS_CGROUP="$CGROUP_BASE/containers"
# Create directories if they don't exist
mkdir -p "$CONTAINERS_CGROUP"/{web-tier,database-tier,cache-tier}
# Enable memory controller
echo '+memory' > "$CGROUP_BASE/cgroup.subtree_control" 2>/dev/null || true
echo '+memory' > "$CONTAINERS_CGROUP/cgroup.subtree_control" 2>/dev/null || true
# Web tier - 512MB max, 256MB high, no swap
echo '536870912' > "$CONTAINERS_CGROUP/web-tier/memory.max"
echo '268435456' > "$CONTAINERS_CGROUP/web-tier/memory.high"
echo '0' > "$CONTAINERS_CGROUP/web-tier/memory.swap.max"
# Database tier - 2GB max, 1GB high, 512MB swap
echo '2147483648' > "$CONTAINERS_CGROUP/database-tier/memory.max"
echo '1073741824' > "$CONTAINERS_CGROUP/database-tier/memory.high"
echo '536870912' > "$CONTAINERS_CGROUP/database-tier/memory.swap.max"
# Cache tier - 1GB max, 768MB high, no swap
echo '1073741824' > "$CONTAINERS_CGROUP/cache-tier/memory.max"
echo '805306368' > "$CONTAINERS_CGROUP/cache-tier/memory.high"
echo '0' > "$CONTAINERS_CGROUP/cache-tier/memory.swap.max"
echo "Container cgroups configured successfully"
EOF
chmod 755 "$SETUP_SCRIPT"
chown root:root "$SETUP_SCRIPT"
# Create systemd service
cat > "$SERVICE_FILE" << EOF
[Unit]
Description=Container Memory Cgroups Setup
After=multi-user.target
Before=docker.service containerd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=$SETUP_SCRIPT
User=root
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
chmod 644 "$SERVICE_FILE"
chown root:root "$SERVICE_FILE"
# Enable and start systemd service
echo -e "${YELLOW}[9/9]${NC} Enabling systemd service..."
systemctl daemon-reload
systemctl enable container-cgroups.service
systemctl start container-cgroups.service
echo -e "${GREEN}Systemd service enabled and started${NC}"
# Verification
echo -e "${YELLOW}Verifying configuration...${NC}"
echo -e "${GREEN}✓${NC} Cgroup controllers: $(cat $CGROUP_BASE/cgroup.subtree_control)"
echo -e "${GREEN}✓${NC} Container controllers: $(cat $CONTAINERS_CGROUP/cgroup.subtree_control)"
echo -e "${GREEN}✓${NC} Web tier memory limit: $(cat $CONTAINERS_CGROUP/web-tier/memory.max) bytes"
echo -e "${GREEN}✓${NC} Database tier memory limit: $(cat $CONTAINERS_CGROUP/database-tier/memory.max) bytes"
echo -e "${GREEN}✓${NC} Cache tier memory limit: $(cat $CONTAINERS_CGROUP/cache-tier/memory.max) bytes"
echo -e "${GREEN}✓${NC} Service status: $(systemctl is-active container-cgroups.service)"
echo ""
echo -e "${GREEN}[SUCCESS]${NC} Container memory cgroups configured successfully!"
echo "To assign processes to cgroups, use:"
echo " echo \$PID > $CONTAINERS_CGROUP/{web-tier,database-tier,cache-tier}/cgroup.procs"
echo ""
echo "To monitor memory usage:"
echo " cat $CONTAINERS_CGROUP/*/memory.current"
Review the script before running. Execute with: bash install.sh