Powered By Blogger

Monday, November 2, 2015

Real-world Docker Series: Run Dedicated Containers as systemd services

Since running docker run commands to start up many containers when a docker host comes online would become impractical and extremely tedious, we can move these commands into systemd service unit files.

To create your own systemd service unit files, you must store the files in /etc/systemd/system.
It's a good practice to name them by prefixing the service name with docker to easily identify what they are later.
Ex: /etc/systemd/system/docker.<containername>.service

Here is an example of a systemd service for a container:
[Unit]
Description=Nginx Container 1
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop Cont1
ExecStartPre=-/usr/bin/docker rm Cont1
ExecStart=/usr/bin/docker run --name Cont1 --rm -v /root/cont1:/usr/share/nginx/html:Z -p 80:80 nginx

[Install]
WantedBy=multi-user.target

If you're unfamiliar with systemd services, there's a few things to notice here.
After: This makes sure the service is started after the docker service.
Requires: This will not run if there is no docker service.
TimeoutStartSec: 0 implies we will not timeout when trying to start this service
Restart: Start the service's process (ExecStart) if it ends
ExecStartPre: You can have many “pre” commands. Notice the '-' at the beginning of the command. This tells the service that if this command fails, move on and do not fail at starting the service. This is important mainly to the restart aspect of this service. The first “pre” command ensures that the container named Cont1 is stopped. The second command ensures it's removed any possible orphaned containers named Cont1.
ExecStart: This is where your docker run command goes, and is the main process that systemd will be watching.
[Install] and WantedBy are replacements for the old chkconfig runlevels. Multi-user.target is the equivalent of run level 3. When we run systemctl enable docker.cont1.service, it will be installed (enabled) at run-level 3.

Caveats:
docker stop <container name> will stop the container temporarily, but systemd will automatically restart the container based on the service we created. Test by running docker stop <container name> then run docker ps. Notice the time the container has been up.

To truly stop the running container, do so by stopping the associated service you created for it.

 systemctl stop <docker.MyContainer'sService>


This is where you may want to introduce some of the power of cgroups (control groups.)  Cgroups allow the administrator to control how much of the host's resources are taken up by child processes.  You would want to add any restrictions for the container's in its service.  This is outside the scope of this series, but you should certainly check out Red Hat's documentation on the topic of cgroups as it pertains to RHEL7, as it has changed significantly with the implementation of systemd in RHEL7.

Next: How to use selinux with docker

No comments:

Post a Comment