Перейти до вмісту

Модуль 0.2: Робочий процес розробника

Hands-On Lab Available
K8s Cluster intermediate 30 min
Launch Lab ↗

Opens in Killercoda in a new tab

Складність: [ШВИДКИЙ] — основні патерни kubectl для швидкості та точності на CKAD

Час на проходження: 35–45 хвилин

Передумови: Модуль 0.1 (Огляд CKAD), базова впевненість у роботі з командним рядком та достатній словник Kubernetes, щоб розпізнавати Pod’и, Деплойменти, Сервіси, Job’и, ConfigMap’и, Secret’и та простори імен


Результати навчання

Розділ «Результати навчання»

Після завершення цього модуля ви зможете:

  • Спроєктувати повторюваний робочий процес kubectl, який перетворює екзаменаційні завдання на згенерований YAML, невеликі правки, застосовані ресурси та перевірені результати без марнування часу.
  • Діагностувати типові збої ресурсів розробника за допомогою kubectl describe, kubectl logs, kubectl exec, подій, JSONPath та перевірок простору імен.
  • Порівняти імперативні команди, згенеровані маніфести та пряме написання YAML, щоб обрати найшвидший надійний шлях для кожного завдання CKAD.
  • Оцінити, чи був ресурс створений у правильному просторі імен, з правильною командою контейнера, наданий через правильний Сервіс та прибраний після тестування.
  • Реалізувати перевірки багатоконтейнерного Pod’а, Job’а, CronJob’а, ConfigMap’а, Secret’а та зв’язності за допомогою патернів, які працюють на кластерах Kubernetes 1.35+.

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Розробник провалює передачу чергування, бо Деплоймент був правильний, Сервіс був правильний, а історія команд виглядала переконливо — проте кожен об’єкт опинився в попередньому просторі імен. Команда витрачає перші хвилини, переглядаючи логи застосунку, потім мережеву політику, потім теги образів, тоді як справжній збій лежить на видноті: робочий процес жодного разу не змусив розробника довести, де саме він працює, перш ніж створювати ресурси.

CKAD має таку саму форму. Іспит рідко питає, чи можете ви процитувати означення Pod’а. Він питає, чи зможете ви перетворити сценарій на робочий об’єкт Kubernetes, поки годинник цокає. Знання важливі, але робочий процес вирішує, чи дійдуть ці знання до кластера в точному вигляді. Сильний робочий процес робить правильну дію легкою: задати контекст, згенерувати маніфест, відредагувати найменшу безпечну поверхню, застосувати, перевірити зсередини кластера та не лишити по собі випадкових ресурсів.

Цей модуль трактує kubectl як верстак розробника, а не як енциклопедію команд. Ви навчитеся, коли створювати імперативно, коли спершу генерувати YAML, коли інспектувати живий стан, а коли відмовитися від шляху через команду, бо редагувати маніфест безпечніше. Мета не в тому, щоб одного разу набрати найменше символів. Мета — завершити багато завдань із низькою частотою помилок, бо швидкість без перевірки — це лише швидший спосіб втратити бали.

Аналогія з майстерним верстаком

Уважний майстер не жбурляє всі інструменти на верстак, сподіваючись, що потрібний з’явиться сам. Рулетка, кутник, олівець, пилка та струбцини мають своє визначене місце, бо повторювана робота стає надійною, коли підготовка є свідомою. Ваш робочий процес для CKAD має відчуватися так само: аліас, простір імен, dry run, редагування, застосування, перевірка та прибирання у послідовності, яку ви можете повторити під тиском.


Базовий робочий процес: від завдання до перевіреного ресурсу

Розділ «Базовий робочий процес: від завдання до перевіреного ресурсу»

Робочий процес розробника починається ще до того, як ви щось створюєте. Завдання CKAD зазвичай дає вам простір імен, тип ресурсу, ім’я, образ, порти, значення середовища, поведінку команди та вимогу до перевірки. Якщо ви починаєте набирати з першого ж іменника, який упізнали, ви ризикуєте розв’язати лише частину завдання. Досвідчені практики Kubernetes роблять паузу, достатню, щоб класифікувати завдання, бо саме класифікація визначає найбезпечніший шлях через kubectl.

Використовуйте kubectl повністю один раз — коли документуєте чи навчаєте командам, — а потім користуйтеся аліасом k заради швидкості, коли ви його вже визначили. У цьому модулі k означає kubectl. Ви все одно маєте розуміти кожну розгорнуту команду, бо аліаси допомагають лише тоді, коли вони скорочують правильну поведінку. Аліас, що приховує плутанину, просто дає вам помилятися швидше.

Terminal window
alias k='kubectl'

Перше рішення — чи можна створити ресурс правильно однією імперативною командою. Прості Pod’и, Деплойменти, Сервіси, Job’и, CronJob’и, ConfigMap’и та Secret’и часто можна. Багатоконтейнерні Pod’и, спільні томи, проби, контекст безпеки, посилання на середовище через env-from та нетривіальні команди зазвичай потребують згенерованого YAML із подальшим редагуванням. Високий рівень майстерності — не в тому, щоб запам’ятати кожен прапорець; він у тому, щоб знати, коли припинити силувати прапорці й перейти на маніфест.

+---------------------+ +----------------------+ +-------------------+
| Read exam prompt | ---> | Classify resource | ---> | Choose creation |
| namespace, name, | | Pod, Deployment, | | imperative, dry |
| image, ports, data | | Service, Job, etc. | | run, or YAML |
+---------------------+ +----------------------+ +-------------------+
| | |
v v v
+---------------------+ +----------------------+ +-------------------+
| Set namespace | ---> | Generate or edit | ---> | Apply, inspect, |
| or pass -n every | | the smallest safe | | test, and clean |
| time deliberately | | manifest surface | | up test objects |
+---------------------+ +----------------------+ +-------------------+

Корисна ментальна модель — «прочитай, виріши, побудуй, доведи». Прочитай завдання, шукаючи обмеження. Виріши, який робочий процес підходить. Побудуй лише той об’єкт, який потрібен. Доведи його з точки зору кластера, а не лише за кодом виходу твого термінала. Ця послідовність запобігає типовому збою, коли YAML синтаксично коректний, але поведінка все одно неправильна.

Підказка для активного навчання: Прочитайте цей сценарій, перш ніж дивитися далі: «Створіть Pod з ім’ям probe-demo з образом nginx, потім перевірте образ контейнера, який насправді дійшов до API-сервера». Ви б скористалися k run напряму, спершу згенерували YAML чи написали YAML з нуля? Вирішіть чому, тоді порівняйте свою відповідь із робочим процесом нижче.

Для простого Pod’а без додаткових полів пряме імперативне створення прийнятне, бо команда чітко відображає запитуваний об’єкт. Перевірка все одно важлива. Ви не завершили, коли команда завершилася. Ви завершили, коли живий об’єкт має очікувану форму, а Pod досягає придатного до використання стану.

Terminal window
k run probe-demo --image=nginx
k wait --for=condition=Ready pod/probe-demo --timeout=90s
k get pod probe-demo -o jsonpath='{.spec.containers[0].image}'
k delete pod probe-demo

Якщо завдання додає другий контейнер, спільний том, певну політику перезапуску або команду з вимогами до лапок, згенерований YAML стає безпечнішим. Сенс генерування через dry-run не в тому, щоб уникнути YAML. Сенс — уникнути YAML «з чистого аркуша», зберігаючи при цьому повний контроль над фінальним маніфестом. Ви дозволяєте kubectl створити шаблонну заготовку, а потім редагуєте лише ті частини, що мають значення.

Terminal window
k run probe-demo --image=nginx --dry-run=client -o yaml > probe-demo.yaml

Решта цього модуля будує робочий процес пошарово. Спершу ви робите свою оболонку достатньо швидкою для повторюваної роботи. Потім надійно генеруєте маніфести. Потім редагуєте поширені об’єкти розробника. Потім перевіряєте через логи, exec, події та JSONPath. Зрештою ви відпрацьовуєте весь цикл на хронометрованих вправах, що відповідають тому, як відчуваються завдання CKAD.


Налаштування оболонки та дисципліна аліасів

Розділ «Налаштування оболонки та дисципліна аліасів»

Аліаси не є чарами, і вони не обов’язкові для Kubernetes. Вони корисні, бо CKAD — це іспит на продуктивність, де повторювані команди створюють повторювані можливості для друкарських помилок. Головне — аліасувати завершені, добре зрозумілі звички, а не винаходити приватну мову, яка стає нечитабельною під тиском. Кожен аліас має зменшувати тертя для команди, яку ви вже вмієте розгорнути.

Додайте це до ~/.bashrc або ~/.zshrc у вашому навчальному середовищі. У реальному екзаменаційному терміналі спершу з’ясуйте, що вже налаштовано, перш ніж редагувати стартові файли. Деякі середовища містять k та автодоповнення, але ви маєте вміти швидко відтворити свій робочий процес, якщо оболонка стартує без них.

Terminal window
alias k='kubectl'
alias kaf='kubectl apply -f'
alias kdel='kubectl delete'
alias kd='kubectl describe'
alias kg='kubectl get'
alias kl='kubectl logs'
alias kx='kubectl exec -it'
alias kgy='kubectl get -o yaml'
alias kgw='kubectl get -o wide'
export kdr='--dry-run=client -o yaml'
alias kr='kubectl run'
alias kgpw='kubectl get pods -w'

Змінна kdr заслуговує на особливу увагу, бо це змінна оболонки, а не функція Kubernetes. Змінна без лапок розгортається у два аргументи командного рядка: --dry-run=client та -o yaml. Це робить її зручною для практики, але вам також варто почуватися впевнено, набираючи повні прапорці. Якщо у вашій сесії оболонки немає цієї змінної, явна форма завжди працює.

Terminal window
k run web --image=nginx $kdr > web.yaml
k run web --image=nginx --dry-run=client -o yaml > web.yaml

