Search code examples
dockerdocker-swarm

Running a container as child of Swarm service


I need to run a container ('child' image) that has access to the GPU for video encode acceleration, but I also need for it to be orchestrated by Swarm. The compose file (stack file) below effectively launches the child image, but when the stack is removed, the child container is left orphaned. I'm trying to avoid running Docker-in-Docker per Jérôme Petazzoni's excellent blog. Are there any additional labels I'm missing in order to have the child container linked to the parent service--allowing the child container to be orchestrated by Swarm via the parent service?

version: "3.7"
services:
  parent-service:
    image: docker:stable
    entrypoint: [sh, -c]
    environment:
      TASK_NAME: '{{.Task.Name}}'
    command: >-
      'exec docker run
      --interactive
      --device=/dev/dri/renderD128:/dev/dri/renderD128
      --label com.docker.stack.namespace=$$(docker container inspect --format "{{index .Config.Labels \"com.docker.stack.namespace\"}}" $${TASK_NAME})
      --volumes-from=$${TASK_NAME}
      --rm
      child:latest'
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock

Solution

  • It turns out this is pretty straight forward in Docker as long as you keep the PID chain of sidecar container (the child) intact and manage OS signals properly. If the PID chain stays intact, the child container will receive a SIGTERM signal when the parent service terminates. We have come across 3 cases we have to deal with; 1.) container is directly running our application which we can control to ensure signals are handled, 2.) container application is a 3rd party app that runs under shell and handles signals properly, and 3.) container application does not handle signals properly.

    1. In this case your app is PID 1, so you ensure it handles signals, such as SIGTERM, properly and terminates the application to avoid zombie containers.
    2. In this case, the PID chain is maintained by executing the application under shell using 'exec', which transitions the container's PID 1 from the shell to the application.
    3. For this final case, you can launch the container application using dumb-init which will manage the signals on behalf of the application. In this case, ensure dumb-init is PID 1.