Kubernetes

Kubernetes for Small Projects: a Practical Approach

Kubernetes for Small Projects

Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It has become a popular choice for running microservices-based applications in production, but it can also be a valuable tool for smaller projects.

Modern web app infrastructure has come a long way, evolving from just having a backend database on one server to using tons of different services spread across multiple virtual machines and servers. The shift to cloud solutions with load balancing and horizontal scaling capabilities was a big step, and then we got to microservices.

But managing a modern, microservice-based infrastructure comes with its own set of headaches because of the complex architecture and all the different components involved. The main pain points are:

  1. Collecting logs from all the services
  2. Gathering metrics
  3. Keeping an eye on the health of services and restarting them if issues pop up
  4. Automatically discovering new services as they get added
  5. Automating configuration updates when adding/removing service components
  6. Scaling up and down easily
  7. Continuously integrating code changes and deploying new versions seamlessly
  8. Not getting locked into a specific vendor’s solution, whether a cloud provider or bare metal servers.

Kubernetes emerged as a way to address all these operational needs in one comprehensive system.

Kubernetes Fundamentals

The Kubernetes architecture overall looks like a master (there can be more than one) and multiple nodes (up to 5,000), each of which has the following installed:

  • Docker
  • Kubelet (manages Docker)
  • Kube-proxy (manages iptables)

The master contains:

  • API server
  • etcd database
  • Scheduler (decides which node to run a container on)
  • Controller manager (responsible for fault tolerance)

In addition to all this, there is the kubectl management utility and configurations described in YAML format (declarative DSL).

The Kubernetes Architecture

From a usage perspective, Kubernetes offers a cloud that combines all these masters and nodes, allowing you to run the “building blocks” of infrastructure. These primitives include:

  • Container – an image + the command run in it
  • Pod (literally translated as “pod”) – a collection of containers (can be just one) with a shared network, one IP address, and other shared characteristics (shared data storage, labels); note: It is pods (not individual containers) that Kubernetes allows you to run
  • Label and Selector – a set of arbitrary key-value pairs assigned to pods and other Kubernetes primitives
  • ReplicaSet – a set of pods whose number is automatically maintained (when the number of pods in the configuration changes, when any pods/nodes fail), making scaling very simple
  • Deployment – ReplicaSet + history of old ReplicaSet versions + update process between versions (used for continuous integration and deployment tasks)
  • Service – DNS name + virtual IP + selector + load balancer (for distributing requests across pods matching the selector)
  • Job – a pod and the logic for determining its successful execution (used for migrations)
  • CronJob – Job and a cron schedule
  • Volume – attachment of data storage (to a pod, ReplicaSet or Deployment) with specified size, access type (ReadWriteOnce, ReadOnlyMany, ReadWriteMany), and storage type (19 implementation methods are supported: physical, software, cloud)
  • StatefulSet – similar to a ReplicaSet set of pods, but with strictly defined names/hosts so that these pods can always communicate with each other using them (for ReplicaSet, names are randomly generated each time) and have separate volumes (not one for all, as in the case of a ReplicaSet)
  • Ingress – a service accessible to external users that distributes all requests to services based on rules (depending on the hostname and/or URLs)

Examples of describing a pod and ReplicaSet in YAML format:

POD:

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

This YAML defines a pod named “my-nginx-pod” with a single container named “nginx”. The container uses the “nginx:latest” image and exposes port 80.

ReplicaSet:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-nginx-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

This YAML defines a ReplicaSet named “my-nginx-replicaset” that maintains 3 replicas of the pod defined above. The selector ensures that the ReplicaSet manages pods with the label “app: nginx”. The template specifies the pod configuration used to create the replicas.

These primitives address all of the challenges outlined above with a few minor exceptions: in the automation of configuration updates, the problem of building Docker images, ordering new servers, and installing nodes on them is not solved, and in CI/CD there remains the need for preparatory work (installing CI, describing rules for building Docker images, rolling out YAML configurations to Kubernetes).

Architecture and CI/CD

By small projects, we mean small (up to 50 nodes, up to 1500 pods) and medium (up to 500 nodes, up to 15000 pods) projects.

For the smallest bare metal projects, we use three hypervisors (bare metal projects refer to deployments where the software and infrastructure run directly on physical servers, without relying on virtualization or cloud providers).

Small bare metal project

The Ingress controller is installed on three virtual machines (kube-front-X).

The Ingress controller is installed on three virtual machines (kube-front-X).

Instead of the Pacemaker shown in the diagram, VRRP, ucarp, or other technology can be used, depending on the specific data center.

The Continuous Delivery pipeline looks like this:

Continuous Delivery
  • We use GitLab for continuous integration.
  • In Kubernetes, we set up environments for each tier (production, staging, testing, etc. – the number depends on the specific project). Different tiers can be served by different Kubernetes clusters (on different hardware and in different clouds), and deployment to them is configured in GitLab.
  • We put the Dockerfile (or rather, we use dapp for this) and the .kube directory with YAML configurations in Git.
  • On commit (build stage), we create a Docker image, which is pushed to the Docker Registry.
  • Next (test stage), we take this Docker image and run tests on it.
  • On release (release stage), the YAML configurations from the .kube directory are passed to the kubectl utility, which sends them to Kubernetes, after which Docker images are downloaded and launched in the infrastructure deployed according to the YAML configuration. Previously, we used Helm for this, but now we are finalizing our own dapp tool.
  • Thus, Kubernetes is fully responsible for the last (operate) stage.

For small projects, the infrastructure looks like a container cloud (its implementation is secondary – it depends on the available hardware and needs) with configured storage (Ceph, AWS, GCE…) and an Ingress controller, as well as (in addition to this cloud) possibly additional virtual machines for running services that we don’t deploy inside Kubernetes.

Conclusion

From our perspective, Kubernetes has matured enough to be used in projects of any size. Moreover, this system provides an excellent opportunity to build projects that are very simple, reliable, fault-tolerant, and horizontally scalable from the very beginning. The main challenge is the human factor: for a small team, it can be difficult to find a specialist who can handle all the necessary tasks (which requires broad technological expertise), or such a specialist may be too expensive (and may soon become bored working on the project).

If you need someone who knows how to work with Kubernetes, reach out to us at Gart. We have extensive experience working on Kubernetes projects.

Let’s work together!

See how we can help to overcome your challenges

FAQ

Why use Kubernetes for small projects?

Even for small projects, Kubernetes offers benefits like simplified application deployment, improved scalability, better resource utilization, and portability.

Is Kubernetes too complex for small projects?

While Kubernetes has a learning curve, its benefits often outweigh the initial effort. Numerous resources and lightweight distributions make it accessible for smaller teams.

What are some use cases for Kubernetes in small projects?

Deploying microservices-based applications Running batch jobs (data processing, ETL) Managing a personal website or blog Setting up development environments with multiple services

How can Kubernetes benefit microservices architectures?

Kubernetes promotes modular development, independent scaling, and fault tolerance for microservices.

Can Kubernetes be used for CI/CD in small projects?

Yes, Kubernetes integrates well with CI/CD pipelines, streamlining deployments and rollbacks.
arrow arrow

Thank you
for contacting us!

Please, check your email

arrow arrow

Thank you

You've been subscribed

We use cookies to enhance your browsing experience. By clicking "Accept," you consent to the use of cookies. To learn more, read our Privacy Policy