Marcin Jahn | Dev Notebook
  • Home
  • Programming
  • Technologies
  • Projects
  • About
  • Home
  • Programming
  • Technologies
  • Projects
  • About
  • An icon of the Networking section Networking
    • HTTP Protocol
    • OSI Model
    • TCP Procol
    • UDP Protocol
    • WebSocket
    • HSTS
    • DNS
    • Server Name Indication
    • gRPC
  • An icon of the Security section Security
    • OAuth2
      • Sender Constraint
    • Cryptography
      • Cryptography Basics
    • TPM
      • Overiew
      • TPM Entities
      • TPM Operations
  • An icon of the Linux section Linux
    • Gist of Linux Tooling
    • Unknown
    • SELinux
    • Containers
    • Bash Scripting
    • Linux From Scratch
    • Networking
  • An icon of the Kubernetes section Kubernetes
    • Meaning and Purpose
    • Cluster
    • Dev Environment
    • Kubernetes API
    • Objects
    • Pods
    • Scaling
    • Events
    • Storage
    • Configuration
    • Organizing Objects
    • Services
    • Ingress
    • Helm
  • An icon of the Observability section Observability
    • Tracing
  • An icon of the Databases section Databases
    • ACID
    • Glossary
    • Index
    • B-Tree and B+Tree
    • Partitioning and Sharding
    • Concurrency
    • Database Tips
  • An icon of the SQL Server section SQL Server
    • Overview
    • T-SQL
  • An icon of the MongoDB section MongoDB
    • NoSQL Overview
    • MongoDB Overview
    • CRUD
    • Free Text Search
  • An icon of the Elasticsearch section Elasticsearch
    • Overview
  • An icon of the Git section Git
    • Git
  • An icon of the Ansible section Ansible
    • Ansible
  • An icon of the Azure section Azure
    • Table Storage
    • Microsoft Identity
  • An icon of the Google Cloud section Google Cloud
    • Overview
  • An icon of the Blockchain section Blockchain
    • Overview
    • Smart Contracts
    • Solidity
    • Dapps
  • Home Assistant
    • Home Assistant Tips
  • An icon of the Networking section Networking
    • HTTP Protocol
    • OSI Model
    • TCP Procol
    • UDP Protocol
    • WebSocket
    • HSTS
    • DNS
    • Server Name Indication
    • gRPC
  • An icon of the Security section Security
    • OAuth2
      • Sender Constraint
    • Cryptography
      • Cryptography Basics
    • TPM
      • Overiew
      • TPM Entities
      • TPM Operations
  • An icon of the Linux section Linux
    • Gist of Linux Tooling
    • Unknown
    • SELinux
    • Containers
    • Bash Scripting
    • Linux From Scratch
    • Networking
  • An icon of the Kubernetes section Kubernetes
    • Meaning and Purpose
    • Cluster
    • Dev Environment
    • Kubernetes API
    • Objects
    • Pods
    • Scaling
    • Events
    • Storage
    • Configuration
    • Organizing Objects
    • Services
    • Ingress
    • Helm
  • An icon of the Observability section Observability
    • Tracing
  • An icon of the Databases section Databases
    • ACID
    • Glossary
    • Index
    • B-Tree and B+Tree
    • Partitioning and Sharding
    • Concurrency
    • Database Tips
  • An icon of the SQL Server section SQL Server
    • Overview
    • T-SQL
  • An icon of the MongoDB section MongoDB
    • NoSQL Overview
    • MongoDB Overview
    • CRUD
    • Free Text Search
  • An icon of the Elasticsearch section Elasticsearch
    • Overview
  • An icon of the Git section Git
    • Git
  • An icon of the Ansible section Ansible
    • Ansible
  • An icon of the Azure section Azure
    • Table Storage
    • Microsoft Identity
  • An icon of the Google Cloud section Google Cloud
    • Overview
  • An icon of the Blockchain section Blockchain
    • Overview
    • Smart Contracts
    • Solidity
    • Dapps
  • Home Assistant
    • Home Assistant Tips

Pods

Each pod has its own IP, hostname, processes, network interfaces and other resources.

A pod contains one or more containers. These containers share a node and some Linux namespaces (it’s configurable, e.g. pod’s containers by default do not share PID namespace).

Sharing network namespaces by pod’s containers:

It makes sense to have multiple containers in a pod if these containers need to work together closely. The example below shows a web app and a sidecar container providing TLS support:

Other examples:

  • some web API container and a separate container that prepares data for that API (in some common storage)
  • Istio service mesh
  • Dapr

Containers in a single pod are scaled together.

Networking

All pods can talk to each other, and they are reachable from any node. Pods may define the ports they use in YAML, but they do not have to. It’s only informative (and it gives the possibility to name the ports, which is useful when creating Services for them).

