41

It is a recommended best practice to not run dockerized Node.JS applications as PID 1 (see https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals) in order to correctly capture signals.

The docker run command provides the --init flag to wrap the application entry point with a small init system that forwards signals correctly.

Is there a built-in equivalent of the --init flag in Kubernetes?

I've explored the Pod and Container object specifications for Kubernetes 1.10 but have not seen anything related to specifying how the image gets started.

An alternative would be to explicitly include and use Tini in every container, but I would really like some way that does it transparently the way the --init flag behaves.

Are there other alternatives?

marcind
  • 52,944
  • 13
  • 125
  • 111

2 Answers2

16

If you enable process (PID) namespace sharing for your pods, the init process (pause) will come from Kubernetes. If you have a separate process namespace for your containers, they need to include tini or another init process themselves.

According to https://www.ianlewis.org/en/almighty-pause-container, Kubernetes 1.7 had a shared process namespace by default and a kubelet flag to disable it, 1.8 had it off by default and a kubelet flag to enable it. Kubernetes 1.11 has an alpha feature to enable a shared process namespace: https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/

Roland Weber
  • 1,865
  • 2
  • 17
  • 27
13

If you suppose that Kubernetes creates a container using Docker commands, then you should be aware that it knows nothing about --init key. In other words, Kubernetes has no such wrapper for starting a container with another initial process.

So, if you want to use this feature in Kubernetes, you need to prepare a Docker image with Tini in it.

Actually, Tini is included in Docker 1.13 or greater, and you just enable it by passing the --init flag to docker run. So, to add Tini to your image, use the following code in the Dockerfile:

# Add Tini
ENV TINI_VERSION <check-version-on-github>
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]

# Run your program under Tini
CMD ["/your/program", "-and", "-its", "arguments"]
Artem Golenyaev
  • 2,568
  • 12
  • 20
  • 1
    I am aware of Tini and that fact that I can include it in my images explicitly. I am looking for an alternative where I do not have to modify all of my Dockerfiles. – marcind Jun 12 '18 at 16:22
  • [marcind](https://stackoverflow.com/users/358970/marcind "48,907 reputation"), as I mentiond, for now, there are no other options, only to modify your Dockerfiles – Artem Golenyaev Jun 13 '18 at 07:59
  • 4
    @marcind Kubernetes is a system for orchestration container, Docker `--init` is a feature of a container runtime (for instance, you can use RKT instead of Docker for Kubernetes). So, Kubernetes just cannot contain any features like a custom init systems, because they are runtime specific, and Kubernetes is not. – Anton Kostenko Jun 13 '18 at 08:19
  • 4
    @AntonKostenko "K8s can use RKT" does not imply "K8s cannot contain any Docker-specific support". It would be quite simple to provide runtime-specific configuration options. They just haven't done so. – Alice Purcell Feb 14 '19 at 16:05
  • 4
    Hm.. what? Ok, maybe it was no so clear, but - Kubernetes doesn't support any runtime specific feature and will not support them if they will not be a part of OpenContainer standard. Moreover, it is not an easy to add something runtime-specific because of internal structure and requirements. It you think different, you can always submit a merge request with that small feature. – Anton Kostenko Feb 16 '19 at 12:41
  • 4
    Alternative way to install tini in your Dockerfile (this syntax is for Alpine Linux): `RUN apk add --no-cache tini` `ENTRYPOINT ["/sbin/tini", "--"]`. Got this from @emj365's link – Matt Browne Oct 25 '19 at 18:05