Завдання CKAD часто містять Job’и та CronJob’и, і їх легко згенерувати неправильно, якщо забути, де починається команда. Для Job’ів команда йде після --. Для CronJob’ів розклад є частиною означення ресурсу, а команда все одно йде після --. Сприймайте -- як межу: прапорці перед ним налаштовують kubectl, а слова після нього стають командою та аргументами контейнера.

Terminal window
alias kcj='kubectl create job'
alias kccj='kubectl create cronjob'
k create job once --image=busybox -- echo complete
k create cronjob hourly --image=busybox --schedule="0 * * * *" -- date

Аліаси для діагностики мають бути короткими, але не загадковими. Одноразовий Pod для діагностики має використовувати --rm, щоб він зник, -it, коли потрібен інтерактивний вивід, та --restart=Never, коли команда контейнера має виконатися один раз і завершитися. Без --restart=Never швидка команда може перетворитися на заплутану проблему життєвого циклу замість чистого тесту.

Terminal window
alias kdebug='kubectl run debug --image=busybox --rm -it --restart=Never --'
alias klc='kubectl logs -c'
alias kctx='kubectl config use-context'
alias kns='kubectl config set-context --current --namespace'

Автодоповнення також є частиною якості робочого процесу. Воно зменшує помилки в написанні імен ресурсів та просторів імен. Автодоповнення не замінює розуміння, але це цінний запобіжник, коли ім’я довге або схоже на інший об’єкт. Налаштуйте його під час практики, щоб ви могли вирішити, чи варто швидко налаштувати його у вашому екзаменаційному середовищі.

Terminal window
source <(kubectl completion bash)
complete -o default -F __start_kubectl k

Якщо ви використовуєте Z shell, налаштування інше, але мета та сама: зробити, щоб k get po<Tab> та доповнення імен ресурсів працювали. Не витрачайте екзаменаційний час на налагодження вигадливої конфігурації оболонки. Вашим запасним варіантом завжди мають бути прості команди плюс акуратно скопійований вивід k get.

Terminal window
source <(kubectl completion zsh)
compdef __start_kubectl k

Досвідчений робочий процес тримає аліаси достатньо малими, щоб їх можна було перевірити. Після їх налаштування протестуйте команди на нешкідливих ресурсах. Якщо аліас розгортається несподівано, виправте його, перш ніж покладатися на нього. Іспит — не місце, щоб виявити, що ваш локальний аліас оболонки використав прапорець, який не підтримується встановленим у кластері клієнтом.

Terminal window
type k
type kgy
echo "$kdr"
k version --client

Підказка для активного навчання: Припустімо, echo "$kdr" нічого не виводить під час екзаменаційного завдання. Що ламається, що все одно працює, і як би ви продовжили, не витрачаючи час на ремонт стартових файлів оболонки?

Правильна відповідь — у Kubernetes нічого не ламається. Бракує лише вашого скорочення. Продовжуйте з явними прапорцями: --dry-run=client -o yaml. Саме тому кожне скорочення в цьому модулі подається як коротша форма видимої команди, а не як щось, що треба сліпо запам’ятати.


Спершу простір імен: запобігайте правильній роботі в неправильному місці

Розділ «Спершу простір імен: запобігайте правильній роботі в неправильному місці»

Помилки з простором імен особливо болісні, бо всі команди можуть успішно виконатися. Ви створюєте Деплоймент, надаєте до нього доступ, інспектуєте Pod’и та запускаєте тести, але перевіряльник дивиться в інший простір імен. Це гірше за негайну помилку, бо успішний вивід вселяє хибну впевненість. Виправлення — це правило робочого процесу: кожне завдання починається з роботи над простором імен, перш ніж створювати ресурс.

Є два безпечні стилі роботи з простором імен. Ви можете задати поточний простір імен для сесії або передавати -n у кожній команді. Задавання простору імен швидше для завдання з багатьох команд, але воно створює ризик, коли ви переходите до наступного завдання. Передавання -n є явним і трохи довшим. Свідомо використовуйте один стиль і не зміщуйтеся між ними без перевірки.

Terminal window
k create ns dev
k config set-context --current --namespace=dev
k get pods
Terminal window
k get pods -n dev
k run web --image=nginx -n dev
k expose pod web --port=80 -n dev

Найшвидша перевірка простору імен — не найгарніша команда; це та, яку ви насправді виконаєте. k config view --minify показує поточний контекст і простір імен. Якщо простір імен не з’являється, команди за замовчуванням використовують default. Ця відсутність є значущою, тож не читайте її як «невідомо». Вона означає, що Kubernetes використає простір імен default, якщо ви не передасте -n.

Terminal window
k config view --minify | grep namespace || true

Краща екзаменаційна звичка — задавати або передавати простір імен на початку кожного завдання, а потім перевіряти створений об’єкт у тому самому просторі імен. Це створює замкнений цикл: команда, яка створює об’єкт, і команда, яка доводить його існування, обидві вказують на одне й те саме місце. Якщо вони не збігаються, ви виявите проблему одразу.

Terminal window
k create ns inventory
k config set-context --current --namespace=inventory
k create deploy api --image=nginx
k get deploy api
k get pods -l app=api

Коли перемикаєте завдання, скидайте контекст свідомо. Не покладайтеся на пам’ять. Якщо завдання один використовувало payments, а завдання два використовує inventory, перша команда для завдання два має згадати inventory — або задавши контекст, або передавши -n inventory. Незначна вартість цієї команди набагато менша за діагностику невидимих ресурсів.

Terminal window
k config set-context --current --namespace=inventory
k config view --minify | grep namespace

Зупиніться та подумайте: Ви завершуєте завдання в payments, потім створюєте Сервіс для наступного завдання, не перемкнувшись на inventory. Сервіс існує, але перевіряльник повідомляє, що його немає. Яка команда найшвидше виявить проблему і як би ви виправили стан, не видаляючи непов’язаних ресурсів?

Найшвидше виявлення — це зазвичай k get svc -A | grep <service-name>, бо воно показує, де об’єкт насправді опинився. Виправлення залежить від ресурсу. Для екзаменаційних завдань найчистіший шлях — зазвичай відтворити об’єкт у правильному просторі імен, перевірити його там і видалити лише той об’єкт, що опинився не там, якщо ви впевнені, що він ваш.

Terminal window
k get svc -A | grep api || true
k get svc api -n payments -o yaml > api-svc.yaml

Якщо ви експортуєте YAML із неправильного простору імен, приберіть поля, які не слід відтворювати, і обережно змініть простір імен. Для CKAD часто швидше перегенерувати Сервіс у правильному просторі імен, ніж очищати експортований YAML. Експорт живого YAML містить поля, керовані сервером, які можуть відвернути вас від завдання.

Terminal window
k expose deploy api --port=80 -n inventory
k get svc api -n inventory
k delete svc api -n payments

Генерація через dry-run: швидкий YAML без ризику чистого аркуша

Розділ «Генерація через dry-run: швидкий YAML без ризику чистого аркуша»

Патерн dry-run — це центр робочого процесу розробника на CKAD. Він дає вам коректну структуру Kubernetes без створення ресурсу. Це має значення, бо багато завдань потребують одного чи двох власних полів понад те, що імперативна команда може виразити чисто. Генерування маніфеста дозволяє вам почати з коректних apiVersion, kind, metadata та поширених міток, а потім відредагувати лише потрібні поля.

Terminal window
k run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
k create deploy web --image=nginx --replicas=3 --dry-run=client -o yaml > deploy.yaml
k create job backup --image=busybox --dry-run=client -o yaml -- echo done > job.yaml
k expose deploy web --port=80 --dry-run=client -o yaml > svc.yaml

Коли використовуєте скорочення kdr, пам’ятайте, що перенаправлення відбувається у вашій оболонці. Файл записує оболонка, а не Kubernetes. Якщо команда перед > неправильна, ви все одно можете створити порожній або частковий файл — залежно від характеру збою. Завжди інспектуйте згенерований YAML перед застосуванням, якщо ви щось важливе редагували чи перенаправляли.

Terminal window
export kdr='--dry-run=client -o yaml'
k run nginx --image=nginx $kdr > pod.yaml
sed -n '1,80p' pod.yaml

Генерація через dry-run особливо корисна для ресурсів, синтаксис яких легко набрати з помилкою. Деплоймент, згенерований через k create deploy, містить правильне поєднання селектора та мітки шаблону. Написати ці поля з нуля можливо, але це також місце, де невеликі розбіжності призводять до Деплойменту, який ніколи не володіє своїми Pod’ами. Дозвольте інструменту згенерувати цей зв’язок, а потім відредагуйте образ, кількість реплік, порти чи значення середовища за потреби.

Terminal window
k create deploy web --image=nginx --replicas=2 $kdr > web-deploy.yaml
k apply -f web-deploy.yaml
k rollout status deploy/web --timeout=90s

Генерація Сервісу має два надійні шляхи. Ви можете надати доступ до наявного ресурсу або створити Сервіс безпосередньо. Надання доступу до Деплойменту зручне, бо Kubernetes використовує мітки Деплойменту, щоб побудувати селектор. Створення Сервісу безпосередньо корисне, коли Pod’и-бекенди вже мають відомі мітки або коли завдання прямо просить маніфест Сервісу.

Terminal window
k expose deploy web --port=80 --target-port=80 $kdr > web-svc.yaml
k create svc clusterip web --tcp=80:80 $kdr > web-svc-direct.yaml

Для Job’ів та CronJob’ів генерація через dry-run запобігає поширеній проблемі з часом. Якщо ви запускаєте об’єкт безпосередньо, Job може стартувати й завершитися ще до того, як ви помітите, що команда була неправильною. Спершу згенерований YAML дозволяє вам інспектувати команду контейнера та політику перезапуску, перш ніж контролер почне діяти.

Terminal window
k create job backup --image=busybox $kdr -- sh -c 'echo backup complete' > backup-job.yaml
k create cronjob hourly --image=busybox --schedule="0 * * * *" $kdr -- sh -c 'date' > hourly-cronjob.yaml

