ruk·si

☸️ Kubernetes
Pods

Updated at 2018-12-31 02:42

Kubernetes pod represents a running process on your cluster. Pod usually wraps a single container, but can also be a small group of tightly coupled containers that share resources on the same node.

Pod is the smallest deployable object in Kubernetes. You rarely create individual pods by hand, you use higher-level controllers to handle that.

But which controller to use to manage my pods?

  • Use Deployment controller for persistent services.
  • Use DaemonSet controller for background processes that should run on each node.
  • Use Job controller for batch workloads that are executed to termination.

Docker is the most common pod container runtime. Kubernetes pods do support other container runtimes as well.

Each pod is meant to run a single instance of a given application. Similar concept where you have one or multiple workers for your web application.

You scale with pod replication. To horizontally scale the behavior, you would add more pods of the same type to the cluster. This is referred as replication.

Replicated pods are usually managed as a group by an abstraction called a controller. Controller has desired state that it wants to maintain and replicating pods is one of the ways controller can drive towards the desired state.

Pods running on unreachable nodes are in Terminating or Unknown state.

You can control pod-to-node scheduling with node labels. Allows constrain a pod to only eligible to run on a subset of nodes.

Each pod is assigned a unique IP address. All containers in a pod also share the IP and ports. Containers in the pod can communicate using localhost.

Multi-container pods can use shared volumes for storage. Then restarting one container won't affect the volume.

Controllers use pod templates to create the actual pods. The pod templates used by common controllers are pretty much the same as creating a pod manually but you don't specify kind or apiVersion.

# apiVersion: v1
# kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
    - name: myapp-container
  image: busybox
  command: [ 'sh', '-c', 'echo Hello Kubernetes! && sleep 3600' ]

Pods don't self-heal or reallocate themselves. Controllers handle that behavior, pod only controls the containers inside of it.

restartPolicy: Always|OnFailure|Never tells should a pod restart its containers. Always is the default.

Pods maintain no reference to the templates they were created from. Changes to the template or replacing the template doesn't affect already started pods. You need to either modify the higher level controller that is currently managing the pod, or the pod definition itself.

Containers in separate pods communicate with pod IP and DNS addresses. These are internal to the cluster.

Default grace period for pod deletion is 30 seconds. Grace period gives time to pod to quit safely and other services such as load balancer to remove the pod from the fleet. kubelet notices the status change and triggers preStop hook.

Pod status field is an instance of PodStatus.

  • status.phase:
    • pending: pod has been accepted and is preparing e.g. downloading the images
    • running: pod has been assigned to a node and all the containers are running
    • succeeded: all pod containers have terminated in success
    • failed: all pod containers have terminated, and at least one of them was fail
    • unknown: pod status could not be obtained, most likely an issue with the node
  • status.conditions
    • array of type and status pairs

You can define probes to customize health checks of your pods:

  • Define liveness probe to customize when the pod is considered to be alive.
  • Define readiness probe to customize when to send traffic to the pod.

Example liveness proble:

apiVersion: v1
kind: Pod
metadata:
  labels:
  test: liveness
  name: liveness-http
spec:
  containers:
    args:
      - /server
    image: k8s.gcr.io/liveness
  livenessProbe:
    httpGet:
    # when "host" is not defined, "PodIP" will be used
    # host: my-host
    # when "scheme" is not defined, "HTTP" scheme will be used.
    # Only "HTTP" and "HTTPS" are allowed
    # scheme: HTTPS
    path: /healthz
    port: 8080
    httpHeaders:
      - name: X-Custom-Header
        value: Awesome
    initialDelaySeconds: 15
    timeoutSeconds: 1
  name: liveness

Sources