Kubernetes容器回调

2023-09-14 77

一、容器环境

Kubernetes 的容器环境给容器提供了几个重要的资源:

  • 文件系统,其中包含一个镜像 和一个或多个的卷;
  • 容器自身的信息;
  • 集群中其他对象的信息。

1、容器信息

Pod的名称和命名空间可以通过下行API转换为环境变量,容器内可以使用这些环境变量。同时,容器的hostname会设置为所在Pod的名称,可以通过运行hostname命令或调用libc中的gethostname函数来获取该名称。此外,除了通过镜像静态指定的环境变量外,用户还可以在Pod定义中定义自己的环境变量,并在容器中使用它们。

2、集群信息

创建容器时正在运行的所有服务都可用作该容器的环境变量。 这里的服务仅限于新容器的 Pod 所在的名字空间中的服务,以及 Kubernetes 控制面的服务。对于名为 foo 的服务,当映射到名为 bar 的容器时,定义了以下变量:

FOO_SERVICE_HOST=<其上服务正运行的主机>
FOO_SERVICE_PORT=<其上服务正运行的端口>

服务具有专用的 IP 地址。如果启用了 DNS 插件, 可以在容器中通过 DNS 来访问服务。

二、容器生命周期回调

Kubelet作为Kubernetes的核心组件之一,负责管理节点上的容器。Kubelet可以利用容器生命周期回调框架来在容器生命周期中的特定事件触发时运行指定的代码,从而实现对容器的精细管理。

正如很多编程语言的框架(例如Angular)一样,Kubernetes也为容器提供了生命周期回调的特性。通过生命周期回调,容器可以感知其生命周期中的事件,并在这些事件发生时执行注册的回调函数中实现的代码。

1、容器回调

有两个回调暴露给容器:

  • PostStart

这个回调在容器被创建之后立即被执行。 但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行。没有参数传递给处理程序。

  • PreStop

在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用。 如果容器已经处于已终止或者已完成状态,则对 preStop 回调的调用将失败。 在用来停止容器的 TERM 信号被发出之前,回调必须执行结束。 Pod 的终止宽限周期在 PreStop 回调被执行之前即开始计数, 所以无论回调函数的执行结果如何,容器最终都会在 Pod 的终止宽限期内被终止。 没有参数会被传递给处理程序。

2、回调处理程序实现

容器可以通过实现和注册该回调的处理程序来访问该回调。 针对容器,有两种类型的回调处理程序可供实现:

  • Exec – 在容器的 cgroups 和名字空间中执行特定的命令(例如 pre-stop.sh)。 命令所消耗的资源计入容器的资源消耗;
  • HTTP – 对容器上的特定端点执行 HTTP 请求。

3、回调处理程序执行

当调用容器生命周期管理回调时,Kubernetes 管理系统根据回调动作执行其处理程序, httpGet 和 tcpSocket 在 kubelet 进程执行,而 exec 则由容器内执行。

回调处理程序调用在包含容器的 Pod 上下文中是同步的。 这意味着对于 PostStart 回调,容器入口点和回调异步触发。 但是,如果回调运行或挂起的时间太长,则容器无法达到 running 状态。

PreStop 回调并不会与停止容器的信号处理程序异步执行;回调必须在可以发送信号之前完成执行。 如果 PreStop 回调在执行期间停滞不前,Pod 的阶段会变成 Terminating并且一直处于该状态, 直到其 terminationGracePeriodSeconds 耗尽为止,这时 Pod 会被杀死。 这一宽限期是针对 PreStop 回调的执行时间及容器正常停止时间的总和而言的。 例如,如果 terminationGracePeriodSeconds 是 60,回调函数花了 55 秒钟完成执行, 而容器在收到信号之后花了 10 秒钟来正常结束,那么容器会在其能够正常结束之前即被杀死, 因为 terminationGracePeriodSeconds 的值小于后面两件事情所花费的总时间(55+10)。

如果 PostStart 或 PreStop 回调失败,Kubernetes 将会强制终止容器。因此,建议将这些回调处理程序设计成尽可能轻量级的操作,以确保它们能够在规定的时间内成功完成。有时候执行长时间运行的命令可能也是很有用的,例如,在停止容器之前保存状态或执行清理操作。

4、回调递送保证

Kubernetes 对于回调的递送保证至少一次,回调可能会被多次调用,因此,在实现回调处理程序时需要考虑如何正确处理这种多次调用的情况。通常情况下,只会进行单次递送。 例如,如果 HTTP 回调接收器宕机,无法接收流量,则不会尝试重新发送。 然而,偶尔也会发生重复递送的可能。 例如,如果 kubelet 在发送回调的过程中重新启动,回调可能会在 kubelet 恢复后重新发送。

5、调试回调处理程序

回调处理程序的日志不会在 Pod 事件中公开。 如果处理程序由于某种原因失败,它将播放一个事件。 对于 PostStart,这是 FailedPostStartHook 事件,对于 PreStop,这是 FailedPreStopHook 事件。 要自己生成失败的 FailedPostStartHook 事件,请修改 lifecycle-events.yaml 文件将 postStart 命令更改为 “badcommand” 并应用它。 以下是通过运行 kubectl describe pod lifecycle-demo 后你看到的一些结果事件的示例输出:

Events:
Type   Reason               Age From                Message
----   ------              ---- ----                -------
Normal Scheduled            7s default-scheduler Successfully assigned default/lifecycle-demo to ip-XXX-XXX-XX-XX.us-east-2...
Normal Pulled               6s kubelet Successfully pulled image "nginx" in 229.604315ms
Normal Pulling              4s (x2 over 6s) kubelet Pulling image "nginx"
Normal Created              4s (x2 over 5s) kubelet Created container lifecycle-demo-container
Normal Started              4s (x2 over 5s) kubelet Started container lifecycle-demo-container
Warning FailedPostStartHook 4s (x2 over 5s) kubelet Exec lifecycle hook ([badcommand]) for Container "lifecycle-demo-container" in Pod "lifecycle-demo_default(30229739-9651-4e5a-9a32-a8f1688862db)" failed - error: command 'badcommand' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: \"badcommand\": executable file not found in $PATH: unknown\r\n"
Normal Killing              4s (x2 over 5s) kubelet FailedPostStartHook
Normal Pulled               4s kubelet Successfully pulled image "nginx" in 215.66395ms
Warning BackOff             2s (x2 over 3s) kubelet Back-off restarting failed container
  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。