Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Redno2 <[email protected]>
  • Loading branch information
redno2 committed Nov 3, 2023
1 parent 4b2a84f commit 56d5109
Show file tree
Hide file tree
Showing 12 changed files with 927 additions and 2 deletions.
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

90 changes: 88 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,88 @@
# docker-limiter-desktop
Desktop utility that dynamically manages Docker daemon resources using systemd and cgroups. It ensures optimal container performance while preserving host stability, offering configurable daemon management.
# Docker-Limiter-Desktop

Docker-Limiter-Desktop is a dedicated system utility built to seamlessly manage system resources allocated to Docker daemon on desktop environments.

## Description

Docker-Limiter-Desktop exploits shell scripts in conjunction with `systemd` slice and cgroups to deftly adjust the CPU and Memory quotas and limits allocated to all Docker containers. The configurations for `systemd` slices are dynamically altered based on available system resources, ensuring an equilibrium in system performance while averting potential resource exhaustion scenarios. Additionally, a main configuration file is available to manage the daemon and apply user-specific preferences and settings.

## Features

- **Dynamic Memory Management:** Adjusts memory limit for Docker containers by dynamically altering `systemd` slice configurations based on available system memory. **Default allocate 90% of memory.**

- **CPU Optimization:** Intelligently modifies the CPU quota for Docker containers, adapting to the available CPU cores and their utilization. **Default allocate 90% of CPUs.**

- **Daemon Configuration:** Provides a main configuration file to manage the daemon and its operational parameters.
## How to Use

### Prerequisites

- Docker installed and configured
- systemd for managing services and slices
- Root permissions for managing systemd services and configurations

### Installation and Setup
Download the deb release and
```sh
sudo apt install ./docker-limiter-desktop.deb
```


## Configuration

### System Resource Limits

Modify the system resource limitations applied to Docker containers by editing the configuration file located at `/etc/default/docker-limiter-desktop`.

Here is a basic guide on how to configure the resource limitations:

```plaintext
# /etc/default/docker-limiter-desktop
# Configuration file for Docker Limiter Desktop
# Short description:
# MAX_MEMORY: Maximum percentage of total system memory allocated for Docker containers
# MAX_CPU: Maximum percentage of total system CPU allocated for Docker containers
# The Docker daemon will be automatically restarted after modifications to this file.
```

### Doc
See the cgroups resources usage
```
root@host:/root# systemd-cgtop
Control Group Tasks %CPU Memory Input/s Output/s
/ 1279 119.6 2.7G 178.1K 120.7K
docker.slice 204 101.3 852.3M - -
docker.slice/docker-limiter.slice 204 101.3 852.2M - -
docker.slice/docker-limiter.slice/docker-limiter-desktop.slice 204 101.3 852.2M - -
```
See the heritage
```
root@host:/root# systemd-cgls -u docker-limiter-desktop.slice
Unit docker-limiter-desktop.slice (/docker.slice/docker-limiter.slice/docker-limiter-desktop.slice):
├─docker-8af0064166bd382691f20e43eb5613338c6126e914da30c87a38ff7884cf6130.scope …
│ ├─38491 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38539 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38540 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38541 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38542 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38543 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38544 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38545 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38546 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38547 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38548 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38549 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38550 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38551 stress --cpu 100 --vm 1 --vm-bytes 2G
│ ├─38552 stress --cpu 100 --vm 1 --vm-bytes 2G
...
```
# Dev / test
Build manually the package
```
dpkg-deb --build docker-limiter-desktop
```
9 changes: 9 additions & 0 deletions docker-limiter-desktop/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Package: docker-limiter-desktop
Version: 0.0.4
Section: utils
Priority: standard
Architecture: amd64
Depends: jq
Homepage: https://github.com/swissquote/docker-limiter-desktop
Maintainer: RedNo2 <[email protected]>
Description: Docker daemon controller to limit memory and CPU allocation
17 changes: 17 additions & 0 deletions docker-limiter-desktop/DEBIAN/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

if [ "$1" = "configure" ]; then
if [ ! -e /etc/default/docker-limiter-desktop ]; then
cp /usr/share/docker-limiter-desktop/docker-limiter-desktop /etc/default/docker-limiter-desktop
fi
fi

/usr/local/sbin/docker-limiter-desktop-set-resources

## Reload daemon
systemctl daemon-reload
systemctl enable docker-limiter-desktop
systemctl stop docker-limiter-desktop
systemctl enable docker-limiter-desktop.path
systemctl restart docker-limiter-desktop.path
systemctl restart docker
6 changes: 6 additions & 0 deletions docker-limiter-desktop/DEBIAN/postrm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

