Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@drmalex07
Last active March 17, 2024 07:42
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save drmalex07/87ad205751765d471e11 to your computer and use it in GitHub Desktop.
Save drmalex07/87ad205751765d471e11 to your computer and use it in GitHub Desktop.
Wrap a docker container in a systemd service. #docker #systemd.service #systemd #cgroups

README

Suppose we want to wrap a container running a Redis instance as a service.

Override unit file for docker daemon

We must override the service unit file that ships with docker (under /lib/systemd/system) in order to pass some cgroup-related options to the docker daemon. So, following the usual method to override parts of a unit file, we create the file /etc/systemd/system/docker.service.d/10-service.conf with contents:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon --exec-opt native.cgroupdriver=systemd --cgroup-parent system.slice -H fd://

Verify that docker is actually overriden by running systemctl cat docker and systemctl show docker| grep ExecStart

Define a slice

Suppose we want to control the resources allocated to our Redis service. We define a slice /etc/systemd/system/redis.slice with contents (just an examples):

[Unit]
Description=Resource control for Redis containers
Before=slices.target

[Slice]

CPUAccounting=yes
CPUShares=1024

MemoryAccounting=yes
MemoryLimit=134217728

This unit file will be referenced by the service unit files. For more info on available options, see man systemd.resource-control

Create a service for the container

Let's call our service as redis-1. We create a corresponding service unit file at /etc/systemd/system/redis-1.service. There are many options available (see man systemd.service), the following is a very simple one creating an one-off container (with docker run):

[Unit]
Description=Redis container
Requires=docker.service
After=docker.service redis.slice

[Service]
Restart=always

# Using `docker start` for an existing container is also valid 
ExecStart=/usr/local/bin/docker run --rm --name redis-1 --hostname redis-1.1 --cgroup-parent redis.slice redis:3.0
ExecStop=/usr/local/bin/docker stop -t 2 redis-1

[Install]
WantedBy=multi-user.target

Enable services

systemctl stop docker.service
systemctl reenable docker.service
systemctl start docker.service
systemctl enable redis-1.service
systemctl start redis-1.service

Verify that redis-1 is running inside redis.slice cgroup:

systemd-cgls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment