Changing /Proc/Sys/Kernel/Core_Pattern File Inside Docker Container

How to modify the `core_pattern` when building docker image

I needed this myself, I just found out how.
it is not related to docker, but to linux in general.
I am using ubuntu and I am 99% certain centos will behave the same in this regard.

it is edited via sysctl command.

see example

bash$ cat /proc/sys/kernel/core_pattern 
|/usr/share/apport/apport %p %s %c %d %P %E
bash$ sudo sysctl -w kernel.core_pattern="|/usr/share/apport/apport-kde %p %s %c %d %P %E"
kernel.core_pattern = |/usr/share/apport/apport-kde %p %s %c %d %P %E
bash$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport-kde %p %s %c %d %P %E
bash$

note that value starting with | is to express commands. the core dump will be sent to the command as STDIN

Since you asked your question about docker, let me also provide a compatible answer.

FROM centos:7
RUN sudo sysctl -w kernel.core_pattern="core-%e"

for more info on the core pattern you can use in your file, instead of just %e, see https://sigquit.wordpress.com/2009/03/13/the-core-pattern/

also another related question/answer that has more details

https://unix.stackexchange.com/questions/343275/why-is-editing-core-pattern-restricted

Changing /proc/sys/kernel/core_pattern file inside docker container

The kernel does not support per-container patterns. There is a patch for this, but it is unlikely to go in any time soon. The basic problem is that core patterns support piping to a dedicated process which is spawned for this purpose. But the code spawning it does not know how to handle containers just yet. For some reason a simplified pattern handling which requires a target file was not deemed acceptable.

How to remount the /proc filesystem in a docker as a r/w system?

If the goal is to set sysctl settings, docker has realized the issue and in 1.12+ you can use the --sysctl flag when running a docker container (or in your compose file) which will set the values inside the container before it is run.

This is sadly not (yet) integrated yet in the dockerfile syntax.

https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime

docker run --sysctl kernel.shmmax=1073741824 yourimage

Example docker-compose.yml (must use version 2.1):

version: '2.1'
services:
app:
sysctls:
- kernel.shmmax=1073741824

How to disable core file dumps in docker container

You have to start your container with the option --ulimit core=0 to disable coredumps.

Reference: https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container---ulimit

Example

On the host, temporarily set the coredump path to /tmp for verification:

echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern

Start a container as usual and force a core dump:

docker run --rm -it bash
(inside the container)
# yes > /dev/null &
# kill -SIGABRT $(pidof yes)
# ls /tmp
(shows core.yes.<pid>)

Now, with --ulimit core=0:

docker run --ulimit core=0 --rm -it bash
(inside the container)
# yes > /dev/null &
# kill -SIGABRT $(pidof yes)
# ls /tmp
(No entries)

Where are core files stored in a lxc container?

| indicates that a program should handle the core dump. Rather than saving the coredump to a file it will be piped into that programs input. Means if core_pattern is set to |... apport apport will handle the core dumps.

Unfortunately apport will create coredumps only for installed packages. I would set the pattern to a file name, like this:

echo '/tmp/cores/core.%e.%p.%t' > /proc/sys/kernel/core_pattern

The would give you coredumps like /tmp/core.program.pid.012345678 where program is the program name, pid the program's pid plus a timestamp at the end.

Check man core for more information (espcecially information about meta chars that can be used in the core pattern.

Centos docker container crashes with 6 Segmentation fault - where's the core dump

I ended up skipping the abrt and changing the core_pattern file to out to a directory on the host. Here's my two bytes on getting a core dump out of a crashing docker instance:

On the host:

docker run --privileged -it -v /tmp:/core image-name bash

(you can do this with docker exec, but my machine didn't have the flags available to exec)

--privileged = required to be able to edit the /proc/sys/kernel/core_pattern file

-v = to mount the /tmp directory of the host in a /core directory in the container

In the instance:

set the location of the core dumps to /core (which is a mount of the /tmp dir in the host machine):

echo "/core/core-%e-%s-%u-%g-%p-%t" > /proc/sys/kernel/core_pattern

test it:

sleep 60 &  
kill -SEGV <pid of that sleep process>

Should be able to see a core file in the /tmp dir on the host. When my instance crashed, I finally got the dump in the host machine.

Core dumped, but core file is not in the current directory?

Read /usr/src/linux/Documentation/sysctl/kernel.txt.

core_pattern is used to specify a core dumpfile pattern name.

  • If the first character of the pattern is a '|', the kernel will treat
    the rest of the pattern as a command to run. The core dump will be
    written to the standard input of that program instead of to a file.

Instead of writing the core dump to disk, your system is configured to send it to the abrt (meaning: Automated Bug Reporting Tool, not "abort") program instead. Automated Bug Reporting Tool is possibly not as documented as it should be...

In any case, the quick answer is that you should be able to find your core file in /var/cache/abrt, where abrt stores it after being invoked. Similarly, other systems using Apport may squirrel away cores in /var/crash, and so on.



Related Topics



Leave a reply



Submit