3 votes

Comment obtenir un coredump d'un processus planté à l'intérieur d'un conteneur Docker en utilisant apport ?

Nous avons un ensemble de microservices, publiés en tant qu'images docker, et nous les exécutons sur site pour des tests locaux et dans le cluster AKS k8s. Nous utilisons ubuntu 16.04, car AKS l'utilise actuellement.

Nous aimerions collecter automatiquement les coredump lorsque notre microservice plante à l'intérieur du conteneur docker. Nous avons réussi à le faire en suivant les instructions en environnement local, mais nous aimerions utiliser le récupérateur de coredump ubuntu apport.

Mais nous ne parvenons pas à collecter le dump à cause de l'erreur suivante:

ERROR: apport (pid 26994) Thu Apr 9 16:17:34 2020 : l'hôte pid 26979 s'est écrasé dans un conteneur sans support apport

docker run -d --privileged -v /var/crash:/var/crash ubuntu:16.04 /bin/sleep 50000
docker kill 

Après avoir examiné ce que fait apport, il semble que nous devons installer apport à l'intérieur du conteneur. Pas de problème, créez un Dockerfile avec l'installation de apport :

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y --no-install-recommends systemd apport && rm -rf /var/lib/apt/lists/*
RUN sed -i "s/enabled=0/enabled=1/g" /etc/default/apport
RUN sed -i "s/'problem_types'/#'problem_types'/g" /etc/apport/crashdb.conf
COPY ./super.sh /opt/super.sh
RUN ["chmod", "+x", "/opt/super.sh"]
WORKDIR /opt
ENTRYPOINT [ "/opt/super.sh" ]

où super.sh est :

#!/bin/bash
service apport start
sleep 50000

Mais cela donne également le même résultat. Il doit y avoir une entrée apport.socket sous le répertoire de l'hôte /proc//root/run/, qui indique probablement à apport qu'une autre instance est en cours d'exécution à l'intérieur du conteneur. apport.socket est le socket d'activation, qui nécessitera systemd pour fonctionner à l'intérieur du conteneur.

Ce n'est pas si bon

Questions

  1. Y a-t-il un moyen d'activer la transmission de coredump pour une application à l'intérieur d'un conteneur vers la machine hôte en utilisant apport ?
  2. Que faut-il faire à l'intérieur du conteneur pour permettre à apport de passer correctement à la collecte de coredump ?
  3. Est-il vraiment nécessaire d'installer systemd à l'intérieur du docker pour que cela fonctionne ?

P.S.

Nous avons obtenu le comportement que nous souhaitions en commentant certains blocs de code dans /usr/share/apport/apport, introduits par

869366238 data/apport (Brian Murray 2017-11-20 08:46:52 -0800)

mais ce n'est pas la solution que nous aimerions accepter.

2voto

stukselbax Points 151

Pour ceux qui sont vraiment intéressés, voici nos conclusions.

Pour que apport.socket puisse être écouté, vous devez d'abord installer systemd. Pour que systemd fonctionne correctement, il doit être le premier processus dans le conteneur, donc vous devez modifier votre commande ENTRYPOINT pour être /sbin/init. Pour que apport fonctionne correctement à l'intérieur du conteneur, vous devez installer le module python3-systemd qui permet l'activation de systemd et la propagation des paramètres. Pour exécuter votre processus, vous devez rédiger un simple fichier unité qui décrit comment lancer votre application avec systemd. Pour Ubuntu 18.04, vous devez également installer le package init pour permettre l'exécution de /sbin/init.

Si vous utilisez un autre type de virtualisation, comme vmware dans mon cas (qui exécute l'hôte ubuntu, sur lequel s'exécutent des conteneurs docker), vous devez également supprimer ConditionVirtualization=container du fichier apport-forward.socket, sinon systemd n'écoutera pas le socket d'activation mentionné précédemment.

En combinant le tout, voici ce que vous pouvez faire pour activer le fonctionnement correct d'apport à l'intérieur du conteneur.

Fichier Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic
COPY dotnet.service /lib/systemd/system/
RUN apt-get update && apt-get install -y --no-install-recommends \
    systemd \
    init \
    apport \
    python3-systemd && rm -rf /var/lib/apt/lists/*
RUN sed -i "s/enabled=0/enabled=1/g" /etc/default/apport && \
    sed -i "s/'problem_types'/#'problem_types'/g" /etc/apport/crashdb.conf && \
    sed -i "s/ConditionVirtualization=container//g" /lib/systemd/system/apport-forward.socket
RUN systemctl enable apport-forward.socket && \
    systemctl enable dotnet.service

# notre application
COPY . /opt/app
WORKDIR /opt/app
EXPOSE 5000
ENTRYPOINT [ "/sbin/init" ]

Fichier dotnet.service

[Unit]
Description=Mon service

[Service]
Type=oneshot
ExecStart=/opt/app/MyServiceElf

[Install]
WantedBy=multi-user.target

Tout cela ajoute environ 65 Mo de données supplémentaires, ce qui semble fou, donc nous transférons cette question au dépôt d'apport

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X