Initial commit.
This commit is contained in:
234
content/posts/kube-intro/index.md
Normal file
234
content/posts/kube-intro/index.md
Normal file
@ -0,0 +1,234 @@
|
||||
+++
|
||||
title = "Intro to kubernetes"
|
||||
weight = 0
|
||||
date = "2025-07-22"
|
||||
+++
|
||||
|
||||

|
||||
|
||||
### Problem in learning kubernetes
|
||||
|
||||
Lots of people are considering learning Kubernetes but are struggling to take the first
|
||||
steps because the official docs are complete dogshit for beginners.
|
||||
Don't get me wrong, the docs are great, but they serve a different purpose and are mostly used by experienced
|
||||
developers as a reference for things they are about to build or for explanations of
|
||||
some concepts that Kubernetes leverages.
|
||||
|
||||
Also official docs are mostly focus on how to deploy a big-ass production-ready system.
|
||||
Which is not something that you will target as a beginner. So instead I'm gonna show you how to deploy a single app.
|
||||
|
||||
Another problem is that people who don't use Kubernetes or are not familiar with all the problems it solves say that
|
||||
for medium and small projects, it is overkill.
|
||||
Which is actually complete bullshit as well.
|
||||
Because of the fact that Kubernetes automates a lot of things, it makes it easier to use than to not use it.
|
||||
And it is not that hard to start.
|
||||
|
||||
### What is Kubernetes? And how is better than Docker?
|
||||
|
||||
People that are aquite good with docker might ask, like `why should I care? Because I can run docker in cluster mode with docker-swarm!`
|
||||
Weeeeell, here's my response to you. The main problem with docker swarm is that it
|
||||
might run applications on multiple nodes, but nothing more than that.
|
||||
What about ingress management, automated certificate issuing, DNS updates, distributed volume provisioning? Docker swarm doesn't have it,
|
||||
and won't have unless they change their approach for declaring workloads. Kubernetes on the other hand is easily extendable, is adopted by big-tech companies and
|
||||
supported by a lot of cloud providers, which makes it a de-facto standard for container orchestration. Sad to admit,
|
||||
but docker swarm is silently dying from the day it was born.
|
||||
|
||||
### What's inside of Kubernetes?
|
||||
|
||||
Since I wanted to give high-level overview of Kubernetes, I won't go into details about each component,
|
||||
and networking, but I will give you a brief overview of the main components that make up Kubernetes.
|
||||
|
||||
* Container
|
||||
* Pod
|
||||
* Deployment
|
||||
* Service
|
||||
* Ingress
|
||||
* Namespace
|
||||
* Secret
|
||||
* ConfigMap
|
||||
|
||||
Now let's take a look at each of these components in more detail.
|
||||
|
||||
#### Container
|
||||
|
||||
Containers are not really something unique to Kubernetes. You might be familiar with containers from other systems
|
||||
like Docker. In context of kubernetes, containers are exactly same containers as they are in docker or containerd. Nothing brand new in here.
|
||||
|
||||
#### Pod
|
||||
|
||||

|
||||
Pods are the smallest deployable units in Kubernetes.
|
||||
It's a logically connected group of containers.
|
||||
|
||||
You can think of them as a virtual machines running some applications. And there are several reasons for that.
|
||||
First of all, pods share same network and you can go from one container to another using localhost.
|
||||
Also, you can attach volumes to pod and then share it to multiple containers.
|
||||
Which seems a lot like a virtual machine, right?
|
||||
|
||||
#### Deployment
|
||||
|
||||
Pods are cool, but there are some limitations to them. First of all, the pod objects are immutable, which means that you can't change them after they are created.
|
||||
|
||||
It might be a problem if you want to update your application, because you will have to delete the pod and create
|
||||
a new one. Also, scaling pods by yourself sounds weird. Of couese you can manually
|
||||
create [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/),
|
||||
but on average it's not something you would want to do.
|
||||
|
||||
So that's why we have [Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/).
|
||||
It allows you to describe a template for a pod and then Kubernetes will take care of creating, updating, and scaling pods for you. It will implicitly create a ReplicaSet for you, and will be maintaining it for you as well.
|
||||
|
||||
Deployment is a higher-level abstraction that allows you to manage pods more easily, scale them up and down, and update them without downtime.
|
||||
|
||||
There are some policies that you can set for deployments, like how many pods to keep running at the same
|
||||
time, update strategies, and so on.
|
||||
|
||||
Generally speaking, use deployments to manage your pods, and don't create pods directly unless you have
|
||||
a good reason to do so.
|
||||
|
||||
#### Service
|
||||
|
||||