Сильний робочий процес використовує kubectl explain як точковий довідник, а не як проєкт для читання. Якщо ви забули, де розташоване поле, спитайте схему API. Це швидше й безпечніше за вгадування відступів. Наприклад, env контейнера належить контейнеру, тоді як volumes належить spec.

Terminal window
k explain pod.spec.containers.env
k explain pod.spec.volumes
k explain deployment.spec.template.spec.containers.readinessProbe

Підказка для активного навчання: Вам потрібен Деплоймент із пробою готовності. Ви б продовжували намагатися виразити пробу через прапорці k create deploy, чи згенерували б Деплоймент і відредагували YAML? Поясніть компроміс, перш ніж рухатися далі.

Згенеруйте та відредагуйте YAML. Проба готовності вкладена в специфікацію контейнера шаблону Pod’а, і силувати її через імперативні скорочення було б повільніше й менш надійно. Патерн dry-run дає вам каркас Деплойменту, включно із селекторами та мітками шаблону, тож ви можете додати пробу в правильному місці.

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10

Застосовуйте лише після того, як маніфест розповідає послідовну історію. Мітки в селекторі та шаблоні Pod’а мають збігатися. Імена контейнерів мають збігатися з тими іменами, які ви використаєте з logs -c чи exec -c. Порти, на які посилаються проби та Сервіси, мають збігатися з фактичними портами контейнера чи слухачами застосунку. Валідність YAML — це лише перші ворота; поведінка Kubernetes — справжній тест.

Terminal window
k apply -f web-deploy.yaml
k rollout status deploy/web --timeout=90s
k get deploy web -o wide
k describe deploy web

Імперативні команди, маніфести та матриця рішень

Розділ «Імперативні команди, маніфести та матриця рішень»

Не кожне завдання заслуговує на файл маніфесту. Якщо завдання каже «створіть Pod з ім’ям web з образом nginx», пряме імперативне створення є швидким і точним. Якщо завдання каже «створіть Pod з ім’ям web з двома контейнерами, що мають спільний том», пряме імперативне створення — неправильний інструмент. Майстерність практика — у виборі робочого процесу, який мінімізує загальний час, включно з перевіркою та виправленням.

Патерн завданняНайкраща стартова точкаЧому це працюєКоманда перевірки
Простий одноконтейнерний Podk run напряму або YAML через dry-runКоманда чітко відображає запитуваний об’єктk get pod NAME -o wide
Деплоймент із реплікамиk create deployЗгенеровані селектор і мітки шаблону вирівнюються автоматичноk rollout status deploy/NAME
Сервіс для наявного Деплойментуk expose deployСелектор виводиться з наявних мітокk get endpointslices -l kubernetes.io/service-name=NAME
Багатоконтейнерний Podk run ... $kdr, потім редагуванняІмперативні прапорці не можуть чисто виразити кілька контейнерівk get pod NAME -o jsonpath='{.spec.containers[*].name}'
Job або CronJob із командоюk create job або k create cronjobМежа команди після -- є явноюk get jobs або k get cronjobs
ConfigMap або Secret з літералівk create cm або k create secretІмперативне створення уникає помилок з відступамиk get cm NAME -o yaml
Проба, том, envFrom, securityContextЗгенеруйте YAML, потім редагуйтеВкладені поля легше правильно розмістити в маніфестіk describe pod та події

Пряма імперативна команда найкраща, коли завдання й команда мають однакову форму. Згенерований маніфест найкращий, коли завдання додає структуру нижче spec. Написаний вручну YAML найкращий лише тоді, коли генерація зайняла б більше часу, ніж написання невеликого знайомого об’єкта, або коли ви адаптуєте патерн, який багато разів відпрацьовували. На іспиті гордість не має жодної цінності; обирайте шлях, який найшвидше дає перевірений правильний об’єкт.

Розглянутий приклад: завдання каже «У просторі імен demo створіть Деплоймент з ім’ям api з образом nginx, двома репліками, і надайте до нього доступ усередині кластера на порту 80. Перевірте, що він досяжний зсередини кластера». Це чистий імперативний робочий процес, бо кожен потрібний об’єкт має пряму команду.

Terminal window
k create ns demo
k config set-context --current --namespace=demo
k create deploy api --image=nginx --replicas=2
k rollout status deploy/api --timeout=90s
k expose deploy api --port=80 --target-port=80
k get svc api
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://api
k config set-context --current --namespace=default
k delete ns demo

Тепер порівняйте схоже завдання: «Створіть Pod з ім’ям api з контейнером nginx та сайдкаром busybox, що спить одну годину». Ім’я ресурсу звучить просто, але структура — це вже не однокомандний Pod. Згенеруйте базовий Pod, відредагуйте другий контейнер, застосуйте та перевірте, що обидва контейнери існують.

Terminal window
k run api --image=nginx $kdr > api-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: api
labels:
run: api
spec:
containers:
- name: api
image: nginx
- name: sidecar
image: busybox
command: ["sleep", "3600"]
Terminal window
k apply -f api-pod.yaml
k wait --for=condition=Ready pod/api --timeout=90s
k get pod api -o jsonpath='{.spec.containers[*].name}'
k logs api -c sidecar --tail=5

Крок перевірки виявляє ще одну досвідчену звичку: перевіряйте поведінку, що має значення, а не лише існування об’єкта. Багатоконтейнерний Pod може існувати, поки один контейнер аварійно завершується. Сервіс може існувати без ендпойнтів. Job може існувати, не завершившись. ConfigMap може існувати з неправильним ключем. Ваша послідовність команд має доводити саме те твердження, яке вимагає завдання.


Редагування YAML без руйнування структури

Розділ «Редагування YAML без руйнування структури»

Редагування YAML — це місце, де багато інакше сильних кандидатів втрачають час. Маніфести Kubernetes чутливі до відступів, і найпоширеніший збій — це не збій у концепції Kubernetes; це поле, розміщене на неправильному рівні. Використовуйте генерацію, щоб отримати зовнішню структуру, потім робіть невеликі правки з чітким наміром «до й після». Ви не пишете роман у YAML. Ви розміщуєте поля точно там, де їх очікує API.

Конфігурація Vim може усунути тертя, якщо ви користуєтеся Vim. Якщо в практиці ви використовуєте інший редактор, знайте: екзаменаційне середовище все одно може віддавати перевагу редагуванню в терміналі. Ці налаштування роблять дворівневий відступ YAML передбачуваним.

set tabstop=2
set shiftwidth=2
set expandtab
set autoindent

Найшвидші команди Vim для CKAD — це ті, що підтримують дублювання, відступи, пошук та збереження. Вам не потрібно ставати експертом із Vim, щоб скласти CKAD, але вам потрібна достатня вправність, щоб дублювати блок контейнера й переміщати поля, не руйнуючи відступи.

yy
p
dd
>>
<<
/image
:50
:wq

Коли додаєте сайдкар, копіюйте повний блок контейнера, а не набирайте кожен рядок з нуля. Потім відредагуйте скопійовані ім’я, образ і команду. Це зменшує синтаксичний ризик, бо маркери списку та відступи вже збігаються з маніфестом. Критична деталь — другий рядок - name: має вирівнюватися з рядком - name: першого контейнера.

apiVersion: v1
kind: Pod
metadata:
name: multi
spec:
containers:
- name: main
image: nginx
- name: sidecar
image: busybox
command: ["sleep", "3600"]

Розміщення volumes та volumeMounts — класичне джерело помилок. volumes належить spec, бо описує сховище, доступне Pod’у. volumeMounts належить кожному контейнеру, бо описує, де цей контейнер бачить сховище. Якщо ви поміняєте ці рівні місцями, маніфест може бути відхилений, або контейнер може стартувати без очікуваних файлів.

apiVersion: v1
kind: Pod
metadata:
name: shared-logs
spec:
volumes:
- name: logs
emptyDir: {}
containers:
- name: web
image: nginx
volumeMounts:
- name: logs
mountPath: /var/log/nginx
- name: reader
image: busybox
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: logs
mountPath: /var/log/nginx

Змінні середовища мають подібне правило рівня. env належить контейнеру, бо змінні середовища впроваджуються в процес конкретного контейнера. Об’єкт ConfigMap можна згенерувати окремо, а потім послатися на нього з Pod’а чи Деплойменту. Це розділення важливе, бо завдання може попросити вас створити і джерело даних, і робоче навантаження, яке його споживає.

Terminal window
k create cm app-config --from-literal=MODE=prod --from-literal=LOG_LEVEL=info
apiVersion: v1
kind: Pod
metadata:
name: env-demo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "env && sleep 3600"]
envFrom:
- configMapRef:
name: app-config

Після редагування YAML швидко скористайтеся зворотним зв’язком на стороні сервера. k apply --dry-run=server -f file.yaml просить API-сервер перевірити маніфест, не зберігаючи його. Клієнтський dry-run генерує чи перевіряє локально, але серверний dry-run ловить поведінку схеми та допуску ближче до кластера, який ви використовуєте. Якщо серверний dry-run проходить, застосування файлу менш ризиковане.

Terminal window
k apply --dry-run=server -f env-demo.yaml
k apply -f env-demo.yaml

Підказка для активного навчання: У Pod’і зі спільним томом вище — що сталося б, якби volumeMounts розмістили під spec поряд із volumes, а не під кожним контейнером? Спрогнозуйте, чи прийме API таке, а потім скористайтеся k explain pod.spec.containers.volumeMounts, щоб підтвердити, де належить це поле.

Ширший урок у тому, що kubectl explain є частиною робочого процесу редагування. Вам не потрібно запам’ятовувати кожен шлях поля. Вам потрібно знати, як швидко віднайти шлях і правильно його застосувати. Схема API — це джерело істини під час іспиту.

Terminal window
k explain pod.spec.containers.volumeMounts
k explain pod.spec.volumes.emptyDir
k explain pod.spec.containers.envFrom.configMapRef

Швидкі патерни тестування зсередини кластера

Розділ «Швидкі патерни тестування зсередини кластера»

