DEV Community

Cover image for Kubernetes Design
Barbara
Barbara

Posted on

Kubernetes Design

In this blogpost, you will get a crisp guide through the design concepts of Kubernetes. Let's go:

Decoupled resources

Each component should be decoupled from outer resources, so that every component can be removed, replaced or rebuilt.
Use Services for connections to other resources to provide flexibility.

Transience

Each object should be built with the expectation that other components will die and be rebuilt.
Having this in mind, we can update and scale with ease.

Flexible Framework

Multiple independent resources work together, but they are decoupled and do not expect a permanent relationship to other resources.
This framework of independent resources is not as efficient, as we have a lot of controllers or watch-loops in place to monitor the current cluster state and change things until the state matches the configuration.
But on the other hand, this framework allows us to have more flexibility, a very high availability and scalability.

Resource Usage

Kubernetes allows us to easily scale clusters and sets resource limits via configuration.

CPU

spec.containers[].resources.limits.cpu
spec.containers[].resources.requests.cpu
Enter fullscreen mode Exit fullscreen mode

1 CPU in K8s is equivalent to 1 AWS vCPU or 1GCP Core or 1 AzurevCore or 1 Hyperthread on a bare-metal Intel processor with Hyperthreading (eg to behave like multiple virtual cores).

RAM

spec.containers[].resources.limits.memory
spec.containers[].resources.requests.memory
Enter fullscreen mode Exit fullscreen mode

With Docker the limits.memory value is converted to an integer value to be used in the docker run --memory <value> <image> command.
If the container exceeds its memory limit, it may be restarted or the entire Pod could be evicted from the node.

Ephemeral Storage

Container files, logs can be stored there. If the containers use more than the limit in the Pod, the Pod will be evicted.

spec.containers[].resources.limits.ephemeral-storage
spec.containers[].resources.requests.ephemeral-storage
Enter fullscreen mode Exit fullscreen mode

Label Selectors

They provide a flexible and dynamic way to interact with your K8s cluster and help with the following points:

  • Resource Organization
  • Resource Identification
  • Selective Resource Access
  • Application Deployment
  • Scaling and Load Balancing
  • Rolling Updates and Rollbacks
  • Monitoring and Logging
  • Multi-Tenancy
  • Custom Workflows

Selectors are namespace scoped, you can add the --all-namespaces argument to select matching objects in all namespaces

kubectl get object-name -o yaml
kubectl get pod pod-name -o yaml

labels:
  app: sample
  pod-template-hash: 0815
Enter fullscreen mode Exit fullscreen mode

kubectl -n yourns get --selector app=your_pod

Multi-Container Pods

Having multiple containers allows independent development and scaling for every container to best meet the needs of the workload.
Every container in a POD shares a single IP address and namespace.
Each container has equal potential access to storage given to the Pod.

Different types of containers

Ambassador

Used to communicate outside resources, often outside a cluster. With this you don't need to implement a new service or a new entry to an ingress controller.

Adapter

is used to modify the data generated by the primary container. An example would be a datastream that needs to be modified for a usecase.

Sidecar

you can compare it to a sidecar on a motorcycle. It often provides services that are not found in the main application. For example a logging container. So it remains decoupled and scalable.

initContainer

An init container allows one or more containers to run only if one or more previous containers run and exit successfully.
For example a git-sync container would be an init container for another applications that needs to have always the latest information from a given git.

spec:
  containers:
   -name: app
    image: app-image
  initContainers:
  - name: git-sync
    image: git-sync-image
Enter fullscreen mode Exit fullscreen mode

CRD - Custom Resource Definition

With CRDs you can extend the K8s API and create custom resource.
With the help of a CRD you can add databases, message queues or machine learning models and many more and create custom schemas for your custom resource.
There are also public CRDs that can be used. For example Helm CRDs or the Prometheus Operator CRDs.

Job

It is a resource object to manage and run a task or a batch process. Jobs ensure that a given number of pods successfully completes.

Characteristics

  • One-Time Execution. For example a database migration or a backup
  • Parallelism. number of parallel pod completions
  • Pod Template. defines the container(s) to run
  • Completion and Failure Handling. can be defined via completions and backoffLimit. The backoffLimit defines the number of retries.
  • Garbage collection.

Sample of a job manifest.yaml in K8s

apiVersion: batch/v1
kind: Job
metadata:
  name: your-job
spec:
  completions: 3  # Number of desired completions
  parallelism: 1  # Number of pods running in parallel
  template:
    spec:
      containers:
      - name: your-container
        image: your-image
        command: ["echo", "Hello World!"]
  backoffLimit: 2  # Maximum number of retries in case of failure
Enter fullscreen mode Exit fullscreen mode

checklist to see if your design is good

[] The application is as decoupled as it can be
[] Nothing can be taken out of an existing container.
[] Every container is transient and is able to react properly when other containers are transient
[] Chaos Monkey can run without my users noticing it
[] Every component can be scaled to meet the workload

Further reading:
K8s CRD: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
Resource: https://training.linuxfoundation.org/training/kubernetes-for-developers/

Top comments (0)