Устройство Kubernetes и безопасная лаборатория
Начни с простых понятий, открой терминал на портале и шаг за шагом посмотри, как Kubernetes запускает приложение и восстанавливает удалённый Pod.
Ещё не начатЛаборатория уже готова к работе
Оставь этот урок открытым, а практикум открой в соседней вкладке. На портале есть терминал, подготовка задания, автоматическая проверка и журнал. Нужен вход через GitLab.
Открыть лабораторную в соседней вкладке ↗Маршрут: объяснения ниже → пошаговая лабораторная → тест на понимание.
Сокращения этого модуля: расшифровки и смысл
- API
- Application Programming Interface — программный интерфейс
- DNS
- Domain Name System — система доменных имён
- HTTP
- Hypertext Transfer Protocol — протокол передачи веб-данных
- SSH
- Secure Shell — протокол защищённого удалённого доступа
- UID
- Unique Identifier — уникальный идентификатор
- YAML
- YAML Ain’t Markup Language — язык описания данных
В командах сохраняется точное написание параметров и имён. В тексте сокращения раскрываются в скобках.
Результат модуля
- Объяснить своими словами, чем отличаются контейнер, Pod, нода и кластер.
- Понять, кто принимает команды, выбирает ноду и запускает контейнер.
- Через терминал портала исправить учебное приложение и увидеть восстановление Pod.
- Сохранить наблюдения в журнале и получить автоматическую проверку лабораторной.
1. С чего начинаем: приложение и контейнер
Представь маленький сайт, который должен постоянно отвечать на запросы. Его нужно запустить, а если процесс завершится — вернуть в работу. Если пользователей станет больше, понадобятся несколько копий приложения. Kubernetes помогает управлять таким запуском на серверах.
Контейнер — запущенная программа в изолированном окружении. Образ контейнера — подготовленный набор файлов, из которого её запускают. Это разные вещи: из одного образа можно запустить несколько контейнеров. В нашей лабораторной уже выбран маленький образ BusyBox с простым сервером HTTP (Hypertext Transfer Protocol — протокол передачи веб-данных) — программой, которая отдаёт веб-страницу по запросу.
Kubernetes обычно не управляет отдельным контейнером напрямую. Он создаёт Pod — объект, внутри которого запускаются один или несколько контейнеров. В нашем упражнении в каждом Pod ровно один контейнер с веб-сервером. Пока представляй Pod как один экземпляр нашего приложения.
Чтобы выполнить этот модуль, достаточно браузера. Терминал уже встроен в портал, а kubectl — программа для работы с Kubernetes — установлен на стенде. Устанавливать Docker, kind, kubectl или создавать новый кластер для этой работы не нужно.
Сначала прочитай объяснения ниже, затем выполняй лабораторную по одному шагу. Не старайся сразу запомнить все английские слова: после каждой команды связывай новое слово с объектом, который увидел на экране.
- Образ — из чего запускают программу.
- Контейнер — запущенная программа.
- Pod — объект Kubernetes, в котором работают контейнеры. В этой работе один Pod содержит один контейнер.
2. Кто работает внутри Kubernetes
Кластер — группа машин, которыми Kubernetes управляет как одной системой. Отдельная машина называется нода, или Node. Это может быть физический сервер или виртуальная машина.
У кластера есть управляющая часть — control plane — и ноды, на которых запускаются приложения. На нашем стенде управляющая нода называется ubuntu, её адрес 192.168.0.12. Учебные Pod запускаются на рабочей ноде ubuntuworker. Терминал портала подключается к первой машине, но это не означает, что само учебное приложение работает на ней.
API (Application Programming Interface — программный интерфейс) — интерфейс, через который программы читают и меняют объекты Kubernetes. Когда ты вводишь команду kubectl, она обращается к API server — точке входа в Kubernetes. API server проверяет запрос и права пользователя. Принятое состояние объектов сохраняется в etcd. В таблице ниже — роли остальных участников.
Например, ты просишь две копии сайта. Контроллеры создают нужные объекты, scheduler выбирает ноды для ещё не назначенных Pod, а kubelet на выбранной ноде организует запуск контейнеров через среду выполнения, например containerd. Компоненты обмениваются состоянием через API (Application Programming Interface — программный интерфейс); это не одна программа, которая выполняет все действия подряд.
Поэтому ответ на команду и готовый сайт появляются не обязательно одновременно. Запрос могли принять, но контейнер ещё загружается или приложение ещё не готово. Дальше мы научимся проверять именно результат.
- API (Application Programming Interface — программный интерфейс) server
- Принимает запросы kubectl и других компонентов, проверяет доступ и работает с объектами API (Application Programming Interface — программный интерфейс).
- etcd
- Хранит состояние объектов API (Application Programming Interface — программный интерфейс). Здесь записано, какие объекты созданы и что о них известно; это не хранилище всех файлов приложения.
- Контроллер
- Сравнивает нужное и текущее состояние и старается устранить разницу. Например, замечает, что не хватает одного Pod.
- Scheduler
- Выбирает подходящую ноду для Pod, которому нода ещё не назначена.
- Kubelet
- Работает на каждой ноде: следит за назначенными ей Pod и взаимодействует со средой выполнения контейнеров.
- Среда выполнения контейнеров
- Непосредственно запускает и останавливает контейнеры на ноде. Один из вариантов — containerd.
По шагам
- Ты задаёшь желаемое число копий приложения.
- API (Application Programming Interface — программный интерфейс) server принимает запрос и сохраняет состояние через etcd.
- Контроллеры создают недостающие объекты Pod.
- Scheduler назначает новым Pod ноду.
- Kubelet и среда выполнения запускают контейнеры на этой ноде.
- Проверки готовности показывают, можно ли направлять запросы приложению.
3. Что мы просим и что получилось
Объект Kubernetes — запись с именем, настройками и текущим состоянием. Например, объект Deployment описывает, как запускать и обновлять копии нашего приложения. Слово реплика означает одну такую копию.
У объекта есть spec — что должно быть, и status — что Kubernetes наблюдает сейчас. Если в spec.replicas указано 2, мы попросили две реплики. Если status.readyReplicas пока равно 1, готова только одна. Нужно выяснить причину или дождаться завершения запуска.
Deployment управляет объектом ReplicaSet. ReplicaSet поддерживает нужное число Pod. Для первого знакомства запомни связь: Deployment → ReplicaSet → Pod → контейнер. Когда мы меняем число реплик Deployment, Kubernetes сам создаёт или убирает Pod.
Параметры объектов можно описать в текстовом файле YAML (YAML Ain’t Markup Language — язык описания данных) — такой файл называют манифестом. Команда kubectl apply отправляет настройки из файла в API (Application Programming Interface — программный интерфейс). В этом модуле готовые объекты создаёт кнопка портала; писать свой манифест с нуля пока не требуется.
Сообщение о принятом изменении означает, что запрос обработан. Оно ещё не доказывает, что приложение готово обслуживать запросы. Мы отдельно посмотрим число готовых реплик и проверим ответ веб-сервера.
- spec.replicas: 2 — хотим две реплики.
- status.readyReplicas: 1 — пока готова одна.
- Статус записывает Kubernetes. Для изменения желаемого числа копий мы меняем spec.
spec:
replicas: 2
status:
readyReplicas: 1
4. Как устроена лаборатория на портале
Открой страницу «Лабораторная», выбери первое задание и войди через свою учётную запись GitLab. Кнопка «Подготовить задание» создаёт учебные объекты, «Проверить результат» проверяет их состояние, а «Очистить ресурсы этой попытки» удаляет объекты этой попытки. Журнал и подтверждённый результат после очистки сохраняются.
Кнопка «Подключиться» в терминале открывает оболочку пользователя igor на 192.168.0.12. В этой оболочке работают обычные команды Linux и уже настроенный kubectl. Вставляй команду в терминал и нажимай Enter. Значок приглашения оболочки, например $, вводить не нужно. Ctrl+C прерывает текущую команду.
Namespace — именованная область для объектов внутри одного кластера. Наш namespace называется interview-lab. Параметр -n interview-lab говорит kubectl, в какой области искать или менять объект. В командах лабораторной мы указываем его явно.
Это существующий кластер, а namespace не превращает его в отдельную виртуальную машину. Терминал использует реальные права igor. Поэтому меняй только учебные объекты из инструкции; настройки нод, системные namespace и компоненты кластера для этой работы не трогаем.
Контекст kubectl — сохранённый набор настроек: к какому кластеру обращаться и от чьего имени. На проверенном стенде он называется kubernetes-admin@kubernetes. Если контекст или ноды не совпали с описанием, сначала разберись с подключением; команды изменения пока не выполняй.
Команда get только показывает объекты. Команды scale, set selector и delete уже меняют состояние. Сначала будем читать и записывать наблюдения, затем делать одно понятное изменение за раз.
- kubectl
- Программа, через которую мы обращаемся к API (Application Programming Interface — программный интерфейс) Kubernetes.
- -n interview-lab
- Выбрать namespace учебной работы. Это выбор области, а не ограничение прав пользователя.
- get pods
- Показать список объектов Pod. Имена объектов появятся в выводе команды.
- portal-demo
- Имя учебного Deployment и Service. Это разные типы объектов, которым дали одинаковое имя.
5. Как читать вывод команд
У команды kubectl get pods первая колонка NAME — имя Pod. READY показывает, сколько контейнеров внутри этого Pod готовы. В нашей работе контейнер один, поэтому ожидаем 1/1. STATUS=Running означает фазу работы Pod; чтобы убедиться в готовности, смотри также READY.
У команды kubectl get deployment portal-demo колонка READY относится уже к репликам Deployment. Здесь 2/2 означает: нужны две реплики и обе готовы. Не путай это с 1/1 у каждого отдельного Pod.
UID (Unique Identifier — уникальный идентификатор) — уникальный идентификатор конкретного объекта Kubernetes. Имя удобно читать, а UID помогает проверить, что объект действительно заменился. После удаления старого Pod новый получит другой UID. В лабораторной мы запишем имя и UID до изменений.
Команда describe показывает подробности объекта и связанные события. События — короткие сообщения о том, что происходило: например, назначение на ноду или ошибка загрузки образа. Если запуск не закончился, начни с describe и Events, а не с перезапуска всего кластера.
Строка No resources found означает, что выбранная область или выборка сейчас пуста. До подготовки задания это нормально. Если ты уже нажал «Подготовить задание», проверь его результат, namespace и выбранную лабораторную.
- NAME
- Имя объекта. Суффикс имени Pod Kubernetes обычно создаёт сам.
- READY 1/1 у Pod
- Один контейнер из одного готов.
- READY 2/2 у Deployment
- Две требуемые реплики готовы.
- AGE
- Сколько времени прошло с создания объекта, а не сколько он был готов.
6. Как запрос находит нужное приложение
У Pod может меняться адрес: старый Pod удалён, новый создан на его месте. Поэтому к группе Pod обычно обращаются через Service — объект с устойчивой точкой обращения внутри кластера.
Как Service понимает, какие Pod обслуживают наш сайт? На объектах есть labels — метки вида ключ=значение. У наших Pod метка app=portal-demo. В Service есть selector — условие выбора Pod по меткам.
Подготовленное задание специально содержит ошибку: Service ищет метку app=needs-fixing, а Pod имеют app=portal-demo. Сам контейнер при этом может быть Running и Ready, но Service не находит нужные Pod. Мы исправим только selector.
EndpointSlice — объект со списком адресов, через которые Service может достигнуть выбранных Pod. После исправления selector и запуска двух готовых реплик ожидаем два адреса Pod. Автоматическая проверка дополнительно проверяет готовность этих endpoints.
Приложение слушает порт 8080. В конце работы выполним запрос HTTP (Hypertext Transfer Protocol — протокол передачи веб-данных) и получим текст portal-lab:... с идентификатором текущей попытки. Такой ответ подтверждает, что дошли до своего учебного приложения. Детальное устройство DNS (Domain Name System — система доменных имён) и сети разберём в следующей лабораторной.
7. Почему удалённый Pod появляется снова
Допустим, Deployment по-прежнему просит две реплики. Ты удаляешь один Pod, но число в настройках Deployment не меняешь. ReplicaSet замечает, что Pod стало меньше требуемого числа, и создаёт новый.
Это называют согласованием состояния: контроллер снова и снова сравнивает то, что должно быть, с тем, что есть. Слово reconcile в документации означает этот процесс. Kubernetes не угадывает желание пользователя: он следует сохранённым настройкам.
Старый Pod не оживает. Вместо него появляется другой объект с новым UID (Unique Identifier — уникальный идентификатор). Kubelet запускает контейнеры нового Pod после его назначения на ноду. Поэтому важно записать исходный UID и сравнить его с результатом.
Если удалить сам Deployment, это уже другое действие: ты убираешь управляющий объект, а не одну из его реплик. Для нашей проверки удаляем только сохранённый исходный Pod и оставляем Deployment.
Связь владельцев можно увидеть в поле ownerReferences: у Pod владельцем будет ReplicaSet, а у ReplicaSet — Deployment. Это помогает понять, кто восстановит объект после удаления.
По шагам
- В Deployment по-прежнему указаны две реплики.
- Один Pod удалён, временно остался один.
- ReplicaSet создаёт недостающий Pod.
- Новый Pod получает UID (Unique Identifier — уникальный идентификатор), назначается на ноду и запускается.
- После проверки готовности приложение снова имеет две готовые реплики.
8. Что записать и как получить зачёт
На странице практикума есть «Журнал практики». Запиши исходное имя Pod и UID (Unique Identifier — уникальный идентификатор), что было сломано, какие изменения сделал и что увидел после них. Нажми «Сохранить заметку»: этот журнал хранится на сервере.
Затем нажми «Проверить результат». Автоматизация AWX (система запуска заданий Ansible) — уже подключённый к порталу исполнитель заданий — прочитает реальные объекты и выполнит проверку HTTP (Hypertext Transfer Protocol — протокол передачи веб-данных). Она проверяет пять условий: две готовые реплики, связь владельцев, Service, ответ приложения и замену исходного Pod.
Зачёт лабораторной и тест на понимание — разные результаты. Автоматическая проверка подтверждает состояние приложения на стенде. Тест из восьми вопросов в конце урока проверяет, понимаешь ли ты причины такого поведения. Для теста нужно ответить правильно минимум на семь вопросов.
Чек-лист этого урока ты отмечаешь самостоятельно; его отметки и заметка ниже хранятся в этом браузере. Подтверждённый результат и журнал на странице «Лабораторная» хранятся отдельно на сервере. Простая галочка в уроке не засчитывает лабораторную автоматически.
Не записывай пароли, токены или содержимое kubeconfig в заметки. Для этой работы достаточно названий объектов, UID (Unique Identifier — уникальный идентификатор), нескольких строк вывода и объяснения своими словами.
Для будущего Kubernetes as a Service полезен уже этот первый вывод: пользователь задаёт желаемое состояние, а система доводит его до результата и показывает, что получилось. Сейчас мы наблюдаем этот принцип на двух копиях маленького сайта.
Первая лабораторная через терминал портала
Открой лабораторную и подготовь новую попытку
Открой первую лабораторную в соседней вкладке и войди через GitLab. Нажми «Подготовить задание» и дождись состояния «задание готово». Если осталась старая попытка, сначала сохрани её наблюдения и очисти именно её кнопкой портала; затем подготовь новую. Если активно другое задание, портал покажет ссылку на него.
Что должно получиться. Появится Deployment portal-demo с одной репликой и Service с намеренно неправильным selector. Дальше все команды относятся к этой новой попытке.
Если результат отличается
Если подготовка завершилась ошибкой, команды исправления пока не выполняй. Прочитай сообщение в истории запусков: это отдельный сбой подготовки.
Подключись к терминалу и проверь, где находишься
На странице лабораторной нажми «Открыть терминал стенда», затем «Подключиться». Выполни команды по одной. hostname показывает имя машины, whoami — пользователя, current-context — настройки подключения kubectl, get nodes — ноды кластера. Эти команды читают информацию.
hostname whoami kubectl config current-context kubectl get nodesЧто должно получиться. На текущем стенде: ubuntu, пользователь igor, контекст kubernetes-admin@kubernetes. В списке нод есть ubuntu и ubuntuworker со статусом Ready.
Если результат отличается
Если соединение закрыто, подключись снова. Если имя машины, контекст или ноды отличаются, сначала проверь, что открыт терминал именно этой лаборатории.
Посмотри исходное состояние
getпоказывает объекты.deployиrs— короткие имена Deployment и ReplicaSet,svc— Service. Параметр-n interview-labявно выбирает учебную область.kubectl -n interview-lab get deploy,rs,pods,svc kubectl -n interview-lab get pods -l app=portal-demo --show-labels kubectl -n interview-lab describe service portal-demoЧто должно получиться. У Deployment одна готовая реплика. У Pod видна метка app=portal-demo, а в описании Service selector содержит app=needs-fixing. Поэтому готовый Pod ещё не выбран Service.
Если результат отличается
Если список пуст, проверь состояние подготовки. Если вместо portal-demo видны объекты другой лабораторной, вернись к первому заданию на портале.
Сохрани исходный Pod до изменений
Первая строка запоминает имя текущего Pod в переменной оболочки
ORIGINAL_POD. Конструкция $(...) берёт вывод команды; jsonpath здесь выбирает только имя первого Pod. Во второй строке кавычки сохраняют имя как один аргумент. Перед этим убедись, что виден ровно один готовый учебный Pod и нет строк Terminating: тогда выбираем исходный Pod. Скопируй имя и UID (Unique Identifier — уникальный идентификатор) из вывода в журнал практики и сохрани заметку.ORIGINAL_POD=$(kubectl -n interview-lab get pods -l app=portal-demo -o jsonpath='{.items[0].metadata.name}') kubectl -n interview-lab get pod "$ORIGINAL_POD" -o custom-columns=NAME:.metadata.name,UID:.metadata.uidЧто должно получиться. Одна строка с именем portal-demo-... и его длинным UID (Unique Identifier — уникальный идентификатор). Запись в журнале нужна до масштабирования и удаления.
Если результат отличается
Не продолжай с пустым именем или ошибкой NotFound. Проверь подготовку и список Pod. Переменная живёт только в этом сеансе SSH (Secure Shell — протокол защищённого удалённого доступа); при переподключении возьми исходное имя из сохранённого журнала, а не выбирай новый Pod вместо старого.
Попроси две копии приложения
scaleменяет число реплик Deployment;--replicas=2означает две копии.rollout statusждёт завершения запуска.--timeout=90sограничивает ожидание 90 секундами.kubectl -n interview-lab scale deployment portal-demo --replicas=2 kubectl -n interview-lab rollout status deployment/portal-demo --timeout=90s kubectl -n interview-lab get deployment portal-demo kubectl -n interview-lab get pods -l app=portal-demoЧто должно получиться. Deployment показывает READY 2/2, а список содержит два Pod, каждый с READY 1/1. Это две копии одного приложения.
Если результат отличается
При тайм-ауте посмотри kubectl -n interview-lab describe deployment portal-demo и события: kubectl -n interview-lab get events --sort-by=.metadata.creationTimestamp. Увеличивать число реплик ещё раз не нужно.
Исправь, какие Pod выбирает Service
set selectorзаменяет selector Service. Мы указываем ту же метку app=portal-demo, которая уже стоит на учебных Pod. Второй командой смотрим адреса выбранных Pod.kubectl -n interview-lab set selector service portal-demo app=portal-demo kubectl -n interview-lab get endpointslices -l kubernetes.io/service-name=portal-demoЧто должно получиться. В EndpointSlice появятся адреса двух Pod и порт 8080. Обновление может занять несколько секунд; при необходимости повтори только команду get.
Если результат отличается
Сравни selector из describe service portal-demo с labels из get pods --show-labels. Убедись, что обе реплики готовы.
Удали только сохранённый исходный Pod
Сначала echo показывает сохранённое имя. Сверь его с записью в журнале. Если переподключался, сначала восстанови переменную: ORIGINAL_POD='сохранённое-имя', заменив текст в кавычках своим именем Pod. Затем delete удаляет один Pod с этим именем; Deployment остаётся. После восстановления снова получим имена и UID (Unique Identifier — уникальный идентификатор).
echo "$ORIGINAL_POD" kubectl -n interview-lab delete pod "$ORIGINAL_POD" kubectl -n interview-lab rollout status deployment/portal-demo --timeout=90s kubectl -n interview-lab get pods -l app=portal-demo -o custom-columns=NAME:.metadata.name,UID:.metadata.uidЧто должно получиться. После завершения удаления и восстановления снова останутся два Pod. Исходного UID (Unique Identifier — уникальный идентификатор) среди них больше нет, у замены другой UID. Второй Pod может остаться прежним. Если замена ещё запускается, подожди несколько секунд и повтори команду get.
Если результат отличается
Если имя пустое или не совпало с журналом, delete не выполняй. Если старый Pod уже удалён, не удаляй случайный новый: сравни UID (Unique Identifier — уникальный идентификатор) и переходи к проверке. При необходимости открой чистую попытку через кнопки портала.
Посмотри владельца Pod и проверь ответ сайта
В первой команде ownerReferences показывает, кто управляет Pod: ожидаем ReplicaSet. Его имя можно найти в списке rs и посмотреть владельца через describe. Последняя команда запускает wget внутри одного учебного Pod и обращается к Service. После
--идёт уже команда контейнера.-T 5задаёт ожидание до пяти секунд,-qO-выводит текст ответа в терминал.kubectl -n interview-lab get pods -l app=portal-demo -o 'custom-columns=NAME:.metadata.name,OWNER_KIND:.metadata.ownerReferences[0].kind,OWNER_NAME:.metadata.ownerReferences[0].name' kubectl -n interview-lab get rs -l app=portal-demo kubectl -n interview-lab exec deployment/portal-demo -- wget -T 5 -qO- http://portal-demo:8080/Что должно получиться. У Pod OWNER_KIND=ReplicaSet. команда HTTP (Hypertext Transfer Protocol — протокол передачи веб-данных) выводит portal-lab: и идентификатор текущей попытки. Приглашение оболочки может оказаться сразу после ответа — в тексте страницы нет завершающего перевода строки.
Если результат отличается
При ошибке HTTP (Hypertext Transfer Protocol — протокол передачи веб-данных) сначала проверь selector и готовность Pod. Имя portal-demo в HTTP-команде используется внутри кластера: открывать его в адресной строке браузера не нужно.
Получи проверку и объясни результат
Нажми «Проверить результат» на странице лабораторной и дождись завершения. Затем запиши в серверный журнал: почему Service сначала не работал, почему появился новый Pod и кто сохранил требование о двух репликах. Нажми «Сохранить заметку». После этого пройди тест модуля на странице урока.
Что должно получиться. В лабораторной успешно отмечены пять автоматических критериев. В тесте для зачёта нужно минимум 7 из 8. Оба результата отвечают на разные вопросы: работает ли приложение и понимаешь ли ты механизм.
Если результат отличается
Если критерий не прошёл, прочитай его пояснение и исправь причину. Ошибка выполнения AWX (система запуска заданий Ansible) — не оценка знаний. Сначала проверь сообщение о доступности стенда.
Заверши работу аккуратно
Когда результаты и объяснения сохранены, нажми «Очистить ресурсы этой попытки» и дождись завершения. Эта кнопка удаляет учебные объекты попытки; результат проверки и журнал остаются. Затем отключи терминал.
Что должно получиться. Окружение готово к подготовке новой попытки. Проверенный результат первой лабораторной сохранён; следующая лабораторная практикума доступна.
Если результат отличается
Если очистка завершилась ошибкой, прочитай историю. Не удаляй namespace вручную — он используется всем практикумом.
Критерии готовности
Это твоя самопроверка понимания. Отмечай после практики. Зачёт самой лабораторной даёт кнопка «Проверить результат» на странице практикума; он сохраняется на сервере.
Что сохранить в журнале
- В журнале лабораторной: исходное имя и UID (Unique Identifier — уникальный идентификатор) Pod, что было сломано и какие команды помогли.
- Там же: UID (Unique Identifier — уникальный идентификатор) после восстановления и объяснение связи Deployment → ReplicaSet → Pod.
- В истории лабораторной: успешная автоматическая проверка. В уроке: результат теста и собственные отметки понимания.
Основной журнал этой работы находится в практикуме и сохраняется на сервере. Поле ниже — дополнительная заметка к уроку в этом браузере.
Проверь понимание
8 вопросов по этому модулю. Проходной результат — 7 из 8. После ответа — объяснения и ссылки на разделы, к которым стоит вернуться.
Пройти тест модуляОфициальные источники
Чек-листы уроков, заметки к ним и результаты тестов хранятся в этом браузере; для переноса используй экспорт. Автоматические проверки и журнал практикума сохраняются отдельно на сервере.