Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gdraheim/docker-systemctl-replacement
docker systemctl replacement - allows to deploy to systemd-controlled containers without starting an actual systemd daemon (e.g. centos7, ubuntu16)
https://github.com/gdraheim/docker-systemctl-replacement
Last synced: 5 days ago
JSON representation
docker systemctl replacement - allows to deploy to systemd-controlled containers without starting an actual systemd daemon (e.g. centos7, ubuntu16)
- Host: GitHub
- URL: https://github.com/gdraheim/docker-systemctl-replacement
- Owner: gdraheim
- License: eupl-1.2
- Created: 2017-03-21T10:53:50.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-09-15T05:15:29.000Z (4 months ago)
- Last Synced: 2025-01-07T17:04:06.693Z (12 days ago)
- Language: Python
- Homepage:
- Size: 4.29 MB
- Stars: 1,416
- Watchers: 30
- Forks: 405
- Open Issues: 56
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
Awesome Lists containing this project
- awesome-starred - gdraheim/docker-systemctl-replacement - docker systemctl replacement - allows to deploy to systemd-controlled containers without starting an actual systemd daemon (e.g. centos7, ubuntu16) (others)
README
[![Style Check](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/stylecheck.yml/badge.svg?event=push&branch=develop)](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/stylecheck.yml)
[![Type Check](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/typecheck.yml/badge.svg?event=push&branch=develop)](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/typecheck.yml)
[![Unit Tests](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/unittests.yml/badge.svg?event=push&branch=develop)](https://github.com/gdraheim/docker-systemctl-replacement/actions/workflows/unittests.yml)
[![Code Coverage](https://img.shields.io/badge/400%20test-93%25%20coverage-brightgreen)](https://github.com/gdraheim/docker-systemctl-replacement/blob/master/testsuite.py)
[![PyPI version](https://badge.fury.io/py/docker-systemctl-replacement.svg)](https://pypi.org/project/docker-systemctl-replacement/)# docker systemctl replacement
This script may be used to overwrite "/usr/bin/systemctl".
It will execute the systemctl commands without SystemD!This is used to test deployment of services with a docker
container as the target host. Just as on a real machine you
can use "systemctl start" and "systemctl enable" and other
commands to bring up services for further configuration and
testing. Information from "systemctl show" allows deployment
automation tools to work seamlessly.This script can also be run as docker-init of a docker container
(i.e. the main "CMD" on PID 1) where it will automatically bring
up all enabled services in the "multi-user.target" and where it
will reap all zombies from background processes in the container.
When running a "docker stop" on such a container it will also
bring down all configured services correctly before exit.## docker exec lamp-stack-container systemctl list-units --state=running
httpd.service loaded active running The Apache HTTP Server
mariadb.service loaded active running MariaDB database server
## docker exec lamp-stack-container pstree -ap
systemctl,1 /usr/bin/systemctl
|-httpd,7 -DFOREGROUND
| |-httpd,9 -DFOREGROUND
| |-httpd,10 -DFOREGROUND
`-mysqld_safe,44 /usr/bin/mysqld_safe --basedir=/usr
`-mysqld,187 --basedir=/usr --datadir=/var/lib/mysql
|-{mysqld},191
|-{mysqld},192## Problems with SystemD in Docker
The background for this script is the inability to run a
SystemD daemon easily inside a docker container. There have
been multiple workarounds with varying complexity and actual
functionality. (The systemd-nsspawn tool is supposed to help
with running systemd in a container but only rkt with CoreOs
is using it so far).Most people have come to take the easy path and to create a
startup shell script for the docker container that will
bring up the service processes one by one. Essentially one would
read the documentation or the SystemD `*.service` scripts of the
application to see how that would be done. By using this
replacement script a programmer can skip that step.## Service Manager
The systemctl-replacement script does cover the functionality
of a service manager where commands like `systemctl start xx`
are executed. This is achieved by parsing the `*.service`
files that are installed by the standard application packages
(rpm, deb) in the container. These service unit descriptors
define the actual commands to start/stop a service in their
ExecStart/ExecStop settings.When installing systemctl.py as /usr/bin/systemctl in a
container then it provides enough functionality that
deployment scripts for virtual machines continue to
work unchanged when trying to start/stop, enable/disable
or mask/unmask a service in a container.This is also true for deployment tools like Ansible. As of
version 2.0 and later Ansible is able to connect to docker
containers directly without the help of a ssh-daemon in
the container. Just make your inventory look like[frontend]
my_frontend_1 ansible_connection=dockerBased on that `ansible_connection` one can enable the
systemctl-replacement to intercept subsequent calls
to `"service:"` steps. Effectively Ansible scripts that
shall be run on real virtual machines can be tested
with docker containers. However in newer centos/ubuntu
images you need to check for python first.- copy: src="files/docker/systemctl.py" dest="/usr/bin/systemctl"
- package: name="python"
- file: name="/run/systemd/system/" state="directory"
- service: name="dbus.service" state="stopped"See [SERVICE-MANAGER](SERVICE-MANAGER.md) for more details.
---
## Problems with PID 1 in Docker
The command listed as "CMD" in the docker image properties
or being given as docker-run argument will become the PID-1
of a new container. Actually it takes the place that would
traditionally be used by the /sbin/init process which has
a special functionality in unix'ish operating systems.The docker-stop command will send a SIGTERM to PID-1 in
the container - but NOT to any other process. If the CMD
is the actual application (exec java -jar whatever) then
this works fine as it will also clean up its subprocesses.
In many other cases it is not sufficient leaving
[zombie processes](https://www.howtogeek.com/119815/htg-explains-what-is-a-zombie-process-on-linux/)
around.Zombie processes may also occur when a master process does
not do a `wait` for its children or the children were
explicitly "disown"ed to run as a daemon themselves. The
systemctl replacement script can help here as it implements
the "zombie reaper" functionality that the standard unix
init daemon would provide. Otherwise the zombie PIDs would
continue to live forever (as long as the container is
running) filling also the process table of the docker host
as the init daemon of the host does not reap them.## Init Daemon
Another function of the init daemon is to startup the
default system services. What has been known as runlevel
in SystemV is now "multi-user.target" or "graphical.target"
in a SystemD environment.Let's assume that a system has been configured with some
"systemctl enable xx" services. When a virtual machine
starts then these services are started as well. The
systemctl-replacement script does provide this functionality
for a docker container, thereby implementing
"systemctl default" for usage in inside a container.The "systemctl halt" command is also implemented
allowing to stop all services that are found as
"is-enabled" services that have been run upon container
start. It does execute all the "systemctl stop xx"
commands to bring down the enabled services correctly.This is most useful when the systemctl replacement script
has been run as the entrypoint of a container - so when a
"docker stop" sends a SIGTERM to the container's PID-1 then
all the services are shut down before exiting the container.
This can be permanently achieved by registering the
systemctl replacement script as the CMD attribute of an
image, perhaps by a "docker commit" like this:docker commit -c "CMD ['/usr/bin/systemctl']" \
-m ""After all it allows to use a docker container to be
more like a virtual machine with multiple services
running at the same time in the same context.See [INIT-DAEMON](INIT-DAEMON.md) for more details.
---
## Testsuite and Examples
There is an extensive testsuite in the project that allows
for a high line coverage of the tool. All the major functionality
of the systemctl replacement script is being tested so that its
usage in continuous development pipeline will no break on updates
of the script. If the systemctl.py script has some important
changes in the implementation details it will be marked with
an update of the major version.Please run the `testsuite.py` or `make check` upon providing
a patch. It takes a couple of minutes because it may download
a number of packages during provisioning - but with the help of the
[docker-mirror-packages-repo](https://github.com/gdraheim/docker-mirror-packages-repo)
scripting this can be reduced a lot (it even runs without internet connection).Some real world examples have been cut out into a separate
project. This includes dockerfile and ansible based tests
to provide common applications like webservers, databases
and even a Jenkins application. You may want to have a look
at [gdraheim/docker-systemctl-images](https://github.com/gdraheim/docker-systemctl-images)
list.See [TESTSUITE](TESTUITE.md) for more details.
## Development
Although this script has been developed for quite a while,
it does only implement a limited number of commands. It
does not cover all commands of "systemctl" and it will not
cover all the functionality of SystemD. The implementation
tries to align with SystemD's systemctl commands as close
as possible as quite some third party tools are interpreting
the output of it. However the implemented software
[ARCHITECTURE](ARCHITECTURE.md) is very different.The systemctl replacement script has a long [HISTORY](HISTORY.md)
now with over a [thousand commits on github](https://github.com/gdraheim/docker-systemctl-replacement/tree/master)
(mostly for the testsuite). It has also garnered some additional
functionality like the [USERMODE](USERMODE.md) which is
specifically targeted at running docker containers. See the
[RELEASENOTES](RELEASENOTES.md) for the latest achievements.
The choice of the [EUPL-LICENSE](EUPL-LICENSE.md) is intentionally
permissive to allow you to copy the script to your project.Sadly the functionality of SystemD's systemctl is badly
documented so that much of the current implementation is
done by trial and fixing the errors. Some [BUGS](BUGS.md)
are actually in other tools and need to be circumvented. As
most programmers tend to write very simple `*.service` files
it works in a surprising number of cases however. But definitely
not all. So if there is a problem, use the
[github issue tracker](https://github.com/gdraheim/docker-systemctl-replacement/issues)
to make me aware of it. In general it is not needed to emulate
every feature as [EXTRA-CONFIGS](EXTRA-CONFIGS.md) can help.And I take patches. ;)
## The author
Guido Draheim is working as a freelance consultant for
multiple big companies in Germany. This script is related to
the current surge of DevOps topics which often use docker
as a lightweight replacement for cloud containers or even
virtual machines. It makes it easier to test deployments
in the standard build pipelines of development teams.