Сервіс, який відповідає з вашого ноутбука, — це не те саме, що Сервіс, який резолвиться зсередини кластера. Завдання CKAD часто дбають про внутрішньокластерну поведінку, тож ваша перевірка має використовувати тимчасовий Pod у тому самому просторі імен. Патерн короткий, але кожен прапорець має своє призначення: --rm прибирає, -it під’єднує ваш термінал, --restart=Never створює одноразовий Pod, а команда після -- виконує тест.

Terminal window
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://service-name

BusyBox корисний, бо він малий і широко доступний, але він може містити не всі інструменти, які ви хочете, у кожному тегу образу. Для поведінки HTTP curlimages/curl часто зрозуміліший. Для перевірок DNS зазвичай достатньо nslookup із BusyBox. Обирайте образ, що відповідає запитанню, і не марнуйте час, встановлюючи інструменти в тимчасовий Pod.

Terminal window
k run dns-test --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default.svc
k run curl-test --image=curlimages/curl --rm -it --restart=Never -- curl -sS http://service-name

Прапорець --restart=Never має значення, бо він задає політику перезапуску Pod’а для одноразового виконання команди. Якщо тестова команда успішно завершується, а Pod налаштований на перезапуск, кластер може продовжувати його перезапускати або зробити життєвий цикл важчим для тлумачення. Чистий тестовий Pod має запуститися, показати вивід, завершитися та зникнути.

Terminal window
k run once --image=busybox --restart=Never -- echo done
k get pod once
k delete pod once

Коли тест Сервісу провалюється, не стрибайте одразу до діагностики застосунку. Працюйте від мережевого об’єкта назад. Спершу підтвердьте, що Сервіс існує у просторі імен. Потім підтвердьте, що він має селектор. Потім підтвердьте, що для відповідних Pod’ів існують зрізи ендпойнтів (endpoint slices). Потім підтвердьте, що Pod’и готові (Ready). Ця послідовність не дасть вам читати логи застосунку, який Сервіс навіть не вибирає.

Terminal window
k get svc backend
k describe svc backend
k get endpointslices -l kubernetes.io/service-name=backend
k get pods --show-labels

EndpointSlices — це сучасний спосіб, яким Kubernetes відстежує бекенди Сервісу. Ви все ще можете побачити приклади, що використовують k get endpoints, і це може бути корисно, але EndpointSlices дають актуальніші деталі на новіших кластерах. У практиці CKAD будь-який з них може виявити найважливіший факт: чи має Сервіс наразі бекенди.

Terminal window
k get endpoints backend
k get endpointslices -l kubernetes.io/service-name=backend -o wide

Зупиніться та подумайте: Сервіс існує, і DNS резолвиться, але wget http://backend завершується за тайм-аутом. Що вам слід оглянути, перш ніж змінювати образ застосунку?

Огляньте селектор Сервісу та мітки Pod’ів-бекендів, перш ніж змінювати образ. Розбіжність селектора створює цілком валідний Сервіс без корисних бекендів. Якщо EndpointSlices порожні, запиту немає куди йти. Якщо ендпойнти існують, але запит усе одно провалюється, тоді перевірте порти контейнера, готовність, логи та поведінку застосунку.

Terminal window
k describe svc backend
k get pods --show-labels
k get pod -l app=backend -o wide
k logs -l app=backend --tail=20

Тимчасові Pod’и для діагностики не мають перетворюватися на сміття. Якщо інтерактивний тест перервано, --rm не завжди прибирає об’єкт одразу. Перевіряйте та прибирайте за міткою чи ім’ям. Залишені зайві Pod’и зазвичай самі по собі не провалюють завдання, але сміття уповільнює подальшу діагностику й може заплутати вашу власну перевірку.

Terminal window
k get pods
k delete pod test dns-test curl-test --ignore-not-found

Логи, exec, describe, події та JSONPath

Розділ «Логи, exec, describe, події та JSONPath»

Діагностика — це процес звуження. k get каже вам, що існує, та широкий статус. k describe каже вам про планування, події, стан контейнера, проби, монтування та поведінку завантаження образу. k logs каже вам, що записав застосунок. k exec дозволяє вам інспектувати зсередини запущеного контейнера. JSONPath видобуває саме те поле, яке вимагає завдання, без ручного копіювання.

Починайте з k get, коли вам потрібна орієнтація. Використовуйте -o wide, коли мають значення розташування, IP чи інформація про вузол. Використовуйте мітки, коли вам треба пов’язати Деплоймент, ReplicaSet, Pod та Сервіс. Мета — зменшити простір проблеми, перш ніж інспектувати деталі.

Terminal window
k get pods
k get pods -o wide
k get deploy,rs,pod
k get pods --show-labels

Використовуйте k describe, коли Kubernetes ухвалює рішення, якого ви не розумієте. Збої планування, помилки завантаження образу, цикли аварійного перезапуску, невдалі монтування та збої проб готовності зазвичай показують корисні події. Події — це впорядковані за часом підказки від контролерів і kubelet. Вони часто пояснюють збій швидше за логи.

Terminal window
k describe pod web
k describe deploy web
k get events --sort-by=.metadata.creationTimestamp

Використовуйте логи, коли контейнер запускається достатньо, щоб записати вивід. Для одноконтейнерного Pod’а k logs pod-name достатньо. Для багатоконтейнерного Pod’а вкажіть -c, щоб уникнути неоднозначності. Якщо контейнер перезапустився, --previous часто містить вивід аварії, який вам потрібен, тоді як поточні логи можуть бути порожніми чи оманливими.

Terminal window
k logs web --tail=20
k logs web -f
k logs multi -c sidecar --tail=20
k logs web --previous

Використовуйте exec, коли вам треба оглянути файли, середовище, DNS чи поведінку локального процесу всередині запущеного контейнера. Тримайте команди exec сфокусованими. Якщо вам потрібен лише один файл, запустіть cat. Якщо вам потрібна оболонка, використовуйте sh, бо багато мінімальних образів не містять bash.

Terminal window
k exec web -- printenv
k exec web -- cat /etc/resolv.conf
k exec -it web -- sh
k exec multi -c sidecar -- ps

JSONPath найкращий, коли завдання просить точне значення. Копіювати з describe повільно й чревато помилками. Grep по YAML може спрацювати, але може також збігтися з неправильним полем. JSONPath робить ваш намір явним: цей об’єкт, цей шлях, цей вивід.

Terminal window
k get pod nginx -o jsonpath='{.status.podIP}'
k get pods -o jsonpath='{.items[*].status.podIP}'
k get pod nginx -o jsonpath='{.spec.containers[0].image}'
k get pod nginx -o jsonpath='{.spec.nodeName}'

Для багатоконтейнерних Pod’ів JSONPath дозволяє вам швидко перевірити імена та образи. Це корисно після редагування YAML, бо Pod може бути готовим (Ready), усе ще використовуючи образ, відмінний від того, який вимагало завдання. Це також допомагає, коли вам треба націлитися на правильний контейнер для логів чи exec.

Terminal window
k get pod multi -o jsonpath='{.spec.containers[*].name}'
k get pod multi -o jsonpath='{.spec.containers[*].image}'

ConfigMap’и та Secret’и потребують уважного видобування, бо форма їхніх даних різниться. Значення ConfigMap — це звичайні рядки в .data. Значення Secret закодовані в base64 у .data, тож зазвичай ви їх декодуєте, перевіряючи фактичне значення. Не декодуйте значення, якщо завдання прямо просить закодоване значення.

Terminal window
k get cm app-config -o jsonpath='{.data.MODE}'
k get secret app-secret -o jsonpath='{.data.password}' | base64 -d

Розглянутий приклад: завдання каже «Запишіть ім’я вузла, на якому заплановано Pod web, у /tmp/web-node.txt». Це не завдання на логування і не завдання на копіювання з describe. Це завдання на точне видобування, тож JSONPath — найшвидший надійний інструмент.

Terminal window
k get pod web -o jsonpath='{.spec.nodeName}' > /tmp/web-node.txt
cat /tmp/web-node.txt

Тепер застосуйте те саме мислення до складнішого завдання: «Знайдіть образ, що використовується контейнером з ім’ям sidecar у Pod’і multi, і запишіть його в /tmp/sidecar-image.txt». Скорочення з першим контейнером тут недостатньо, бо ціль вибирається за ім’ям. Скористайтеся фільтром JSONPath.

Terminal window
k get pod multi -o jsonpath="{.spec.containers[?(@.name=='sidecar')].image}" > /tmp/sidecar-image.txt
cat /tmp/sidecar-image.txt

Підказка для активного навчання: Ваш Pod має два контейнери, app та logger. Завдання просить образ logger. Чому {.spec.containers[0].image} небезпечний, і які докази ви б зібрали, перш ніж записати файл відповіді?

Індексований шлях небезпечний, бо припускає порядок контейнерів. Правки YAML, згенеровані маніфести та скопійовані приклади можуть розмістити контейнери в іншому порядку, ніж ви очікуєте. Перевірте імена контейнерів через {.spec.containers[*].name}, потім видобудьте за фільтром або уважно огляньте маніфест, перш ніж записувати файл відповіді.

Terminal window
k get pod multi -o jsonpath='{.spec.containers[*].name}'
k get pod multi -o jsonpath="{.spec.containers[?(@.name=='logger')].image}"

Ресурси розробника, які варто генерувати швидко

Розділ «Ресурси розробника, які варто генерувати швидко»

Завдання розробника на CKAD раз за разом використовують невеликий набір патернів ресурсів. Вам не потрібно запам’ятовувати кожен об’єкт Kubernetes в API. Вам потрібна вправна генерація та перевірка для ресурсів, що з’являються в доставці застосунків: Pod’и, Деплойменти, Сервіси, Job’и, CronJob’и, ConfigMap’и, Secret’и та прості багатоконтейнерні Pod’и з томами.

Простий Pod корисний для тестування, діагностики та одноразових робочих навантажень. Використовуйте пряме створення, коли Pod сам по собі є запитуваним об’єктом. Використовуйте dry-run, коли Pod потребує правок. Завжди думайте про політику перезапуску, коли команда має завершитися, а не працювати як служба.

