Kubernetes concept - container environment, container life cycle callback

1. Container environment

The Kubernetes container environment provides containers with several important resources:

  • file system, which consists of a mirror and one or more volumes
  • Information about the container itself
  • Information about other objects in the cluster

container information

A container's hostname is the name of the Pod in which the container is running. The name can be obtained by the hostname command or by calling the gethostname function in libc.

Pod names and namespaces can be converted to environment variables via the downstream API.

User-defined environment variables in a Pod definition are also available in the container, just like any environment variables specified statically in the container image.

cluster information

All services that were running when the container was created are available as environment variables for that container. The services here are limited to services in the same namespace as the pods of the new container, and services in the Kubernetes control plane.

For a service named foo , when mapped to a container named bar , the following variables are defined:

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

Services have dedicated IP addresses. If the DNS plugin is enabled, services can be accessed via DNS in the container.

2. Container life cycle callback

overview

Similar to many programming language frameworks that have lifecycle callback components, such as Angular, Kubernetes provides lifecycle callbacks for containers. Callbacks enable a container to be aware of events in its management lifecycle and run code implemented in handlers when the corresponding lifecycle callback is executed.

container callback

There are two callbacks exposed to the container:

PostStart

This callback is executed immediately after the container is created. However, there is no guarantee that the callback will be executed before the container entry point (ENTRYPOINT). No parameters are passed to the handler.

PreStop

This callback is called before the container is terminated due to an API request or a management event (such as a liveness probe, failure to start a probe, resource preemption, resource competition, etc.). The call to the preStop callback will fail if the container is already in the terminated or completed state. The callback must finish executing before the TERM signal used to stop the container is issued. The Pod's termination grace period starts counting before the PreStop callback is executed, so regardless of the execution result of the callback function, the container will eventually be terminated within the Pod's termination grace period. No arguments will be passed to the handler.

See Terminating Pods for a more detailed description of termination behavior.

Implementation of the callback handler

Containers can access this callback by implementing and registering a handler for that callback. For containers, there are two types of callback handlers that can be implemented:

  • Exec - Executes a specific command (eg pre-stop.sh) in the container's cgroups and namespaces. The resources consumed by the commands are counted towards the resource consumption of the container.
  • HTTP - Perform an HTTP request to a specific endpoint on the container.

Callback handler executes

When the container lifecycle management callback is invoked, the Kubernetes management system executes its handler according to the callback action, httpGet and tcpSocket are executed in the kubelet process, while exec is executed by the container.

Callback handler invocation is synchronous within the context of the Pod containing the container. This means that for the PostStart callback, the container entry point and the callback fire asynchronously. However, if the callback runs or hangs for too long, the container cannot reach the running state.

The PreStop callback does not execute asynchronously with the signal handler that stops the container; the callback must finish executing before the signal can be sent. If the PreStop callback stalls during execution, the Pod's phase becomes Terminating and remains in that state until its terminationGracePeriodSeconds are exhausted, at which point the Pod is killed. This grace period is for the sum of the execution time of the PreStop callback and the normal stop time of the container. For example, if terminationGracePeriodSeconds is 60, the callback function took 55 seconds to finish executing, and the container took 10 seconds to finish normally after receiving the signal, then the container will be killed before it can finish normally, because the terminationGracePeriodSeconds The value is less than the total time spent on the latter two things (55+10).

It kills the container if the PostStart or PreStop callbacks fail.

Users should make their callback handlers as lightweight as possible. But there are also cases where long-running commands are also useful to consider, such as saving state before stopping a container.

Callback Delivery Guarantee

The delivery of the callback should be at -least-once , which means that for any given event, such as PostStart or PreStop, the callback can be called multiple times. How to correctly handle the situation of being called multiple times is a problem to be considered by the callback implementation.

Typically, only a single delivery will be made. For example, if the HTTP callback receiver is down and unable to receive traffic, it will not attempt to resend. Occasionally, however, the possibility of double delivery may occur. For example, if the kubelet restarts in the middle of sending a callback, the callback may be resent after the kubelet resumes.

debug callback handler

Logging for callback handlers is not exposed in Pod events. If the handler fails for some reason, it will broadcast an event. For PostStart this is the FailedPostStartHook event, for PreStop this is the FailedPreStopHook event. To generate the failed FailedPostStartHook event yourself, modify the lifecycle-events.yaml file to change the postStart command to "badcommand" and apply it. Here is an example output of some of the resulting events you see by running 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

Guess you like

Origin blog.csdn.net/leesinbad/article/details/132027858