|
||||
|
||||
[Service](https://kubernetes.io/docs/concepts/services-networking/service/) is a resource that allows you to set a single IP address and DNS name for a set of pods.
|
||||
|
||||
By default you can reach to service by it's name from the same namespace. But if you're in a different namespace, you can reach it by using domain name such as this:
|
||||
|
||||
`<service-name>.<namespace-name>.svc.cluster.local`.
|
||||
|
||||
You can think of services as a load balancer that distributes traffic to a set of pods.
|
||||
|
||||
#### Ingress
|
||||
|
||||

|
||||
|
||||
Ingress is a resource that allows you to expose your services to the outside world with a single IP address and DNS name.
|
||||
|
||||
You can think of it as a reverse proxy that routes traffic to different services based on the request path or host.
|
||||
In order to use ingress, you need to have an ingress controller running in your cluster.
|
||||
K3S by default has [Traefik](https://traefik.io/) ingress controller installed, which is a
|
||||
great choice for beginners. But for more control and features, I personally prefer to use [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/).
|
||||
|
||||
Ingress works this way: you create an ingress resource that defines the rules for
|
||||
routing traffic to different services, based on the request path or host.
|
||||
|
||||
Then the ingress controller will take care of routing the traffic to the appropriate service.
|
||||
|
||||
#### Namespace
|
||||
|
||||
I mentioned namespaces in the beginning, but I didn't explain what they are. Actually it's a very simple concept.
|
||||
It's a way to group resources in Kubernetes and manage access. Most of the time you can think of
|
||||
namespaces as just a way to organise resources in your cluster.
|
||||
|
||||
I prefer using different namespaces for different apps. For example my mailserver is deployed in namespace `mailserver`. But my blog is deployed in namespace `s3rius` for personal projects.
|
||||
|
||||
Telegram bots, CI/CD pipelines, and other applications that I deploy in my cluster are also deployed in their own namespaces. Which makes it easier to manage resources and access control.
|
||||
|
||||
About access control, you can use [Role-Based Access Control (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) to manage access to resources in a namespace. It will only be useful if you have multiple users or teams working in the same cluster.
|
||||
|
||||
You can create roles and role bindings to grant permissions to users or groups in a namespace. But I won't cover RBAC in this blog post. Just because it's too complex and we're only discussing basics.
|
||||
|
||||
#### ConfigMap and Secret
|
||||
|
||||
These two resources are used to store configuration data and sensitive information, respectively.
|
||||
For example, you can use ConfigMap to store environment variables, configuration files,
|
||||
or any other non-sensitive data that your application needs to run. And then mount them as
|
||||
files to your pod, or populate environment variables from it, etc.
|
||||
|
||||
In secrets you can store sensitive information like passwords, API keys, or any other data that
|
||||
you don't want to expose in plain text.
|
||||
But please keep in mind that by default k8s encodes all secrets using base64, which is completely insecure.
|
||||
To make secrets actually secret, you better use [Vault](https://developer.hashicorp.com/vault/docs/platform/k8s)
|
||||
or [External secrets operator](https://external-secrets.io/latest/) or something similar. But for now let's just use default base64 encoded secrets.
|
||||
|
||||
### How to deploy kubernetes
|
||||
|
||||
For local development you have several options:
|
||||
* [K3D](https://k3d.io/) - k3s in Docker.
|
||||
* [Minikube](https://minikube.sigs.k8s.io/docs/) - k8s in docker.
|
||||
* [Kind](https://kind.sigs.k8s.io/) - Kubernetes in Docker, but with a focus on testing Kubernetes itself.
|
||||
|
||||
For production:
|
||||
* [Kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) - raw and barebones way to deploy Kubernetes.
|
||||
* [Kubespray](https://kubespray.io/) - Ansible-based tool to deploy Kubernetes.
|
||||
* [K3S](https://k3s.io/) - Lightweight Kubernetes distribution that is easy to deploy and maintain.
|
||||
* [Rancher](https://rancher.com/) - A complete Kubernetes management platform
|
||||
* [DeckHouse](https://deckhouse.io/products/kubernetes-platform/gs/) - A complete Kubernetes management platform that is easy to deploy and maintain.
|
||||
|
||||
My personal recommendation is to use K3D for local development and K3S for production. For deploying K3S
|
||||
you can use [k3sup](https://github.com/alexellis/k3sup), which is a simple script that allows you to deploy K3S on any Linux server with a single command.
|
||||
|
||||
#### Learning environment
|
||||
|
||||
Let's use Docker-packed Kubernetes to start off. We're going to use [k3d](https://k3d.io) to spin up a cluster.
|
||||
It's an amazing tool that allows you to create a Kubernetes cluster and everything you need with a single command.
|
||||
Additionally, it spins up [k3s](https://k3s.io/) instead of Google's Kubernetes,
|
||||
which is a lightweight version of Kubernetes that is perfect for beginners.
|
||||
|
||||
It has all the features you need to get started and is much easier to set up than other distributions.
|
||||
I'm using this k3d configuration to create a cluster:
|
||||
|
||||
```yaml
|
||||
# yaml-language-server $schema=https://raw.githubusercontent.com/k3d-io/k3d/main/pkg/config/v1alpha5/schema.json
|
||||
apiVersion: k3d.io/v1alpha5
|
||||
kind: Simple
|
||||
metadata:
|
||||
name: default
|
||||
servers: 1
|
||||
volumes:
|
||||
- volume: /tmp/k3d-udev:/run/udev # For openebs
|
||||
ports:
|
||||
- port: 80:80 # HTTP ports mapping for cluster
|
||||
nodeFilters:
|
||||
- loadbalancer
|
||||
- port: 443:443 # HTTPS ports mapping for cluster.
|
||||
nodeFilters:
|
||||
- loadbalancer
|
||||
registries:
|
||||
create:
|
||||
name: registry.localhost # Registry for containers
|
||||
host: "0.0.0.0" # Host for registry
|
||||
hostPort: "5000" # Local port for registry
|
||||
```
|
||||
|
||||
With this configuration, you can create a cluster with a single command:
|
||||
```bash
|
||||
k3d cluster create --config "k3d.yaml"
|
||||
```
|
||||
|
||||
### Connecting to the cluster
|
||||
|
||||
After you install kubectl you should be able to locate file `~/.kube/config`. This file contains all required infomration to connect to clusters. Tools like minikube, k3d or kind will automatically update this file when you create a cluster.
|
||||
|
||||
Let's take a look at the contents of this file:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
preferences: {}
|
||||
# Here's list of clusters that you can connect to.
|
||||
# In this case we have only one cluster, which is k3d-default.
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: DATA+OMITTED
|
||||
server: https://0.0.0.0:44755
|
||||
name: k3d-default
|
||||
# Users is a list of users that you can use to connect to clusters.
|
||||
# Most of the time you will have each user for each cluster.
|
||||
# But in some cases you might have multiple users for the same cluster.
|
||||
users:
|
||||
- name: admin@k3d-default
|
||||
user:
|
||||
client-certificate-data: DATA+OMITTED
|
||||
client-key-data: DATA+OMITTED
|
||||
# Context is a combination of cluster and user that you can use to connect to a cluster.
|
||||
# You can create any combination of cluster and user,
|
||||
# but most of the time you will have only one context for each cluster.
|
||||
contexts:
|
||||
- context:
|
||||
cluster: k3d-default
|
||||
user: admin@k3d-default
|
||||
name: k3d-default
|
||||
# Currently selected context. It will be used as a default one
|
||||
# for all kubectl commands.
|
||||
current-context: k3d-default
|
||||
|
||||
```
|
Reference in New Issue
Block a user