Terminal window
k run web --image=nginx
k run sleeper --image=busybox --restart=Never -- sleep 3600
k run web --image=nginx $kdr > web-pod.yaml

Деплоймент — це звичайна стартова точка для реплікованих робочих навантажень застосунку. Він володіє ReplicaSet’ами, які володіють Pod’ами, і він підтримує команди розгортання. Для завдання CKAD Деплоймент часто простіший за окремі Pod’и, бо k rollout status дає чисту точку перевірки.

Terminal window
k create deploy api --image=nginx --replicas=3
k rollout status deploy/api --timeout=90s
k scale deploy api --replicas=2
k set image deploy/api nginx=httpd
k rollout status deploy/api --timeout=90s

Сервіс дає стабільний доступ до вибраних Pod’ів. Найпоширеніший Сервіс на CKAD — це ClusterIP, який надає доступ до робочого навантаження всередині кластера. Сервіс настільки добрий, наскільки добрий його селектор, тож перевіряйте ендпойнти після створення. Сервіс без ендпойнтів не є успішним шляхом до застосунку.

Terminal window
k expose deploy api --port=80 --target-port=80
k get svc api
k get endpointslices -l kubernetes.io/service-name=api

Job виконує завдання до завершення. Використовуйте його, коли завдання просить пакетне завдання, одноразову команду чи статус завершення. Не плутайте Job із Pod’ом, який просто завершується. Контролер Job відстежує завершення та повторні спроби згідно зі специфікацією Job, що зазвичай і має на увазі завдання.

Terminal window
k create job backup --image=busybox -- sh -c 'echo backup complete'
k wait --for=condition=complete job/backup --timeout=90s
k logs job/backup

CronJob планує Job’и. Завдання CKAD можуть просити певний рядок розкладу, наприклад щогодини. Беріть розклад у лапки, щоб оболонка не інтерпретувала зірочки. Перевірте і означення CronJob, і за потреби створіть з нього ручний Job для тестування поведінки.

Terminal window
k create cronjob hourly --image=busybox --schedule="0 * * * *" -- sh -c 'date'
k get cronjob hourly
k create job hourly-manual --from=cronjob/hourly
k wait --for=condition=complete job/hourly-manual --timeout=90s

ConfigMap’и та Secret’и часто з’являються як допоміжні ресурси. Генеруйте їх імперативно з літералів чи файлів, коли можливо, бо команда уникає помилок із лапками в YAML. Потім посилайтеся на них з Pod’а чи Деплойменту. Пам’ятайте, що Secret’и за замовчуванням лише закодовані в base64, а не магічно захищені в кожному операційному сенсі.

Terminal window
k create cm app-config --from-literal=MODE=prod --from-literal=LOG_LEVEL=debug
k create secret generic app-secret --from-literal=password=s3cr3t

Том ConfigMap корисний, коли завдання хоче, щоб файл був змонтований у контейнер. ConfigMap зберігає пари ключ-значення, а том надає ключі як файли. Це відрізняється від envFrom, який надає ключі як змінні середовища. Обирайте на основі потрібної завданню поведінки.

apiVersion: v1
kind: Pod
metadata:
name: config-file-demo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "cat /etc/app/MODE && sleep 3600"]
volumeMounts:
- name: app-config
mountPath: /etc/app
volumes:
- name: app-config
configMap:
name: app-config

Коли вам треба перевірити змонтовані дані ConfigMap, виконайте exec у контейнер та огляньте змонтований шлях. Не припускайте, що монтування спрацювало, лише тому, що Pod виконується (Running). Контейнер може працювати, поки ваш застосунок читає неправильний шлях до файлу. Перевірка має відповідати завданню.

Terminal window
k exec config-file-demo -- cat /etc/app/MODE

Розглянутий приклад: побудуй, надай доступ, протестуй та огляньте

Розділ «Розглянутий приклад: побудуй, надай доступ, протестуй та огляньте»

Цей розглянутий приклад демонструє повний робочий процес, перш ніж ви спробуєте схоже завдання самостійно. Сценарій навмисно звичайний, бо саме на звичайних завданнях дисципліна окуповується. Ви створите простір імен, розгорнете застосунок, надасте до нього доступ, протестуєте його зсередини кластера, оглянете живий образ та приберете.

Сценарій: «У просторі імен workflow-demo створіть Деплоймент з ім’ям web з образом nginx, двома репліками, надайте до нього доступ як до Сервісу ClusterIP на порту 80, перевірте внутрішньокластерний доступ HTTP, потім запишіть образ першого контейнера в /tmp/web-image.txt».

Почніть з роботи над станом простору імен. Це робить решту команд коротшими і зменшує ймовірність того, що об’єкти опиняться в default.

Terminal window
k create ns workflow-demo
k config set-context --current --namespace=workflow-demo
k config view --minify | grep namespace

Створіть Деплоймент і дочекайтеся розгортання. Команда очікування доводить, що контролер досяг бажаного стану, тоді як get pods показує Pod’и-бекенди та їхній статус.

Terminal window
k create deploy web --image=nginx --replicas=2
k rollout status deploy/web --timeout=90s
k get pods -l app=web -o wide

Надайте доступ до Деплойменту і перевірте бекенди Сервісу. Це момент, коли багато учнів зупиняються занадто рано. Об’єкт Сервісу сам по собі не доводить, що трафік дійде до Pod’ів. EndpointSlices показують, чи вибрав Сервіс готові бекенди.

Terminal window
k expose deploy web --port=80 --target-port=80
k get svc web
k get endpointslices -l kubernetes.io/service-name=web

Протестуйте зсередини кластера за допомогою тимчасового Pod’а. Це доводить DNS, маршрутизацію Сервісу та відповідь HTTP з тієї точки зору, що має значення для більшості робочих навантажень Kubernetes.

Terminal window
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://web

Видобудьте запитуваний образ за допомогою JSONPath. Завдання просить значення у файлі, тож не копіюйте з describe. Дозвольте API вивести точне поле.

Terminal window
k get deploy web -o jsonpath='{.spec.template.spec.containers[0].image}' > /tmp/web-image.txt
cat /tmp/web-image.txt

Приберіть стан простору імен після прикладу. На іспиті ви б не видаляли ресурси, які завдання просить лишити для перевірки, але в практичних лабораторіях вам слід прибирати, щоб подальші вправи починалися з відомого стану.

Terminal window
k config set-context --current --namespace=default
k delete ns workflow-demo

Важлива не конкретно Деплоймент nginx. Важлива послідовність. Спершу простір імен, створення найпростішою надійною командою, очікування узгодження контролера, перевірка ендпойнтів Сервісу, тестування зсередини кластера, видобування точних полів та прибирання лише тоді, коли завдання чи лабораторія це дозволяють.


Патерни діагностики рівня senior

Розділ «Патерни діагностики рівня senior»

Діагностика рівня senior — це менше про знання більшої кількості команд і більше про постановку гостріших запитань у правильному порядку. Коли робоче навантаження зазнає збою, відділіть існування об’єкта від прогресу контролера, прогрес контролера від здоров’я Pod’а, здоров’я Pod’а від поведінки застосунку, а поведінку застосунку від мережевого надання доступу. Кожен рівень має свою команду.

Якщо Деплоймент не виробляє готові Pod’и, огляньте розгортання та Pod’и, перш ніж редагувати YAML. Деплоймент може чекати на завантаження образів, провалювати проби, мати недостатньо ресурсів чи проблеми із селектором. rollout status дає симптом, але describe та події зазвичай дають механізм.

Terminal window
k rollout status deploy/api --timeout=30s
k get rs,pod -l app=api
k describe deploy api
k describe pod -l app=api

Якщо Pod у стані Pending, логи не допоможуть, бо контейнер не стартував. Використовуйте describe pod та події, щоб оглянути планування, налаштування томів чи завантаження образу. Якщо Pod виконується (Running), але не готовий (Ready), імовірно, річ у пробах чи готовності застосунку. Якщо Pod у стані CrashLoopBackOff, логи та попередні логи стають корисними.

Terminal window
k get pod failing -o wide
k describe pod failing
k logs failing --previous

Якщо Сервіс не маршрутизує трафік, огляньте селектори та ендпойнти, перш ніж зазирати у внутрішнощі застосунку. Поширений збій — Деплоймент із міткою app: api, тоді як селектор Сервісу очікує run: api. Обидва об’єкти валідні. Вони просто не з’єднуються. Kubernetes не вгадуватиме ваш намір.

Terminal window
k get svc api -o yaml
k get pods --show-labels
k get endpointslices -l kubernetes.io/service-name=api

Якщо змінної середовища бракує, перевірте об’єкт-джерело та специфікацію Pod’а. ConfigMap може існувати з неправильним ключем. Pod може посилатися на неправильне ім’я ConfigMap. Деплоймент може бути оновлений, поки старі Pod’и ще працюють. Мають значення і живий шаблон Pod’а, і фактичне середовище Pod’а.

Terminal window
k get cm app-config -o yaml
k get deploy api -o yaml
k exec deploy/api -- printenv | grep MODE || true

Якщо змонтованого файлу бракує, перевірте обидва боки монтування. Специфікація Pod’а має означувати том, контейнер має монтувати цей том, а вихідний ConfigMap чи Secret має містити очікуваний ключ. Помилка на будь-якому рівні дає інший симптом, тож інспектуйте кожен рівень свідомо.

Terminal window
k describe pod config-file-demo
k get cm app-config -o yaml
k exec config-file-demo -- ls -la /etc/app

Якщо Job не завершується, перевірте Pod’и, якими володіє Job. Об’єкт Job каже вам про кількість завершень і стан повторних спроб, але логи Pod’а кажуть, чому команда провалилася. Пам’ятайте, що Pod’и Job’а часто завершуються швидко, тож використовуйте мітки та логи з Job’а, а не припускайте довготривалий процес.

Terminal window
k get job backup
k get pods -l job-name=backup
k logs job/backup
k describe job backup

Якщо CronJob не створює Job’и, перевірте розклад, стан призупинення та останні події. Для тестування поведінки створіть ручний Job із CronJob. Це уникає очікування наступного запланованого часу й доводить, чи працює сама команда шаблону.

