Open Ilmn-Ybi opened 6 years ago
Correction - there are no brackets ('{}') after 'Services', I copied from an incorrect copy of .yml file.
services: {}
For those who may want to know, it turned out that I need to set up 'dumb-init' to kill the error.
Hey @Ilmn-Ybi , could you explain what you mean by "I need to set up 'dumb-init' to kill the error" What exactly did you do to kill the error? I'm experiencing the same issue and it's blocking me on my project
@Ilmn-Ybi Is issue resolved now? Do you have objections for this issue to be closed?
@Voronenko If you think the issue is resolved, could you explain what the resolution is? I have the same issue and it's not resolved for me yet @Ilmn-Ybi isn't answering my question.
@jochenparm In this specific case, I understand that there were no dumb-init installed inside container. For your scenario issue might be different
Okay, can you explain to me why I need to install a dumb-init in my container to use Ansible Container with it if it wasn't necessary to do this when using a dockerfile? And if it is needed for compatibility with Ansible Container, is this documented somewhere?
It is not linked to ansible-container, but about unix systems in general (most often used base image in docker )
https://docs.docker.com/v17.09/engine/reference/run/#specify-an-init-process
Quoting some article:
Although people say, that proper docker microservice should run single dedicated process, it is not always achievable in real world. More correct to say, that Docker suggests the philosophy of running a single logical service per container. A logical service can consist of multiple OS processes. Sometimes you really need to run more than one service in a docker container. This is especially true, if you are adapting some application that previously was running in standalone vps environment.
Why init process is important: running processes can be visualized are ordered in a tree: each process can spawn child processes, and each process has a parent except for the top-most process. This top-most process is the init process. It is started when you start your container and always has PID 1. This init process is responsible for starting the rest of the system, including starting your application. When some process terminates, it turns into smth referred as “defunct process”, also known as a “zombie process” (https://en.wikipedia.org/wiki/Zombie_process). In simple words, these are ones that are terminated but have not (yet) been waited for by their parent processes.
But what if parent process terminates (intentionally, or unintentionally)? What happens then to its spawned processes? They no longer have a parent process, so they become “orphaned” (https://en.wikipedia.org/wiki/Orphan_process).
And this is where the init process kicks in. It becomes new parent (adopts) orphaned child processes, even though they were never created directly by the init process. The operating system kernel automatically handles adoption. Moreover: the operating system expects the init process to reap adopted children too.
What if not? As long as a zombie is not removed from the system via a wait, it will consume a slot in the kernel process table, and if this table fills, it will not be possible to create further processes in the host system itself. Also, init system implemented wrong often leads to incorrect handling of processes and signals, and can result in problems such as containers which can’t be gracefully stopped, or leaking containers which should have been destroyed.
More reading on a topic:
Upstart, Systemd, SysV usually are too heavy (overkill) to be used inside docker (+ not always easily possible). What are the options ?
At a time of article writing, most often used init approaches were:
as per docker documentation, https://docs.docker.com/engine/admin/multi-service_container/ Take a look on a Proof-of-concept example of such script below
Will work, but really does not guarantee reaping… Let’s examine more robust alternatives.
dumb-init is a simple process supervisor and init system designed to run as PID 1 inside minimal container environments (such as Docker). It is deployed as a small, statically-linked binary written in C.
dumb-init enables you to simply prefix your command with dumb-init. It acts as PID 1 and immediately spawns your command as a child process, taking care to properly handle and forward signals as they are received.
Project repo: https://github.com/Yelp/dumb-init
Tini advertises itself as a tiny but valid init for containers. Promises:
Shipped as precompiled binary for hugh variety of platforms.
Project repo: https://github.com/krallin/tini
Runit is a cross-platform Unix init scheme with service supervision, a replacement for sysvinit, and other init schemes. It runs on GNU/Linux, BSD, can easily be adapted to other Unix operating systems. The program runit is intended to run as Unix process no 1, it is automatically started by the runit-init /sbin/init-replacement if this is started by the kernel.
Project website: http://smarden.org/runit/
S6 is project, actually sibling of the RUnit by http://skarnet.org/software/s6/overview.html. S6 contains collection of utilities revolving around process supervision and management, logging, and system initialization. More over, specifically for a docker exists helper project, so-called “s6-overlay” https://github.com/just-containers/s6-overlay
S6 provides:
Part of the Phusion baseimage project https://github.com/phusion/baseimage-docker, which currently targets Ubuntu 16:04, Ubuntu 14:04 OS-es. Consists of custom written py file and wrapped optional runit.
Provides
Requires: python inside your container. In present form limited to Ubuntu base system only.
This is known process manager usually used with python applications. I often saw people trying to use it as init system. But: supervisor explicitly mentions that it is not meant to be run as your init process. If you have some subprocess fork itself off, it won’t be cleaned up by Supervisor. Thus you anyway would need to choose different init system.
Good if you anyway used it with your application earlier.
From mentioned above and at the same time lightweight, worse to mention:
Classic supervisor which does not even require root privileges. Ctl script that acts similar to systemd’s systemctl. Supports processes restarting, as well as event handlers based on shell protocols.
Runit ships with swiss-knife set of utilities, one of them is runsvdir
(http://smarden.org/runit/runsvdir.8.html)
It allows defining set of "service definitions" in some directory, and makes
care on launching them at startup.
Typical interaction examples:
/usr/bin/sv status /etc/service/
- get status of services listed in
configuration folder
/usr/bin/sv -w 10 down /etc/service/*
- shutdown all services with timeout 10
Unlike supervisor, s6 uses a folder structure to control services, similar to RUnit. S6-overlay requires them under /etc/services.d before running init (it then copies them over to /var/run/s6/services).
Now, each of those run files is an executable that s6 executes to start the process.
Services are controlled by s6-svc binary. It has number of options, but the main idea is that you give it the directory of the service. So for example, if I wanted to send SIGHUP to nginx, I would do s6-svc -h /var/run/s6/services/nginx. Note: that it’s /var/run and not /etc/services.d; This is hugh difference from RUnit. And lastly, the -h is for SIGHUP.
s6-overlay comes with a number of built versions, so you can download the one that matches your Linux setup. If you want to use s6 directly, users of Alpine and a few other flavors of Linux can just install it from their package manager. We’re running Debian and there’s no PPA for it, so we would have to compile s6 on our own
ISSUE TYPE
container.yml
OS / ENVIRONMENT
SUMMARY
The container.xml file was original (downloaded from github). Ansible-container init and build fine. It can be urn with the 'web' section commented (i.e. no web service). When 'web' section was uncommented, 'ansible-container run' threw errors
STEPS TO REPRODUCE
EXPECTED RESULTS
Run without error(s)
ACTUAL RESULTS
issues/709 Got error. I read through existing related reports, but didn't see clear solution or fix.