diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..364fdec --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +public/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5efe62d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM ghcr.io/getzola/zola:v0.17.1 AS zola + +COPY . /project +WORKDIR /project +RUN ["zola", "build"] + +FROM nginx:1.29.0-alpine + +COPY --from=zola /project/public /usr/share/nginx/html diff --git a/config.toml b/config.toml index e5890cf..063288b 100644 --- a/config.toml +++ b/config.toml @@ -21,7 +21,7 @@ footer_copyright = ' · + + +
Request
K8S cluster
Service
10.43.0.11
Pod1
10.42.10.1
Pod2
10.42.10.2
Pod3
10.42.10.3
Service
10.43.0.12
Pod1
10.42.11.1
Pod2
10.42.11.2
Pod3
10.42.11.3
\ No newline at end of file diff --git a/content/posts/kube-intro/imgs/intro.png b/content/posts/kube-intro/imgs/intro.png new file mode 100644 index 0000000..a8aa8cb Binary files /dev/null and b/content/posts/kube-intro/imgs/intro.png differ diff --git a/content/posts/kube-intro/imgs/pods.svg b/content/posts/kube-intro/imgs/pods.svg new file mode 100644 index 0000000..b3bfcda --- /dev/null +++ b/content/posts/kube-intro/imgs/pods.svg @@ -0,0 +1,486 @@ + + + + + + + + + + + + + + + + + + + + + + + Docker + + Kubelt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/posts/kube-intro/imgs/services.svg b/content/posts/kube-intro/imgs/services.svg new file mode 100644 index 0000000..7cf3867 --- /dev/null +++ b/content/posts/kube-intro/imgs/services.svg @@ -0,0 +1,4 @@ + + + +
Service
10.43.0.10
Pod1
10.42.10.1
Pod2
10.42.10.2
Pod3
10.42.10.3
\ No newline at end of file diff --git a/content/posts/kube-intro/index.md b/content/posts/kube-intro/index.md new file mode 100644 index 0000000..5064f2a --- /dev/null +++ b/content/posts/kube-intro/index.md @@ -0,0 +1,234 @@ ++++ +title = "Intro to kubernetes" +weight = 0 +date = "2025-07-22" ++++ + +![Intro](./imgs/intro.png) + +### 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 + +![Pod](./imgs/pods.svg) +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](./imgs/services.svg) + +[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: + +`..svc.cluster.local`. + +You can think of services as a load balancer that distributes traffic to a set of pods. + +#### Ingress + +![Ingress](./imgs/ingress.svg) + +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 + +``` diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png new file mode 100644 index 0000000..72c827a Binary files /dev/null and b/static/android-chrome-192x192.png differ diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png new file mode 100644 index 0000000..c53bb77 Binary files /dev/null and b/static/android-chrome-512x512.png differ diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png new file mode 100644 index 0000000..6806385 Binary files /dev/null and b/static/apple-touch-icon.png differ diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png new file mode 100644 index 0000000..11b6b41 Binary files /dev/null and b/static/favicon-16x16.png differ diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png new file mode 100644 index 0000000..4785570 Binary files /dev/null and b/static/favicon-32x32.png differ diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..0f16250 Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/site.webmanifest b/static/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/static/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file