Terminal window
k get cronjob hourly -o yaml
k create job hourly-test --from=cronjob/hourly
k wait --for=condition=complete job/hourly-test --timeout=90s
k logs job/hourly-test

Принцип діагностики незмінний: локалізуйте рівень, що володіє поведінкою, потім скористайтеся командою, яка розкриває цей рівень. Не використовуйте логи для планування. Не використовуйте YAML Сервісу для аварій контейнера. Не використовуйте JSONPath, коли зрозумілий людині потік подій пояснив би збій швидше.


  • --dry-run=client -o yaml генерує маніфест без створення об’єкта: Це дозволяє вам поєднати швидкі імперативні каркаси з уважними правками YAML, що зазвичай швидше й безпечніше за написання вкладених маніфестів Kubernetes із порожнього файлу.

  • --restart=Never змінює політику перезапуску Pod’а для одноразових тестів: Це має значення для тимчасових командних Pod’ів, бо успішна команда має чисто завершитися, а не перезапускатися у спосіб, що заплутує вашу перевірку.

  • Сервіс може існувати, маршрутизуючи до жодного Pod’а: Селектор Сервісу має збігатися з мітками на готових Pod’ах, тож EndpointSlices чи ендпойнти — це доказ того, що трафіку є куди йти.

  • JSONPath — це інструмент точності, а не просто опція форматування: Він найсильніший, коли завдання просить одне точне поле, особливо коли ви записуєте файли відповідей або вибираєте іменований контейнер із багатоконтейнерного Pod’а.


ПомилкаЧому це шкодитьКращий робочий процес
Забути задати чи передати простір імен на початку завданняОб’єкти створюються правильно, але в неправильному просторі імен, що часто виглядає як загадковий збій перевіряльникаПочинайте кожне завдання з k config set-context --current --namespace=NAME або послідовно використовуйте -n NAME
Використання прямих імперативних команд для вкладених вимог Pod’аБагатоконтейнерні Pod’и, томи, проби та посилання на середовище стають незручними чи неможливими, щоб виразити їх точноЗгенеруйте базовий маніфест через dry-run, відредагуйте вкладені поля, перевірте, потім застосуйте
Забути --restart=Never на одноразових тестових Pod’ахКоманда, що має виконатися один раз, може перезапуститися чи лишити по собі заплутаний стан Pod’аВикористовуйте k run test --image=... --rm -it --restart=Never -- COMMAND для тимчасових перевірок
Перевірка лише того, що об’єкт Сервісу існуєСервіс без відповідних ендпойнтів не доводить, що трафік дійде до будь-яких Pod’ів-бекендівПеревіряйте селектори, мітки Pod’ів та EndpointSlices після створення чи діагностики Сервісу
Ручне копіювання значень із describe, коли потрібна точна відповідь у файліРучне копіювання повільне й може захопити неправильний рядок чи зайве форматуванняВикористовуйте перенаправлення JSONPath, наприклад k get pod web -o jsonpath='{.spec.nodeName}' > /tmp/answer.txt
Перегляд логів для Pod’ів, які не стартувалиPending Pod’и не мають корисних логів контейнера, тож справжня проблема — у плануванні, томах чи завантаженні образуВикористовуйте k describe pod та впорядковані події перед логами, коли Pod не виконується (Running)
Редагування YAML на неправильному рівні відступуKubernetes відхиляє маніфест або приймає об’єкт, що поводиться інакше, ніж задуманоВикористовуйте k explain FIELD.PATH, уважно копіюйте наявні блоки та запускайте k apply --dry-run=server -f file.yaml
Залишення тимчасових ресурсів для діагностики розкиданими по простору іменПодальший вивід get pods стає галасливим, і ви можете сплутати тестові Pod’и з робочимиВіддавайте перевагу --rm для інтерактивних тестів і видаляйте іменовані Pod’и для діагностики через --ignore-not-found після перерваних сесій

  1. Ваше екзаменаційне завдання каже створити Деплоймент з ім’ям checkout у просторі імен shop, надати до нього доступ усередині на порту 80 та перевірити, що Pod у тому самому просторі імен може його досягти. Ви створюєте Деплоймент і Сервіс, але ваш тестовий Pod повідомляє, що не може зарезолвити checkout. Що ви перевіряєте першим і які команди ви б запустили?

    Відповідь

    Спершу перевірте розташування простору імен, бо імена DNS за замовчуванням обмежені простором імен. Запустіть k get deploy,svc,pod -n shop, щоб підтвердити, що об’єкти існують там, де очікує завдання, потім запустіть тимчасовий тестовий Pod у тому самому просторі імен через k run test --image=busybox --rm -it --restart=Never -n shop -- nslookup checkout. Якщо Сервісу немає в shop, пошукайте по всіх просторах імен через k get svc -A | grep checkout || true, відтворіть його в shop та видаліть лише той об’єкт, що опинився не там, якщо ви впевнені, що він з’явився через вашу помилку. Це перевіряє результат модуля — оцінювання правильності простору імен перед глибшою діагностикою.

  2. Ви згенерували маніфест Pod’а для api через k run api --image=nginx $kdr, потім відредагували його, додавши сайдкар busybox. Pod виконується (Running), але k logs api повертає помилку, що просить обрати контейнер. Як ви оглянете логи сайдкара та доведете, що обидва контейнери присутні?

    Відповідь

    Багатоконтейнерні Pod’и потребують вибору контейнера для логів, коли Kubernetes не може зрозуміти, який контейнер ви маєте на увазі. Спершу доведіть імена контейнерів через k get pod api -o jsonpath='{.spec.containers[*].name}', потім огляньте сайдкар через k logs api -c sidecar --tail=20. Якщо сайдкар аварійно завершується, скористайтеся k logs api -c sidecar --previous після перевірки k describe pod api. Ключове рішення — націлюватися на іменований контейнер, а не трактувати багатоконтейнерний Pod як одноконтейнерний.

  3. Завдання просить вас створити Job з ім’ям report, який виводить daily report complete, а потім записати доказ, що він завершився. Ви випадково запускаєте звичайний Pod, бо пам’ятаєте образ і команду, але не тип контролера. Що не так із таким розв’язком і як ви це виправите?

    Відповідь

    Pod, що завершується, — це не те саме, що Job. Завдання просить контролер Job, який відстежує завершення та повторні спроби. Виправте, створивши справжній Job: k create job report --image=busybox -- sh -c 'echo daily report complete', потім перевірте через k wait --for=condition=complete job/report --timeout=90s та k logs job/report. Якщо помилковий Pod не пов’язаний із перевіркою, приберіть його через k delete pod report --ignore-not-found або видаліть конкретне ім’я помилкового Pod’а. Це застосовує рішення робочого процесу між одноразовими Pod’ами та керованою контролером пакетною роботою.

  4. Ваш Сервіс backend існує, і DNS резолвиться з тимчасового Pod’а, але запити HTTP зависають. Pod’и Деплойменту виконуються (Running). Які докази ви б зібрали, перш ніж редагувати образ контейнера чи перезапускати Pod’и?

    Відповідь

    Спершу зберіть докази селектора та ендпойнтів Сервісу. Запустіть k describe svc backend, k get pods --show-labels та k get endpointslices -l kubernetes.io/service-name=backend -o wide. Якщо EndpointSlices порожні, селектор Сервісу не збігається з готовими Pod’ами, тож редагування образу не розв’язало б проблему маршрутизації. Якщо ендпойнти існують, тоді огляньте цільові порти, готовність та логи застосунку через k describe pod -l app=backend та k logs -l app=backend --tail=20. Важливий крок міркування — відділення маршрутизації Сервісу від поведінки застосунку.

  5. Завдання просить вас записати образ, що використовується контейнером з ім’ям logger у Pod’і webapp, у /tmp/logger-image.txt. Pod має два контейнери, і logger не гарантовано йде першим. Яку команду вам слід використати і чому індексований JSONPath тут ризикований?

    Відповідь

    Використовуйте фільтр JSONPath за іменем: k get pod webapp -o jsonpath="{.spec.containers[?(@.name=='logger')].image}" > /tmp/logger-image.txt. Індексований вираз, як-от {.spec.containers[0].image}, ризикований, бо припускає, що порядок контейнерів відповідає вашому очікуванню. Багатоконтейнерні маніфести часто редагуються копіюванням блоків, а порядок — це не те саме, що ідентичність. Спершу перевірте імена через k get pod webapp -o jsonpath='{.spec.containers[*].name}', якщо ви не впевнені.

  6. Ви створюєте ConfigMap app-config із MODE=prod, потім створюєте Pod, що має вивести змінну й заснути. Pod стартує, але k exec env-demo -- printenv | grep MODE нічого не показує. Що вам слід оглянути і яка помилка розміщення YAML найімовірніша?

    Відповідь

    Огляньте і ConfigMap, і специфікацію Pod’а: k get cm app-config -o yaml та k get pod env-demo -o yaml. Імовірна помилка YAML — розміщення envFrom на неправильному рівні, наприклад під spec замість конкретного контейнера. envFrom належить під spec.containers[], бо змінні середовища впроваджуються в процес контейнера. Скористайтеся k explain pod.spec.containers.envFrom, щоб підтвердити шлях, виправте маніфест, застосуйте його та за потреби відтворіть Pod, бо змінні середовища Pod’а задаються під час старту контейнерів.

  7. Вам треба додати пробу готовності до Деплойменту. Ви знаєте образ і кількість реплік, тож починаєте з k create deploy. Чи слід вам далі шукати імперативний прапорець для проби, чи перемкнути робочий процес? Опишіть найшвидший надійний шлях.

    Відповідь

    Перемкніться на згенерований YAML і відредагуйте маніфест. Запустіть k create deploy web --image=nginx --replicas=2 --dry-run=client -o yaml > web.yaml, додайте readinessProbe під контейнером у spec.template.spec.containers, перевірте через k apply --dry-run=server -f web.yaml, потім застосуйте та перевірте через k rollout status deploy/web --timeout=90s та k describe pod -l app=web. Це швидше й безпечніше за полювання на прапорець, бо проби — це вкладені поля контейнера, а розміщення в YAML — природний робочий процес.

  8. Під час хронометрованої практики Pod застряг у стані Pending, і колега пропонує одразу перевірити k logs. Що вам слід зробити натомість і чому?

    Відповідь

    Використовуйте k describe pod POD_NAME та k get events --sort-by=.metadata.creationTimestamp перед логами. Pending означає, що контейнер не стартував, тож логів контейнера для читання може не бути. Імовірні причини — обмеження планування, проблеми з томами, налаштування завантаження образу чи проблеми допуску, і вони з’являються в умовах Pod’а та подіях. Логи стають корисними після старту контейнера або після його аварії; до того правильний рівень для огляду — це події kubelet і планувальника.


