Kubernetes 相当于 `docker run --init`

Posted

技术标签:

【中文标题】Kubernetes 相当于 `docker run --init`【英文标题】:Kubernetes equivalent of `docker run --init` 【发布时间】:2018-11-21 00:44:35 【问题描述】:

建议的最佳做法是不要将 dockerized Node.JS 应用程序作为 PID 1(请参阅https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals)运行以正确捕获信号。

docker run 命令提供了--init 标志,以使用正确转发信号的小型初始化系统包装应用程序入口点。

Kubernetes 中是否有内置的 --init 标志?

我已经探索了 Kubernetes 1.10 的 Pod 和 Container 对象规范,但没有看到任何与指定映像如何启动相关的内容。

另一种方法是在每个容器中显式包含和使用Tini,但我真的想要某种方式,可以像--init 标志的行为方式那样透明地执行它。

还有其他选择吗?

【问题讨论】:

仅供参考,这似乎也是 .NET Core 的建议:github.com/dotnet/runtime/issues/21661 【参考方案1】:

如果您为 pod 启用进程 (PID) 命名空间共享,则 init 进程 (pause) 将来自 Kubernetes。如果您的容器有单独的进程命名空间,则它们需要包含 tini 或其他 init 进程本身。

根据https://www.ianlewis.org/en/almighty-pause-container,Kubernetes 1.7 默认有一个共享进程命名空间和一个 kubelet 标志来禁用它,1.8 默认情况下它是关闭的,一个 kubelet 标志来启用它。 Kubernetes 1.11 具有启用共享进程命名空间的 alpha 功能: https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/

【讨论】:

为了快速参考,这是在 Pod 规范中添加 shareProcessNamespace: true 的问题。【参考方案2】:

如果您假设 Kubernetes 使用 Docker 命令创建容器,那么您应该知道它对 --init 键一无所知。换句话说,Kubernetes 没有这样的包装器来启动具有另一个初始进程的容器。

所以,如果你想在 Kubernetes 中使用这个功能,你需要准备一个带有Tini 的 Docker 镜像。

实际上,Tini 包含在 Docker 1.13 或更高版本中,您只需将 --init 标志传递给 docker run 即可启用它。因此,要将 Tini 添加到您的图像中,请在 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"]

【讨论】:

我知道 Tini 以及我可以明确地将它包含在我的图像中的事实。我正在寻找一种无需修改所有 Dockerfile 的替代方案。 @marcind Kubernetes 是一个用于编排容器的系统,Docker --init 是容器运行时的一个特性(例如,你可以使用 RKT 代替 Docker for Kubernetes)。因此,Kubernetes 不能包含任何像自定义初始化系统这样的功能,因为它们是特定于运行时的,而 Kubernetes 不是。 @AntonKostenko “K8s 可以使用 RKT”并不意味着“K8s 不能包含任何 Docker 特定的支持”。提供特定于运行时的配置选项将非常简单。他们只是没有这样做。 嗯..什么?好吧,也许不是很清楚,但是 - Kubernetes 不支持任何运行时特定的功能,如果它们不是 OpenContainer 标准的一部分,也不会支持它们。此外,由于内部结构和要求,添加特定于运行时的东西并不容易。如果您认为不同,您可以随时提交具有该小功能的合并请求。 在 Dockerfile 中安装 tini 的另一种方法(此语法适用于 Alpine Linux):RUN apk add --no-cache tiniENTRYPOINT ["/sbin/tini", "--"]。从@emj365 的链接得到这个

以上是关于Kubernetes 相当于 `docker run --init`的主要内容,如果未能解决你的问题,请参考以下文章

docker 入门(二):docker 和 沙盒、虚拟机以及 Kubernetes 的关系

Kubernetes之三 k8s中的pod

K8S VS Docker !结局意想不到!

KUBERNETES04_下载策略私有仓库下载envcommand生命周期容器钩子资源限制

KUBERNETES04_下载策略私有仓库下载envcommand生命周期容器钩子资源限制

kubernetes 为何弃用docker?