Persistent Kernel Parameter Tuning via Privileged Docker Containers: Solutions and Best Practices


2 views

When working with privileged Docker containers, there's a common misconception that kernel parameter changes (via sysctl) will automatically persist on the host system. Here's why this doesn't happen as expected:

# This only affects the container's namespace
docker run --rm --privileged ubuntu:latest sysctl -w net.core.somaxconn=65535

Even with --privileged flag, Docker creates new namespaces for the container (including the network namespace). The changes you make are confined to that namespace unless you take additional steps.

For lasting changes, you need to modify the host's sysctl configuration directly. Here are three effective approaches:

1. Bind-mounting /proc with --privileged

# This will modify the host's parameters
docker run --rm --privileged -v /proc/sys:/proc/sys ubuntu:latest \
    sysctl -w net.core.somaxconn=65535

2. Modifying sysctl.conf through the container

# Create a custom sysctl.conf file
echo "net.core.somaxconn=65535" > /tmp/sysctl.conf

# Apply it to the host
docker run --rm --privileged -v /tmp/sysctl.conf:/etc/sysctl.d/99-custom.conf \
    ubuntu:latest sysctl -p /etc/sysctl.d/99-custom.conf

3. Direct host modification via container

# For temporary changes (lost on reboot)
docker run --rm --privileged -v /proc:/host/proc ubuntu:latest \
    sh -c "echo 65535 > /host/proc/sys/net/core/somaxconn"

# For permanent changes
docker run --rm --privileged -v /etc:/host/etc ubuntu:latest \
    sh -c "echo 'net.core.somaxconn=65535' >> /host/etc/sysctl.conf"

While these methods work, consider the security implications:

  • --privileged gives full host access (equivalent to root)
  • Bind-mounting /proc or /etc exposes critical system paths
  • Always validate configuration files before applying them
# Recommended approach for production:
# 1. Create a custom Docker image with your sysctl config
FROM ubuntu:latest
COPY sysctl.conf /etc/sysctl.d/99-loadbalancer.conf
CMD ["sysctl", "-p", "/etc/sysctl.d/99-loadbalancer.conf"]

# 2. Deploy with limited privileges
docker run --rm --cap-add=SYS_ADMIN -v /proc/sys:/proc/sys your-image

For critical systems, consider using configuration management tools (Ansible, Chef, Puppet) instead of privileged containers for kernel tuning.


When running a Docker container with --privileged flag, you might expect kernel parameter modifications to persist on the host system. However, this isn't the default behavior due to how Docker implements namespace isolation.

# This only changes the parameter within the container
docker run --rm --privileged ubuntu:latest sysctl -w net.core.somaxconn=65535

The key issue is that even privileged containers have their own mount namespace by default. While they have access to all devices and capabilities, the /proc filesystem remains container-specific unless explicitly mounted from the host.

To make lasting changes to host kernel parameters, you need to:

# Method 1: Mount host's procfs directly
docker run --rm --privileged -v /proc:/host/proc ubuntu:latest \
    sh -c "sysctl -w net.core.somaxconn=65535 --system"

# Method 2: Use nsenter to modify host namespaces
docker run --rm --privileged --pid=host ubuntu:latest \
    nsenter -t 1 -m -u -n -i sysctl -w net.core.somaxconn=65535

For production systems, consider these approaches:

# Create a dedicated tuning container with host PID namespace
docker run -d --name kernel-tuner --privileged --pid=host \
    -v /etc/sysctl.conf:/etc/sysctl.conf \
    -v /proc:/host/proc \
    ubuntu:latest tail -f /dev/null

# Then execute changes via exec
docker exec kernel-tuner sysctl -p /etc/sysctl.conf

To ensure changes persist across reboots:

# 1. Modify /etc/sysctl.conf in the container
echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf

# 2. Apply changes immediately
sysctl -p /etc/sysctl.conf

# 3. Verify on host
cat /proc/sys/net/core/somaxconn

While privileged containers offer flexibility, they introduce security risks:

  • Use read-only mounts where possible
  • Limit container capabilities instead of full privileges
  • Consider using --cap-add=SYS_ADMIN instead of --privileged