Checking if the pod accepts requests:

  • SSH into any node, and try to curl the IP address of a pod

  • create another Pod, get into it, and curl the other pod from it

  • k port-forward <pod-name> <pod-port> - it’s the easiest thing to do, but the most complex under the hood. It can also be used with Services.

Logs

k logs <pod> - displays pod logs

Options:

  • -f for follow
  • --timestamps for timestamps
  • -p - logs from the previous instance of the pod (if died)

Deleting a pod deletes the logs as well. Logs are kept in /var/log/containers on the nodes.

Accessing Pods

  • k cp kiada:html/index.html /tmp/index.html - copying files to/from containers
  • k exec <pod> -- ps aux - execute a command in a pod (-it for interactive)
  • k attach - attaches to stdin, stderr, stdin (useful if pod’s container expects input). If stdin is not needed, it is not different than k logs -f
  • ephemeral containers - currently in Alpha

Init Containers

A pod can have init container(s) specified. They start before the “main” container(s), finish successfully and only then do the “main” container(s) start.

“Main” containers run in parallel. Init containers run consecutively (1 at a time).

Some use cases:

  • prepare some files on a volume for the main container
  • configure some networking
  • delay container start until some condition is met
  • notify some external service that the pod is starting

Init containers should work in an idempotent way.

Lifecycle

Pod’s conditions (a part of “status”):

  • PodScheduled - pod scheduled to a worker node
  • Initialized
  • ContainersReady
  • Ready

Restart policies of pods:

  • Always
  • OnFailure - only non-zero exit code causes a restart
  • Never

These policies can be defined only on the pod level, not on the container level.

When a container dies and gets restarted, there is a varying delay before the container starts:

The first time is immediate, then it grows exponentially up to 5 minutes. This behavior is reset if the container has run successfully for at least 10 minutes.

Resources

Processes need resources like CPU and memory to run. Pods are no different. In Kubernetes, we can specify for each pod:

  • guaranteed CPU share (requests)
  • limit of CPU usage (limit)
  • guaranteed memory share (requests)
  • limit of memory usage (limit)

The commonly repeated wisdom is to:

  • always assign CPU requests
  • never assign CPU limits
  • always assigning memory request equal to memory limit

Probes

Liveness Probe

K8s automatically restarts a container that crashes. However, there are situations when the app does not terminate but is unhealthy (i.e., in a deadlock).

Liveness probe may be defined for every container in a pod. It is checked periodically. If the container does not respond, it is considered unhealthy and is terminated (and restarted). They cannot be used with init containers.

Types:

  • HTTP GET - response code between 200-399 is considered successful
  • TCP socket - just a TCP connection is attempted
  • Exec - executes a command inside of the container and checks the exit code

Additional configurable parameters:

K8s does not mention anywhere that the probe is successful. It could be logged by a tested container by an app running on it.

When the probe fails, K8s tries to terminate the app gracefully (with TERM). If that fails, it kills is forcefully (kill -9).

Readiness Probe

It is used to check if the pod is ready to accept requests. Like Liveness Probe supports three types.

Containers without Readiness probes are considered Ready as soon as they are started.

If the Readiness Probe fails, a pod is removed from Endpoints object of a service. It is not restarted, like with the Liveness Probe.

Startup Probe

Additional probe - Startup Probe may be added if the app is known to start long. Then, a separate configuration is used to check app health during startup. We might define how long it should take for the app to start responding to health checks. It’s perfectly normal for the Startup probe to fail a couple of times initially. A successful Startup probe indicates that K8s should switch to the Liveness probe. It is usually executed at short intervals making sure the app is alive.

Only after Complete Startup the container becomes Ready (via the Readiness Probe).

Usually, both probes use the same endpoint, but they can be different (or even use different types).

Hooks

There are two hooks:

  • post-start - run immediately after the container is started parallelly to it
  • pre-stop

They are specified per container.

Init containers are similar to post-start hooks, but they’re defined per pod.

They can be defined as HTTP GET, or as “exec” (just like probes). “tcpSocket” is not supported.

A container is in the “Pending” state until post-start is completed. Logs also cannot be seen even though the container is already running. If the hook fails, the container is restarted.

The post-start HTTP hook should not be used if we want to target the same container with it (or the same pod in general). It could happen that the hook will be executed before the webserver is started in the container. It will cause a restart since the HTTP request will fail. We end up in a restart loop. HTTP hook is good for notifying some other apps about the container starting.

The pre-stop hook is not invoked if the app terminates by itself.

Termination

If the pod is to be killed, a TERM signal is sent to it. By default, 30s is given for the container to shut down gracefully. It can be changed with the terminationGracePeriodSeconds setting in spec. If the time passes and the container still lives, KILL is sent to it.

Resources

  • Stop Using CPU Limits
←  Objects
Scaling  →
© 2023 Marcin Jahn | Dev Notebook | All Rights Reserved. | Built with Astro.