if [ "$1" = "remove" ]; then
echo "Deleting the config file..."
rm -f /etc/default/docker-limiter-desktop
fi
32 changes: 32 additions & 0 deletions docker-limiter-desktop/DEBIAN/preinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash


CONFIG_FILE="/etc/docker/daemon.json"
KEY="cgroup-parent"
VALUE="docker-limiter-desktop.slice"

# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "jq could not be found. Please install it to proceed."
exit 1
fi

# Check if the configuration file exists and is a file
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "{ \"$KEY\": \"$VALUE\" }" > "$CONFIG_FILE"
echo "Configuration file created and configuration added."
else
# Check if the key-value pair is present in the config file
CURRENT_VALUE=$(jq -r ".[\"$KEY\"]" "$CONFIG_FILE")

if [[ "$CURRENT_VALUE" == "$VALUE" ]]; then
echo "Configuration already exists."
else
# Add or update the key-value pair
jq ".[\"$KEY\"] = \"$VALUE\"" "$CONFIG_FILE" > "$CONFIG_FILE.tmp" \
&& mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
echo "Configuration added or updated."
fi
fi


36 changes: 36 additions & 0 deletions docker-limiter-desktop/DEBIAN/prerm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

CONFIG_FILE="/etc/docker/daemon.json"
KEY="cgroup-parent"
VALUE="docker-limiter-desktop.slice"

# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "jq could not be found. Please install it to proceed."
exit 1
fi

# Check if the configuration file exists and is a file
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "Configuration file does not exist."
else
# Check if the key-value pair is present in the config file
CURRENT_VALUE=$(jq -r ".[\"$KEY\"]" "$CONFIG_FILE")

if [[ "$CURRENT_VALUE" == "$VALUE" ]]; then
# Remove the key-value pair
jq "del(.[\"$KEY\"])" "$CONFIG_FILE" > "$CONFIG_FILE.tmp" \
&& mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
echo "Configuration removed."
else
echo "Specified configuration not found."
fi
fi

## Reload daemon
systemctl stop docker-limiter-desktop
systemctl disable docker-limiter-desktop
systemctl stop docker-limiter-desktop.path
systemctl disable docker-limiter-desktop.path
systemctl daemon-reload
systemctl restart docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Path]
PathModified=/etc/default/docker-limiter-desktop

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Docker daemon controller to limit memory and CPU allocation
After=docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/docker-limiter-desktop-set-resources
StandardOutput=journal

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# /etc/systemd/system/docker-limiter-desktop.slice
[Unit]
Description=Limited resources Slice for Docker daemon
Before=slices.target

[Slice]
CPUAccounting=true
CPUQuota=800%
MemoryAccounting=true
MemoryLimit=8G
MemoryMaxSwap=10G
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

set -a
. /etc/default/docker-limiter-desktop

## Memory
total_mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
# Calculate 90% of the memory
limit_mem_kb=$((total_mem_kb * $MAX_MEMORY / 100))
sed -i "/\[Slice\]/,/^$/s/MemoryLimit=.*/MemoryLimit=${limit_mem_kb}K/" /etc/systemd/system/docker-limiter-desktop.slice

## CPU
total_cpus=$(nproc)
# Calculate 90% of the CPUs formated for CPUQuota
limit_cpu_quota=$((total_cpus * $MAX_CPU))
sed -i "/\[Slice\]/,/^$/s/CPUQuota=.*/CPUQuota=${limit_cpu_quota}%/" /etc/systemd/system/docker-limiter-desktop.slice

## Reload services
systemctl daemon-reload
systemctl restart docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# /etc/default/desktop-docker-limiter

# IMPORTANT: Modifying the configurations in this file will automatically trigger
# a restart of the Docker daemon to apply the new resource limits. Ensure that such
# a restart is safe in your environment to prevent disruptions to running containers.

# This configuration file is used to define the maximum percentage of system resources
# that can be utilized by Docker containers when using the Desktop-Docker-Limiter utility.

# MAX_MEMORY: The maximum percentage of total system memory that can be allocated
# across all Docker containers. Expressed as an integer percentage (0-100).
# Example: MAX_MEMORY=90 means Docker containers can use up to 90% of total system memory.
MAX_MEMORY=90

# MAX_CPU: The maximum percentage of total CPU resources that can be allocated
# across all Docker containers. Expressed as an integer percentage (0-100).
# Example: MAX_CPU=90 means Docker containers can use up to 90% of total CPU resources.
MAX_CPU=90

0 comments on commit 56d5109

Please sign in to comment.