<p>I'm planning to use the distroless base image to run container applications.</p>
<p>Since I'm using envoy in the k8s sidecar, when I stop the application container, I use the sleep command in preStop before safely stopping the pod.</p>
<pre><code>lifecycle
 preStop:
  exec:
    command:
     - sleep
     - &quot;40
</code></pre>
<p>Since the distroless image does not allow the use of shells, etc., we use a multi-stage build so that we can use the sleep command.</p>
<p>This simple golang application.</p>
<pre><code>FROM alpine:3.13 as builder

ENV GOROOT /go

FROM gcr.io/distroless/static-debian10

WORKDIR /app
COPY ./dist/app ./
COPY --from=builder /bin/sleep /bin/sleep


CMD [&quot;./app&quot;]
</code></pre>
<p>The sleep command was failing when I started the Pod in this image and had it switch to another Pod.</p>
<pre><code>Exec lifecycle hook ([sleep 40]) for Container
</code></pre>
<p>Is it not possible to do it this way?
If I'm doing this wrong, I'd like pointers.</p>
<p>Thanks.</p>

<p>The &quot;distoless&quot; images really only make sense when your image consists of <em>only</em> the application you're trying to run, and absolutely nothing else.  This is often a good practice, but trying to bring in the additional <strong>sleep</strong>(1) command isn't quite compatible with it.</p>
<p>I can suggest a couple of approaches to get around this:</p>
<ol>
<li><p>Figure out how to not need <strong>sleep</strong>(1) at all.  &quot;We need to wait 40 seconds, because Envoy&quot; seems like you're working around a bug; fix that bug, instead of trying to delay the container shutdown.</p>
</li>
<li><p>Reimplement the delay in the same language as your main application.  In Python, for example, it's a 3-line script.  Then everything you need to run it is in the image already.</p>
</li>
<li><p>Get a statically-compiled <strong>sleep</strong>(1) binary.  The easiest way to get this is from the <a href="https://busybox.net" rel="nofollow noreferrer">BusyBox</a> tool suite, which contains many common Unix utilities in a single binary; but Alpine Linux is basically just BusyBox plus a package manager, so in turn the easiest way to get BusyBox is to change your image to be <code>FROM</code> an Alpine-based image.</p>
</li>
<li><p>Get all of the dynamic libraries the <strong>sleep</strong>(1) binary requires.  You can run <code>ldd sleep</code> in an environment where it works to figure out what they are.  You probably don't want to copy them directly from the host, though, and this is where normal Linux distributions come with these libraries prepackaged (and come with a <code>/bin/sleep</code> already).</p>
</li>
</ol>
<p>In your Dockerfile you are probably getting a broken symlink <code>/bin/sleep -&gt; busybox</code>.  You could also copy the <code>busybox</code> binary over, but this essentially defeats the point of having a distroless image.</p>