Завдання: Відпрацюйте повний робочий процес розробника на CKAD, створюючи, надаючи доступ, тестуючи, інспектуючи та діагностуючи ресурси в тимчасовому просторі імен. Вправа спроєктована спершу як кероване відпрацювання, а потім як самостійне. Не пропускайте команди перевірки; саме вони перетворюють набирання команд на операційну майстерність.

Частина 1: Підготуйте простір імен і підтвердьте свій робочий процес

Перш ніж створювати робочі навантаження, ізолюйте вправу у власному просторі імен. Це робить прибирання безпечним, а помилки з простором імен очевидними. Використовуйте аліас k лише після підтвердження, що він існує, і повертайтеся до kubectl, якщо у вашій оболонці аліас не налаштований.

Terminal window
alias k='kubectl'
export kdr='--dry-run=client -o yaml'
k create ns ckad-workflow
k config set-context --current --namespace=ckad-workflow
k config view --minify | grep namespace

Критерії успіху для Частини 1:

  • k розгортається в kubectl, або ви свідомо використовуєте kubectl натомість.
  • echo "$kdr" виводить --dry-run=client -o yaml.
  • Поточний простір імен — ckad-workflow.
  • k get pods виконується без помилки простору імен.

Частина 2: Згенеруйте та застосуйте маніфест Деплойменту

Згенеруйте маніфест Деплойменту замість написання з нуля. Це закріплює патерн, що дозволяє Kubernetes створити структуру селектора та міток шаблону за вас. Після генерації огляньте файл, перш ніж застосовувати його.

Terminal window
k create deploy api --image=nginx --replicas=2 $kdr > api-deploy.yaml
sed -n '1,120p' api-deploy.yaml
k apply --dry-run=server -f api-deploy.yaml
k apply -f api-deploy.yaml
k rollout status deploy/api --timeout=90s
k get pods -l app=api -o wide

Критерії успіху для Частини 2:

  • api-deploy.yaml містить kind: Deployment.
  • Деплоймент має дві бажані репліки.
  • k rollout status deploy/api завершується успішно.
  • k get pods -l app=api показує два Pod’и або показує прогрес розгортання, який ви можете пояснити.

Частина 3: Надайте доступ до Деплойменту та протестуйте зсередини кластера

Створіть Сервіс ClusterIP із Деплойменту, потім перевірте маршрутизацію з тимчасового Pod’а. Не трактуйте створення Сервісу як достатнє. Перевірте EndpointSlices, щоб знати, що Сервіс має бекенди.

Terminal window
k expose deploy api --port=80 --target-port=80
k get svc api
k get endpointslices -l kubernetes.io/service-name=api
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://api

Критерії успіху для Частини 3:

  • Сервіс api існує у просторі імен ckad-workflow.
  • EndpointSlices показують адреси бекендів для Сервісу.
  • Тимчасовий тест BusyBox може отримати відповідь HTTP від http://api.
  • Після завершення команди не лишається завершеного Pod’а test, якщо тільки команду не перервали.

Частина 4: Створіть багатоконтейнерний Pod зі згенерованого YAML

Згенеруйте базовий Pod, потім відредагуйте його в багатоконтейнерний Pod. Мета — відпрацювати момент, коли імперативного створення перестає бути достатньо й редагування маніфеста стає правильним робочим процесом.

Terminal window
k run webapp --image=nginx $kdr > webapp-pod.yaml

Замініть згенерований файл цією фінальною формою, якщо ви практикуєтеся неінтерактивно, або відредагуйте свій згенерований файл вручну, щоб він збігся з нею.

apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
run: webapp
spec:
volumes:
- name: logs
emptyDir: {}
containers:
- name: webapp
image: nginx
volumeMounts:
- name: logs
mountPath: /var/log/nginx
- name: logger
image: busybox
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: logs
mountPath: /var/log/nginx

Перевірте, застосуйте та переконайтеся в обох контейнерах. Якщо готовність триває довше, ніж очікувалося, огляньте Pod, а не застосовуйте той самий файл повторно.

Terminal window
k apply --dry-run=server -f webapp-pod.yaml
k apply -f webapp-pod.yaml
k wait --for=condition=Ready pod/webapp --timeout=90s
k get pod webapp -o jsonpath='{.spec.containers[*].name}'
k logs webapp -c logger --tail=5

Критерії успіху для Частини 4:

  • webapp має рівно контейнери webapp та logger.
  • Обидва контейнери монтують том logs за шляхом /var/log/nginx.
  • k wait --for=condition=Ready pod/webapp успішний, або ви можете пояснити збій з k describe pod webapp.
  • Ви можете отримати логи з контейнера logger за допомогою -c logger.

Частина 5: Видобудьте точні поля за допомогою JSONPath

Використовуйте JSONPath для завдань у стилі файлу відповіді. Ця частина тренує точність. Не копіюйте значення вручну з describe.

Terminal window
k get pod webapp -o jsonpath="{.spec.containers[?(@.name=='logger')].image}" > /tmp/logger-image.txt
k get pod webapp -o jsonpath='{.spec.nodeName}' > /tmp/webapp-node.txt
cat /tmp/logger-image.txt
cat /tmp/webapp-node.txt

Критерії успіху для Частини 5:

  • /tmp/logger-image.txt містить busybox.
  • /tmp/webapp-node.txt містить ім’я вузла, на якому заплановано webapp.
  • Ви використали фільтр JSONPath за іменем для образу logger, а не припускали порядок контейнерів.
  • Ви можете пояснити, чому JSONPath безпечніший за ручне копіювання для точних файлів відповідей.

Частина 6: Додайте дані ConfigMap і перевірте їх усередині Pod’а

Створіть ConfigMap і Pod, що має споживати його як змінні середовища. Ця частина закріплює розміщення поля під специфікацією контейнера.

Terminal window
k create cm app-config --from-literal=MODE=prod --from-literal=LOG_LEVEL=debug

Створіть env-demo.yaml з таким вмістом.

apiVersion: v1
kind: Pod
metadata:
name: env-demo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "env && sleep 3600"]
envFrom:
- configMapRef:
name: app-config

Застосуйте та перевірте зсередини запущеного контейнера.

Terminal window
k apply --dry-run=server -f env-demo.yaml
k apply -f env-demo.yaml
k wait --for=condition=Ready pod/env-demo --timeout=90s
k exec env-demo -- printenv | grep MODE
k exec env-demo -- printenv | grep LOG_LEVEL

Критерії успіху для Частини 6:

  • ConfigMap app-config містить ключі MODE та LOG_LEVEL.
  • Pod env-demo досягає стану Ready.
  • MODE=prod з’являється в середовищі контейнера.
  • LOG_LEVEL=debug з’являється в середовищі контейнера.

Частина 7: Створіть і перевірте Job

Створіть Job із командою після межі --. Дочекайтеся завершення та огляньте логи з Job’а. Це чистий пакетний робочий процес, якого CKAD очікує, коли завдання просить Job.

Terminal window
k create job report --image=busybox -- sh -c 'echo daily report complete'
k wait --for=condition=complete job/report --timeout=90s
k logs job/report
k get job report

Критерії успіху для Частини 7:

  • Job report існує та досягає Complete.
  • k logs job/report виводить daily report complete.
  • Ви можете пояснити, чому Job відрізняється від звичайного Pod’а, що виконує ту саму команду.
  • Ви знаєте, яку команду використати, якщо Job провалиться і вам треба оглянути створений Pod.

Частина 8: Прибирайте свідомо

На іспиті не видаляйте ресурси, які мають лишитися для перевірки. У цій практичній вправі прибирання — частина відновлення відомого стану. Скиньте контекст простору імен, перш ніж видаляти простір імен, щоб подальші команди не вказували на простір імен, що зникає.

Terminal window
k config set-context --current --namespace=default
k delete ns ckad-workflow
k get ns ckad-workflow

Критерії успіху для Частини 8:

  • Ваш поточний простір імен скинуто до default.
  • Простір імен ckad-workflow видалено або він у стані завершення (terminating).
  • Ви не видалили непов’язані простори імен чи ресурси.
  • Ви можете повторити вправу з чистого стану.

Практичні вправи (drills)

Розділ «Практичні вправи (drills)»

Вправа 1: Перевірка аліасів (Ціль: 2 хвилини)

Розділ «Вправа 1: Перевірка аліасів (Ціль: 2 хвилини)»

Ця вправа про впевненість у налаштуванні вашої оболонки. Запустіть кожну команду й поясніть, що вона доводить. Якщо якогось аліаса бракує, використовуйте повну команду kubectl і рухайтеся далі.

Terminal window
type k
echo "$kdr"
k version --client
k get ns

Критерії успіху:

  • Ви знаєте, чи налаштований k.
  • Ви знаєте, чи налаштований kdr.
  • Ви можете продовжити з повними прапорцями, якщо якогось скорочення бракує.

Вправа 2: Швидкість генерації YAML (Ціль: 6 хвилин)

Розділ «Вправа 2: Швидкість генерації YAML (Ціль: 6 хвилин)»

Згенеруйте YAML для поширених ресурсів розробника, не застосовуючи їх. Коротко огляньте кожен файл, щоб пов’язати прапорці команд зі структурою маніфеста.

