概念 - Kubernetes 容器生命周期钩子

该部分描述 Kubelet 托管容器如何使用容器生命周期钩子框架来运行事件在其管理生命周期中触发的代码。

  • 概述
  • 容器钩子
  • 下一步怎么做

概述

与许多具有组件生命周期钩子的编程语言框架(例如 Angular)类似,Kubernetes 为 Containers 提供了生命周期钩子。钩子使容器能够知道其管理生命周期中的事件,并在执行相应的生命周期钩子时运行在句柄中实现的代码。

容器钩子

容器有两个钩子:

PostStart

创建容器后,该钩子立即执行。但是,不能保证钩子将在容器 ENTRYPOINT 之前执行。没有参数传递给句柄。

PreStop

由于 API 请求或管理事件(例如,存活探针失败、抢占、资源争用等)而终止容器之前,将立即调用该钩子。如果容器已经处于终止或完成状态,则对 preStop 钩子的调用将失败。它是阻塞的,表示它是同步的,因此必须先完成删除容器的调用才能发送。没有参数传递给句柄。

有关终止行为的更详细说明,请参见 Pod 的终止(敬请期待~~)。

钩子句柄实现

容器可以通过实现并注册该钩子的句柄来访问该钩子。可以为容器实现两种类型的钩子句柄:

  • Exec - 在 Container 的 cgroup 和命名空间内执行特定命令,例如 pre-stop.sh。命令消耗的资源计入容器;
  • HTTP - 针对容器上的特定端点执行 HTTP 请求。

调用 Container 生命周期管理钩子时,Kubernetes 管理系统将在为该钩子注册的 Container 中执行句柄。

钩子句柄的调用在包含容器的 Pod 上下文中是同步的。这意味着对于 PostStart 钩子,容器 ENTRYPOINT 和钩子会异步触发。但是,如果钩子花费太长时间才能运行或挂起,则容器无法达到运行状态。

对于 PreStop 钩子,其行为类似。如果钩子在执行期间挂起,则 Pod 阶段将保持在 Termination 状态,并在 pod 的 TerminationGracePeriodSeconds 结束后被终止。如果 PostStartPreStop 钩子失败,它将终结容器。

用户应使其钩子句柄尽可能轻便。但是,在某些情况下,长时间运行的命令才有意义,例如当在停止容器之前保存状态。

钩子传递至少要执行一次,这意味着对于任何给定事件(例如 PostStartPreStop),可以多次调用钩子。钩子实现可以正确处理该问题。

通常,只进行一次交付。例如,如果 HTTP 钩子接收器关闭并且无法进行通信,则不会尝试重新发送。但是,在极少数情况下,可能会出现双重交付。例如,如果 kubelet 在发送钩子的过程中重新启动,则可能在 kubelet 重新出现后重新发送该钩子。

钩子句柄的日志未在 Pod 事件中公开。如果句柄由于某种原因失败,则广播事件。对于 PostStart,这是 FailedPostStartHost 事件,对于 PreStop,这是 FailedPreStopHook 事件。我们可以通过运行 kubectl describe pod 来查看这些事件。这是运行该命令的事件的一些示例输出:

Events:
  FirstSeen  LastSeen  Count  From                                                   SubObjectPath          Type      Reason               Message
  ---------  --------  -----  ----                                                   -------------          --------  ------               -------
  1m         1m        1      {default-scheduler }                                                          Normal    Scheduled            Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Pulling              pulling image "test:1.0"
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Created              Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Pulled               Successfully pulled image "test:1.0"
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Started              Started container with docker id 5c6a256a2567
  38s        38s       1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Killing              Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
  37s        37s       1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Killing              Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
  38s        37s       2      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}                         Warning   FailedSync           Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
  1m         22s       2      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Warning   FailedPostStartHook

下一步怎么做

  • 了解有关容器环境(敬请期待~~)的更多信息
  • 获得将句柄附加到容器生命周期事件(敬请期待~~)的实践经验

你可能感兴趣的:(Kubernetes,指南)