Back to Rustfs

Container Resource Detection

docs/operations/container-resource-detection.md

1.0.0-rc.4-preview.15.1 KB
Original Source

Container Resource Detection

RustFS automatically detects container resource limits (CPU and memory) from cgroup v1/v2. This ensures correct resource allocation and accurate metrics in containerized environments (Kubernetes, Docker, etc.).

Problem

When RustFS runs in a container, the underlying system libraries report the host's total CPU cores and memory, not the container's limits. This leads to:

  1. Over-provisioned Tokio threads: Too many worker and blocking threads
  2. Incorrect memory metrics: rustfs_memory_usage_percent shows host-based percentage
  3. Memory budget errors: Object data cache sized to host RAM instead of container limit
  4. OOMKills: Container exceeds its memory limit and gets killed

Solution

RustFS now detects cgroup limits directly from the filesystem:

  • CPU: /sys/fs/cgroup/cpu.max (v2) or /sys/fs/cgroup/cpu/cpu.cfs_quota_us (v1)
  • Memory: /sys/fs/cgroup/memory.max (v2) or /sys/fs/cgroup/memory/memory.limit_in_bytes (v1)

The effective resource limits are the minimum of host and cgroup values.

Detection Logic

CPU Detection

  1. Read cgroup v2 /sys/fs/cgroup/cpu.max
    • Format: "$QUOTA $PERIOD" or "max" (unlimited)
    • Calculate: cores = ceil(quota / period)
  2. Fallback to cgroup v1 /sys/fs/cgroup/cpu/cpu.cfs_quota_us
    • Calculate: cores = ceil(quota / period)
  3. Fallback to host CPU count from sysinfo

Memory Detection

  1. Read cgroup v2 /sys/fs/cgroup/memory.max
    • Value in bytes or "max" (unlimited)
  2. Fallback to cgroup v1 /sys/fs/cgroup/memory/memory.limit_in_bytes
    • Very large values (≥2^62) indicate unlimited
  3. Fallback to host memory from sysinfo

Environment Variables

Disable Cgroup Detection

bash
RUSTFS_DISABLE_CGROUP_DETECTION=1

Disables cgroup detection entirely. Useful for testing or when cgroup filesystem is not accessible.

Override CPU Cores

bash
RUSTFS_OVERRIDE_CPU_CORES=4

Overrides detected CPU cores. Takes precedence over cgroup detection.

Override Memory Limit

bash
RUSTFS_OVERRIDE_MEMORY_BYTES=2147483648

Overrides detected memory limit in bytes. Takes precedence over cgroup detection.

Metrics

New Metrics

MetricDescription
rustfs_memory_effective_total_bytesEffective memory total (host or cgroup)
rustfs_cgroup_detectedWhether cgroup limits were detected (1=yes, 0=no)
rustfs_cgroup_cpu_cores_limitDetected CPU cores limit
rustfs_cgroup_memory_limit_bytesDetected memory limit

Updated Metrics

MetricChange
rustfs_memory_total_bytesNow uses effective memory (cgroup-aware)
rustfs_memory_usage_percentNow calculated against effective memory

Startup Logging

RustFS logs detected container resources at startup:

INFO container resources (detected from cgroup) cpu_cores=2 memory_bytes=1073741824 memory_mib=1024

or

INFO container resources (overridden by environment variables) cpu_cores=4 memory_bytes=2147483648 memory_mib=2048

Examples

Kubernetes with Resource Limits

yaml
resources:
  limits:
    cpu: "2"
    memory: "1Gi"
  requests:
    cpu: "500m"
    memory: "512Mi"

RustFS will detect:

  • CPU cores: 2
  • Memory: 1 GiB (1073741824 bytes)

Docker with CPU and Memory Limits

bash
docker run --cpus=2 --memory=1g rustfs/rustfs:latest

RustFS will detect:

  • CPU cores: 2
  • Memory: 1 GiB

Manual Override

bash
export RUSTFS_OVERRIDE_CPU_CORES=4
export RUSTFS_OVERRIDE_MEMORY_BYTES=2147483648

RustFS will use:

  • CPU cores: 4
  • Memory: 2 GiB

Troubleshooting

Cgroup Detection Not Working

  1. Check if cgroup filesystem is mounted:

    bash
    ls -la /sys/fs/cgroup/
    
  2. Check cgroup version:

    bash
    stat -fc %T /sys/fs/cgroup/
    
    • cgroup2fs = cgroup v2
    • tmpfs = cgroup v1
  3. Check if limits are set:

    bash
    # cgroup v2
    cat /sys/fs/cgroup/cpu.max
    cat /sys/fs/cgroup/memory.max
    
    # cgroup v1
    cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
    cat /sys/fs/cgroup/memory/memory.limit_in_bytes
    

Metrics Show Host Values

If rustfs_memory_effective_total_bytes shows host memory instead of cgroup limit:

  1. Verify cgroup detection is not disabled:

    bash
    echo $RUSTFS_DISABLE_CGROUP_DETECTION
    
  2. Check startup logs for cgroup detection:

    bash
    grep "container resources" /logs/rustfs.log
    
  3. Use environment variable override as workaround:

    bash
    export RUSTFS_OVERRIDE_MEMORY_BYTES=1073741824
    

Implementation Details

Files Modified

  • rustfs/src/cgroup_resources.rs - Core cgroup detection logic
  • rustfs/src/container_config.rs - Container configuration with overrides
  • rustfs/src/memory_observability.rs - Updated memory metrics
  • rustfs/src/server/runtime.rs - Updated Tokio runtime configuration
  • rustfs/src/startup_entrypoint.rs - Startup logging

Performance Impact

  • Startup: One-time detection adds ~1ms overhead
  • Runtime: Cached values, no repeated filesystem reads
  • Memory: Negligible (<1KB for cached values)

Thread Safety

All detection functions are thread-safe and use OnceLock for caching.