Terminal window
k run nginx --image=nginx $kdr > /tmp/pod.yaml
k create deploy web --image=nginx --replicas=2 $kdr > /tmp/deploy.yaml
k create svc clusterip web --tcp=80:80 $kdr > /tmp/svc.yaml
k create job backup --image=busybox $kdr -- echo done > /tmp/job.yaml
k create cronjob hourly --image=busybox --schedule="0 * * * *" $kdr -- date > /tmp/cronjob.yaml
k create cm app-config --from-literal=key=value $kdr > /tmp/cm.yaml
k create secret generic app-secret --from-literal=password=secret $kdr > /tmp/secret.yaml

Критерії успіху:

  • Кожен згенерований файл містить очікуваний kind.
  • Job та CronJob містять задуману команду.
  • Ви можете визначити, які згенеровані маніфести безпечно застосувати одразу, а які потребували б правок для багатшого завдання.

Вправа 3: Перемикання просторів імен (Ціль: 3 хвилини)

Розділ «Вправа 3: Перемикання просторів імен (Ціль: 3 хвилини)»

Відпрацюйте переміщення між просторами імен, не втрачаючи слід контексту. Це не ефектно, але запобігає деяким із найдорожчих помилок.

Terminal window
k create ns alpha
k create ns beta
k config set-context --current --namespace=alpha
k run marker --image=nginx
k get pods
k get pods -n beta
k config set-context --current --namespace=beta
k get pods
k get pods -n alpha
k config set-context --current --namespace=default
k delete ns alpha beta

Критерії успіху:

  • Ви можете спрогнозувати, де з’явиться marker, перш ніж запускати кожну команду get.
  • Ви розумієте різницю між поточним простором імен та явним -n.
  • Ви скидаєте контекст до завершення прибирання.

Вправа 4: Швидкість багатоконтейнерних Pod’ів (Ціль: 5 хвилин)

Розділ «Вправа 4: Швидкість багатоконтейнерних Pod’ів (Ціль: 5 хвилин)»

Створіть багатоконтейнерний Pod, використовуючи генерацію плюс редагування. Сенс не в тому, щоб запам’ятати фінальний YAML. Сенс — відпрацювати створення валідної стартової точки, додавання сайдкара на правильному відступі та перевірку поведінки, специфічної для контейнера.

Terminal window
k create ns multi-drill
k config set-context --current --namespace=multi-drill
k run multi --image=nginx $kdr > /tmp/multi.yaml

Відредагуйте /tmp/multi.yaml так, щоб він містив другий контейнер.

apiVersion: v1
kind: Pod
metadata:
name: multi
labels:
run: multi
spec:
containers:
- name: main
image: nginx
- name: sidecar
image: busybox
command: ["sleep", "3600"]

Застосуйте та перевірте.

Terminal window
k apply --dry-run=server -f /tmp/multi.yaml
k apply -f /tmp/multi.yaml
k wait --for=condition=Ready pod/multi --timeout=90s
k get pod multi -o jsonpath='{.spec.containers[*].name}'
k exec multi -c sidecar -- ps
k config set-context --current --namespace=default
k delete ns multi-drill

Критерії успіху:

  • Обидва контейнери перелічені через JSONPath.
  • k exec явно націлюється на контейнер сайдкара.
  • Ви можете пояснити, чому команда сайдкара має продовжувати працювати, щоб контейнер лишався готовим (Ready).

Вправа 5: Діагностика Сервісу (Ціль: 7 хвилин)

Розділ «Вправа 5: Діагностика Сервісу (Ціль: 7 хвилин)»

Навмисно створіть розбіжність селектора, потім продіагностуйте її. Ця вправа навчає, чому існування Сервісу недостатньо.

Terminal window
k create ns svc-debug
k config set-context --current --namespace=svc-debug
k create deploy api --image=nginx
k rollout status deploy/api --timeout=90s
k create svc clusterip api --tcp=80:80
k patch svc api -p '{"spec":{"selector":{"app":"wrong"}}}'
k get svc api
k get endpointslices -l kubernetes.io/service-name=api

Тепер відновіть селектор і перевірте трафік.

Terminal window
k patch svc api -p '{"spec":{"selector":{"app":"api"}}}'
k get endpointslices -l kubernetes.io/service-name=api
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://api
k config set-context --current --namespace=default
k delete ns svc-debug

Критерії успіху:

  • Ви спостерігаєте порожні чи неправильні ендпойнти, поки селектор неправильний.
  • Ви відновлюєте Сервіс, не відтворюючи Деплоймент.
  • Ви перевіряєте доступ HTTP зсередини простору імен.

Вправа 6: Видобування через JSONPath (Ціль: 4 хвилини)

Розділ «Вправа 6: Видобування через JSONPath (Ціль: 4 хвилини)»

Створіть Pod і видобудьте кілька полів. До кінця ця вправа має відчуватися механічною, бо точне видобування полів з’являється в багатьох практичних завданнях.

Terminal window
k create ns jsonpath-drill
k config set-context --current --namespace=jsonpath-drill
k run nginx --image=nginx
k wait --for=condition=Ready pod/nginx --timeout=90s
k get pod nginx -o jsonpath='{.status.podIP}'
echo
k get pod nginx -o jsonpath='{.spec.containers[0].image}'
echo
k get pod nginx -o jsonpath='{.spec.nodeName}'
echo
k get pod nginx -o jsonpath='{.status.phase}'
echo
k config set-context --current --namespace=default
k delete ns jsonpath-drill

Критерії успіху:

  • Ви можете видобути IP Pod’а, образ, ім’я вузла та фазу без describe.
  • Ви додаєте echo чи форматування за потреби, щоб виводи не зливалися.
  • Ви розумієте, коли шлях за індексом прийнятний, а коли фільтр за іменем безпечніший.

Вправа 7: Повний робочий процес розробника (Ціль: 10 хвилин)

Розділ «Вправа 7: Повний робочий процес розробника (Ціль: 10 хвилин)»

Симулюйте компактне завдання CKAD від початку до кінця. Створіть простір імен, побудуйте Деплоймент, надайте до нього доступ, змонтуйте дані ConfigMap в окремий Pod, видобудьте файл відповіді та приберіть лише після перевірки.

Terminal window
k create ns full-drill
k config set-context --current --namespace=full-drill
k create deploy site --image=nginx --replicas=2
k rollout status deploy/site --timeout=90s
k expose deploy site --port=80 --target-port=80
k get endpointslices -l kubernetes.io/service-name=site
k create cm site-config --from-literal=SITE_MODE=practice

Створіть site-env.yaml.

apiVersion: v1
kind: Pod
metadata:
name: site-env
spec:
containers:
- name: checker
image: busybox
command: ["sh", "-c", "env && sleep 3600"]
envFrom:
- configMapRef:
name: site-config

Застосуйте, перевірте та видобудьте.

Terminal window
k apply --dry-run=server -f site-env.yaml
k apply -f site-env.yaml
k wait --for=condition=Ready pod/site-env --timeout=90s
k exec site-env -- printenv | grep SITE_MODE
k run test --image=busybox --rm -it --restart=Never -- wget -qO- http://site
k get deploy site -o jsonpath='{.spec.template.spec.containers[0].image}' > /tmp/site-image.txt
cat /tmp/site-image.txt
k config set-context --current --namespace=default
k delete ns full-drill

Критерії успіху:

  • Деплоймент досягає успішного розгортання.
  • Сервіс має ендпойнти й відповідає на внутрішньокластерний HTTP.
  • Значення ConfigMap видно всередині site-env.
  • /tmp/site-image.txt містить очікуваний рядок образу.
  • Ви можете пояснити кожну команду перевірки в послідовності.

Модуль 1.1: Образи контейнерів — Збирайте, тегуйте, інспектуйте та обирайте образи контейнерів для завдань застосунків на CKAD.

  • kubernetes.io: команди kubectl — Офіційний згенерований довідник команд kubectl показує точний синтаксис використання як для create job, так і для create cronjob, включно з межею -- та прапорцем розкладу CronJob.
  • kubernetes.io: простори імен — Сторінка завдань про простори імен прямо охоплює обмеження простором імен, --namespace, kubectl config set-context --current --namespace=... та поведінку простору імен default.
  • kubernetes.io: kubectl run — Довідник kubectl run явно документує клієнтський dry-run як друк відповідного об’єкта без його створення.
  • kubernetes.io: deployment — Документація про Деплоймент явно стверджує, що .spec.selector має збігатися з .spec.template.metadata.labels.
  • kubernetes.io: kubectl expose — Автозгенерований довідник kubectl expose каже, що він використовує селектор наданого ресурсу як селектор для нового Сервісу.
  • kubernetes.io: kubectl explain — Офіційний довідник kubectl explain стверджує, що інформація про поля отримується з сервера у форматі OpenAPI.
  • kubernetes.io: configmap — Документація про ConfigMap показує volumes на рівні Pod’а, volumeMounts для кожного контейнера та envFrom.configMapRef, вкладені під специфікацію контейнера.
  • kubernetes.io: kubectl apply — Довідник kubectl apply явно означує --dry-run=server як надсилання запиту на стороні сервера без збереження ресурсу та документує поведінку перевірки на стороні сервера.
  • kubernetes.io: debug service — Офіційний посібник із діагностики сервісу проводить через перевірку EndpointSlices, відповідність селектора міткам та вирівнювання targetPort, коли Сервіс не маршрутизує трафік.
  • kubernetes.io: kubectl logs — Автозгенерований довідник kubectl logs точно означує поведінку за замовчуванням для одного контейнера, селектор контейнера -c та --previous.
  • kubernetes.io: job — Концептуальна сторінка про Job’и прямо пояснює, що Job створює Pod’и, повторює виконання, доки не відбудеться потрібна кількість успішних завершень, та протиставляє Job’и звичайним Pod’ам.
  • kubernetes.io: secret — Концептуальна сторінка про Secret’и стверджує, що значення data — це закодовані в base64 рядки, та явно застерігає, що це лише приховує значення, а не захищає їх.