3

Kubernetes 设计模式笔记 —— Init Container

 11 months ago
source link: https://rollingstarky.github.io/2023/09/09/kubernetes-patterns-reading-notes-init-container/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Kubernetes 设计模式笔记 —— Init Container

2023-09-09

| Linux

| 0

|

2.2k

|

0:02

Init Container 为初始化相关的任务提供了区别于主应用程序的独立的生命周期,从而实现关注点分离。

初始化在很多编程语言中都备受关注。比如在 Java 中,为了初始化某个需要配置的对象,我们使用 constructor。
Constructor 会保证在对象中是第一个运行的,且只被 runtime 运行一次。此外,还可以使用构造函数验证强制参数之类的先决条件,传入参数或默认值以初始化实例字段。

Init Container 与构造函数是类似的,只不过是在 Pod 级别而不是类级别。
假如 Pod 中有一个或多个容器代表主应用程序,这些容器可能需要一些启动前的先决条件。比如为文件系统设置特殊的权限,设置数据库 schema,应用程序种子数据的安装等。同时,这些初始化逻辑可能需要主容器镜像中不包含的工具和库。
又或者,用户想要延迟应用的启动,直到可以确认某个外部的依赖满足条件。
所有上述需求都可以通过 Kubernetes 提供的 Init Container 实现。

Kubernetes 中的 Init Container 属于 Pod 定义的一部分,可以将容器划分成两组:init containers 和 application containers。
所有的 init container 会以串行的顺序一个接一个地执行,在应用容器开始启动之前,所有 init container 的执行必须成功完成。
而应用容器是可以并行运行的,启动顺序也是任意的。
Init and application containers

通常情况下,init container 应该是小型快速且能成功完成的,除非它是用来延迟 Pod 的启动以等待某个依赖符合要求。
当 init container 失败时,整个 Pod 会重新启动(除非配置了 RestartNever),导致所有 init container 重新执行一遍。因而令它们符合幂等原则可以避免副作用。
一方面,init container 有着和应用容器一样的能力:位于同一个 Pod 中,共享资源限制、存储卷和安全设置。另一方面,它们的健康检查和资源处理在语义上有些许不同。它们不存在 rediness check,因为只有当所有的 init container 成功结束之后应用容器才会继续启动。

在容器调度、自动伸缩、配额管理方面,Init container 会影响 Pod 请求和计算资源的方式。由于所有的 init container 会先串行执行到终止,接着应用容器并行运行。因而高效的 Pod 级别的资源分配取决于以下两组值中较大的那个:

  • 所有 init container 中资源请求或限制值最大的那个
  • 所有应用容器资源请求或限制的总和

上述行为的限制在于,当 init container 的资源需求非常高而应用容器相对很低时,这种配置对于资源的利用就很低效。因为 init container 一般只运行很短的一段时间,其他 Pod 无法使用 init container 运行结束后空闲下来的资源。

Init container 能够实现关注点分离,从而使容器保持 single-purposed。应用容器可以由只关注应用逻辑的开发工程师创建,而部署工程师可以为其添加 init container 并只关注配置和初始化任务。比如下面的例子。

apiVersion: v1
kind: Pod
metadata:
name: www
labels:
app: www
spec:
initContainers:
- name: download
image: axeclbr/git
command:
- git
- clone
- https://github.com/mdn/beginner-html-site-scripted
- /var/lib/data
volumeMounts:
- mountPath: /var/lib/data
name: source
containers:
- name: run
image: docker.io/centos/httpd
ports:
- containerPort: 80
volumeMounts:
- mountPath: /var/www/html
name: source
volumes:
- emptyDir: {}
name: source

Init container 克隆外部 Git repo 到挂载的路径,该路径通过 emptyDir 挂载卷实现 init 容器和应用容器间的数据共享。

Init container 将 Pod 中的容器分成两组,拥有不同的生命周期、目的甚至作者。
Init 容器分阶段地执行,且只有当前容器成功完成后才继续进行下一阶段,意味着我们可以确保应用初始化的每一个阶段都是有保障的。
应用容器则可以并行运行,没有提供 init 容器那样的保证。我们可以根据目的在 Pod 中合理地组织关注初始化的 init 容器和关注应用本身的应用容器。

Kubernetes Patterns


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK