Курс по Kubernetes с kind — разгърни, настрой, мащабирай и защити услуга на собствената си машина
Контейнери и облакСредно ниво
От Dorian Chávez · основател и главен изпълнителен директор на Hábil. Така обучаваме тези, които изграждат системи, които не могат да се провалят.
За кого е: за този, който вече е минал курса по Docker от същата поредица, или който пакетира услуги в контейнери с лекота: изграждаш образи, пускаш ги, даваш им томове и ги стартираш заедно с Compose. Средно ниво. Не се предполага да си пипал Kubernetes, нито да имаш клъстер: курсът ти дава един, локален, който се създава и се унищожава за минути. Всяко понятие се обяснява, когато се появи, и се обяснява защо съществува, а не само как се пише.
Какво ще знаеш в края: да разгърнеш услуга в клъстер на Kubernetes и да я управляваш —да я конфигурираш, да я наблюдаваш, да я публикуваш, да я ограничаваш, да ѝ пазиш данните, да я мащабираш и да я обновяваш, като измерваш всяко прекъсване—; да четеш какво ти казва клъстерът, когато нещо се провали (Pending, ImagePullBackOff, CrashLoopBackOff), вместо да триеш и да опитваш пак; и да обясниш, без украси, какво е разстоянието между твоя локален клъстер и един продукционен.
Откъде идва: този курс продължава този по Docker от същата поредица и използва като отправна точка неговия завършен образ на revisor. Ако не си минал онзи курс, ти трябва образ на HTTP услуга, която умее да казва дали е жива и която работи без да е root; Урок 2 ти казва точно на какво трябва да отговаря.
Какво ти трябва, преди да започнеш: компютър с Linux Mint 22.x, работещ Docker Engine и администраторски права (sudo). Урок 1 инсталира kubectl и kind и създава клъстера.
Проектът, който ще изградиш
revisor: HTTP сървърът, който проверява едновременно списък от услуги и връща своя отчет, същият като в курсовете по Go, Rust, TypeScript и Docker от същата поредица; неговият сървър е написан на Go и слуша на порт 8080 (GET /salud, GET /api/estados, конфигурация чрез променливи на средата, подкоманда healthcheck). Тук вече не го програмираш и не го пакетираш: караш го да живее в клъстер. Разгръщаш го с няколко реплики, правиш го откриваем по име, конфигурираш го без да изграждаш образа наново, учиш клъстера да го наблюдава, публикуваш го навън, изолираш го с минимални права и затворена мрежа, даваш му място, където да пази отчета си, превръщаш го в планирана задача и го караш да се мащабира според натоварването. В края всичко се разгръща с два kubectl apply -k —платформата и проекта— и изчакване между тях.
Придружен е от тестовата услуга, която се проваля нарочно от курса по Docker (здрава, бавна или паднала), защото един клъстер се разбира наистина, когато нещо се счупи и видиш какво прави.
Единайсетте урока
| Урок | Какво изграждаш | Какво научаваш | |
|---|---|---|---|
| 0 | Какво е Kubernetes и какво НЕ е kind | засега нищо (четене) | контролната равнина и възлите; да декларираш желаното състояние и да оставиш клъстера да го достигне; картата от Docker към Kubernetes; какво може да се тества с kind и какво не |
| 1 | Инсталиране на kubectl и kind; първият ти клъстер | клъстерът на курса: един контролен възел и два работни | kubectl и kind с фиксирана версия и контролна сума; настройката на inotify; контексти и kubeconfig; създаване, разглеждане, изтриване и пресъздаване |
| 2 | Pods и Deployments | работещият revisor, с реплики, които се раждат наново |
kind load docker-image; ErrImagePull, който се предизвиква нарочно; Pod, ReplicaSet и Deployment; етикети; rollout; securityContext от първия манифест |
| 3 | Services и DNS | revisor, откриваем по име |
ClusterIP; селектори и EndpointSlice; port, targetPort и containerPort; DNS на клъстера; port-forward; един Pod за отстраняване на грешки |
| 4 | Конфигурация и тайни | revisor, конфигуриран без повторно изграждане |
ConfigMap като променливи на средата (revisor чете само променливи) и Secret като файл, и защо base64 не е шифроване; Kustomize с генератори и хешът (hash), който задейства rollout |
| 5 | Проверки на състоянието, ресурси и подредено изключване | revisor, който клъстерът умее да наблюдава |
проби (probes) за стартиране (startup), готовност (readiness) и жизненост (liveness); защо /salud не пита никого; requests и limits; OOMKilled и Pending нарочно; срокът за изключване |
| 6 | Влизане в клъстера | revisor, публикуван навън |
LoadBalancer с MetalLB и Gateway API с Envoy Gateway, инсталирани вътре в клъстера; защо не Cloud Provider KIND на споделена машина (действа върху всички клъстери на kind); Ingress като замразен API; защо не ingress-nginx; какво се излага и откъде |
| 7 | Изолиране: пространства, права и мрежа | собствено пространство от имена с правила | Namespace; Pod Security Admission на ниво restricted; ServiceAccount и минимален RBAC с auth can-i; NetworkPolicy „всичко затворено“ и нейните отваряния (измерва се, че kindnet, CNI на kind, ги прилага; не е нужно да се инсталира друг) |
| 8 | Данни и задачи | запазеният отчет и revisor като планирана задача |
PersistentVolumeClaim и класът за съхранение на kind; Job и CronJob; собственикът на файловете с fsGroup; какво се губи при изтриване на Pod |
| 9 | Мащабиране и обновяване с измерване на всяко прекъсване | revisor, който вдига и сваля реплики според натоварването |
metrics-server; HorizontalPodAutoscaler и неговата формула; прозорецът за сваляне; разпределение с topologySpreadConstraints; RollingUpdate и preStop, измерени със сондиране; rollout undo; PodDisruptionBudget и drain; прозорецът на паднал възел |
| 10 | Завършеният проект и какво се променя в истински клъстер | всичко с два kubectl apply -k (платформа и проект) и изчакване |
Kustomize с база и слоеве (overlays); преглед спрямо нивото restricted; Helm, само споменат; какво не му достига на това, за да бъде продукция |
В края на всеки урок има упражнения с решенията им. А дневникът е твой: записвай в него какво ти е струвало усилия.
Три принципа, които минават през целия курс
Сигурността не е урок, а навик. Урок 7 събира права, пространства и мрежа, защото там те се изучават сами по себе си, но останалата част от курса ги прилага на практика още от първия манифест:
| Урок | Навикът, който се изгражда |
|---|---|
| 0 | да знаеш какво защитава един локален клъстер и какво не |
| 1 | двоични файлове с контролна сума; фиксиран образ на възела; проверка на контекста преди всяка команда, която променя нещо |
| 2 | securityContext в първия Deployment: без root, без повишаване на привилегии, без правомощия (capabilities), файлова система само за четене, профил seccomp |
| 3 | по подразбиране ClusterIP; нищо не се публикува просто така; port-forward само към 127.0.0.1 |
| 4 | един Secret не е шифроване: не се версионира, монтира се като файл и се отбелязва като неизменяем |
| 5 | requests и limits във всеки контейнер; пробите (probes) не зависят от външни услуги |
| 6 | излага се минимумът, през именувана входна точка, и се казва какво липсва (шифроване при пренос) |
| 7 | собствено пространство, ниво restricted, минимални права, затворена по подразбиране мрежа |
| 8 | ServiceAccount без монтирани удостоверения, ако не се нуждае от тях; данните със своя собственик |
| 9 | граници при мащабирането; обновяванията поддържат услугата работеща, като малкото откази са измерени и обяснени |
| 10 | финален преглед спрямо нивото restricted и списъка с онова, което един истински клъстер изисква |
Чете се, преди да се трие. Когато нещо не стартира, рефлексът на начинаещия е да го изтрие и да го приложи отново. Тук рефлексът е друг: describe, logs, get events. Всеки урок нарочно предизвиква типичен срив и те учи на реда, по който се чете, защото този ред е занаятът.
Преподава се само актуалното, а онова, което е премахнато, се назовава, за да го разпознаеш. Поддръжката на ingress-nginx беше прекратена през март 2026 г., а уроците отпреди две години все още го преподават; Ingress е замразен API, а Gateway API е неговият наследник. Курсът казва кое какво е. И всяка версия се дава с датата ѝ: тези в този курс са измерени на 7 октомври 2026 г. (Kubernetes 1.37.1; kind v0.33.0, чийто възел по подразбиране е 1.37.0). Онова, което зависи от външна част (MetalLB, Envoy Gateway, прилагането на NetworkPolicy, metrics-server в kind), се проверява на живо при писането на всеки урок и не се твърди предварително.
Как разбираш, че си приключил
Курсът не свършва, когато си прочел урок 10, а когато проектът ти изпълнява тези седем неща. Те са проектни цели: измерват се и се прецизират при писането на уроците, а всеки урок повтаря своята вече измерена.
- В току-що създаден клъстер
revisorзаработва с три стъпки, винаги в един и същ ред:kubectl apply -kза платформата (MetalLB и Envoy Gateway, с техните CRD),kubectl wait, докато тя е готова, иkubectl apply -kна проекта. Редът има значение, защото CRD и webhook-ите трябва да съществуват преди ресурсите, които ги използват. Аkind delete cluster, последван от същите три стъпки, го изгражда наново, без да поправяш нищо ръчно. - Пространството от имена на
revisorе на нивоrestrictedна Pod Security Admission и не получава нито едно предупреждение при прилагане. - Спираш контейнера на един работен възел (
docker stop) и услугата продължава да отговаря чрез репликата на другия възел, с измерен прозорец: в продължение на десетки секунди —времето, за което клъстерът обявява възела за изгубен (node-monitor-grace-period, 50 s по подразбиране): в четирите кръга на урок 10 услугата отговори отново от 34 до 51 s след спирането на възела, а в урок 9 възелът премина вNotReadyна 57-ата секунда— заявките, които попаднат на мъртвата реплика, се провалят (измерено в един кръг, с 2 реплики: 7 от 42 заявки се провалиха, а последният срив беше 53 s след спирането). Можеш да кажеш какво скъсява или смекчава този прозорец (повече разпределени реплики, повторни опити в клиента, по-кратък срок за откриване в контролната равнина) и какво не (пробите, които се изпълняват от самия паднал възел, нитоtolerationSeconds, който решава само кога се заменят Pod-овете). А обновяване сpreStopнамалява прекъсванията, но не гарантира нула: в четири кръга измери 0, 4, 0 и 1 неуспеха, общо 5 от 2 049 заявки, срещу 29 от 1 569 безpreStopв три кръга (измерено отвътре на клъстера, през Service иkube-proxy, не през входната врата; с четири нишкиcurlна споделена машина и без редуване на кръговете). Когато стартираш възела отново, клъстерът се възстановява сам. - Променяш списъка с услуги в
ConfigMapи клъстерът извършва rollout сам, без да изграждаш образа наново. - Под натоварване
kubectl get hpa --watchпоказва как репликите се покачват, а минути по-късно спадат, и можеш да обясниш защо спадането отнема толкова време, колкото отнема. - Външен за
revisorPod не може да говори с него (NetworkPolicyго спира; цел, която зависи от това клъстерът да я прилага) и сервизният акаунт наrevisorне може да прави нищо, от което не се нуждае (kubectl auth can-iти го доказва). - Можеш да изброиш писмено пет причини, поради които онова, което си изградил, не е продукция, и какво би се направило за всяка от тях в един истински клъстер.
Уроци
- Урок 0 — Какво е Kubernetes и какво НЕ е kind
- Урок 1 — Инсталиране на kubectl и kind; първият ти клъстер
- Урок 2 — Pods и Deployments
- Урок 3 — Services и DNS
- Урок 4 — Конфигурация и тайни
- Урок 5 — Проверки на състоянието, ресурси и подредено изключване
- Урок 6 — Влизане в клъстера
- Урок 7 — Изолиране: пространства, права и мрежа
- Урок 8 — Данни и задачи
- Урок 9 — Мащабиране и обновяване с измерване на всяко прекъсване
- Урок 10 — Завършеният проект и какво се променя в истински клъстер