Kubernetes workloads

Deploy containerized workloads on Kubernetes

view on github

A workload is an application running as a distributed system on a K8s cluster, inside a set of Pods.


Table of contents

  1. Pods
  2. Ancillary containers for pods
  3. Pod lifecycle
  4. Healthchecks
  5. Static pods

  • A pod is the smallest deployable unit of computing that can be created and managed in a cluster.
  • It is a group of containers that :
    1. Share configuration.
    2. Share network and storage resources.
    3. Share execution context and environment variables.
    4. Are co-located : run on the same cluster node.
    5. Are co-scheduled : run at the same time.

The "one-container-per-Pod" model

  • For simplicity's sake, we will assume that each pod will run a single container which covers the vast majority of use cases.
  • The rationale behind that is that K8s manages a container as well as its configuration, resources and execution context as a pod.
  • Diverting from this policy is necessary only if multiple processes are tightly coupled.
  • Also, this rationale stems from the fact that pods are considered ephemeral, interchangeable and disposable.
  • An individual pod will be placed by kube-scheduler, then started by kubelet and will run until either :
    1. The pod process exits.
    2. The pod object is deleted from the cluster state.
    3. The pod is evicted for lack of resources.
    4. The cluster node fails.

Notes :

  • Case 2 can occur for instance when the desired PodTemplate changes for the current set of pods.
  • It is unnecessary as well as strongly discouraged to manage pods directly in the vast majority of cases.
  • If an individual pod is not significant and if the workload it contains has to scale horizontally, it's better to think of workloads as being inherently scalable. K8s provides these capabilities through objects that represent sets of pods (like Deployment).

Ancillary containers for pods

  • Ancillary containers can exist in a pod along with the workload container while still conforming to the above model.
  • They are described in the Pod or Deployment manifest along with the workload container and extend its functionalities.
  • An ordered sequence of containers that have to complete execution and exit with 0 (success) before the next init container starts.
  • Once the last declared init container has successfully exited, kubelet starts the workload container.
  • Init containers offers the following benefits :
    1. Block or delay workload container startup until conditions are met (this allows ordered startup of interdependent Services).
    2. Offload any processing that happens only once at startup from the workload container image to the init container image.
    3. Offer a safe environment for any processing that deals with confidential data or unsecured code execution.
  • By construction, init containers do not support :

Note : a pod will never be added to the resource pool of a service before its workload container is started.

  • An init container that does not need to exit with 0 and keeps running even after the workload container starts.
  • It is described in the manifest as an initContainer that has restartPolicy set to Always and supports container probes as well.
  • Their lifecycle is independant from workload or init containers in the same pod.

  • The lifecycle of a pod involves actions by kube-scheduler, kubelet and container-runtime and is stored as a PodStatus object.

  • For observability purposes, it is represented as a succession of phases :

    phase description
    Pending Setup and execution of init containers
    Running Workload container has started
    Succeeded Workload container exited with 0
    Failed Workload container exited with 1
    Unknown Failed to read the current pod state
  • However, the sequence of successive states a pod will be in during its lifecycle is represented as an array of PodConditions :

    pod condition usage
    PodScheduled Pod scheduled to a node by kube-scheduler
    PodReadyToStartContainers Pod execution environment and resources set up
    ContainersReady All pod containers are ready (image downloaded etc)
    Initialized All init containers exited with 0
    Ready Workload container started successfully
  • K8s handles container failures within pods using a restart policy defined in the PodSpec.

  • When a workload container exits, its wrapping pod will be restarted or marked for deletion depending on that configuration.

  • While kube-controller-manager can create new pods as existing pods are deleted, restarting containers in existing pods may provide faster recovery, resource efficiency, and operational simplicity.

  • Newly created replacement pods may not be scheduled to the same node as the original failed (or succeeded) pod.


Healthchecks

  • kubelet performs healthchecks on pods running on the current node using container probes.

  • Different types of probes exist that more or less match the pod's lifecycle phases.

  • A probe performs a check on a pod and results in an outcome of Success, Failure or Unknown :

    check action
    exec Runs a command inside the container, expects 0
    grpc Performs a gRPC call, expects status SERVING
    httpGet Sends a HTTP GET, expects status 200-399
    tcpSocket Expects specified TCP port to be open

Static pods

  • Static pods are pods directly managed by kubelet on a specific node and not by the control plane components.
  • They exist outside of the decisions made by kube-controller-manager and kube-scheduler.
  • kubelet will create mirror pods in the cluster state to provide observability for static pods through kube-apiserver.
  • The main use case for static pods is to run a self hosted control plane, noticeably when using kubeadm.