93. Проверочный список навыков и итоговый практический экзамен
Незнакомый термин? Откройте словарь Kubernetes и терминов курса.
Назначение, предварительные знания и результаты обучения
Это не список «знаю термин». Ставьте [x], только если выполнили команду,
сохранили нечувствительные доказательства и объяснили наблюдаемое поведение.
Нужны все главы и итоговый проект.
После проверочного списка у вас будет:
- проверяемая матрица навык → команда → доказательство → объяснение;
- 90-минутный практический экзамен;
- список пробелов промышленной эксплуатации, которые локальный kind не может закрыть;
- объективное решение: повторить основы, перейти к
job-readyили к треку промышленной эксплуатации.
Требования к доказательствам
Для каждого пункта запишите:
Дата/версия кластера/контекст:
Команда(ы) и код выхода:
Наблюдаемый инвариант (без скопированного ожидаемого вывода):
Почему это произошло (контроллер/путь данных):
Сбой/восстановление:
Ограничение:
Не прикладывайте kubeconfig, токены, данные Secret или непроверенный пакет поддержки. Снимок экрана без команды, объекта и версии слабее текстового доказательства.
1. Окружение и модель API
- Я проверил ОС, CPU, RAM, диск, cgroup и сервер провайдера контейнеров.
- Я проверил контрольную сумму закреплённых исполняемых файлов
kubectlи kind. - Я создал и удалил конкретный
kube-course, не изменив чужой кластер. - Я могу объяснить путь
kubectl→ сервер API → etcd/контроллер. - Я показал
spec.replicas,status.readyReplicas, generation и observedGeneration. - Я доказал цепочку владения Deployment → ReplicaSet → Pod.
- Я удалил управляемый Pod и назвал контроллер, создавший замену.
- Я отличаю метку, селектор, аннотацию, namespace и ownerReference.
Команды для доказательств:
kubectl version
kubectl get deployment python-api -n kube-course -o yaml
kubectl get rs,pod -n kube-course \
-l app.kubernetes.io/instance=course -o jsonpath=...
Критерий: объяснить, почему повторное применение не удваивает число реплик.
2. Рабочие нагрузки и жизненный цикл
- Я запускал отдельный Pod и видел, что после удаления он не заменяется.
- Я запускал Deployment и просматривал историю rollout.
- Я получил текущее и предыдущее состояние контейнера и restartCount.
- Я выполнил Job до
Completeи объяснил повторы и идемпотентность. - Я показал порядок и отказ init-контейнера.
- Я объясняю нативный сайдкар со стабильным статусом с v1.33 и эфемерный контейнер со стабильным статусом с v1.25.
- Я выбираю Deployment, StatefulSet, DaemonSet или Job по контракту.
- Я не называю StatefulSet высокой доступностью базы данных.
Критерий: для новой рабочей нагрузки за две минуты выбрать контроллер и назвать два вида отказа.
3. Конфигурация и секреты
- Я обновил ConfigMap и наблюдал старое окружение и новый смонтированный файл.
- Я вызвал управляемый rollout и увидел новое окружение.
- Я создавал Secret без сохранения и вывода настоящего значения.
- Я доказал, что base64 обратим и не является шифрованием, не раскрывая секрет.
- Я вызвал
CreateContainerConfigErrorотсутствующим ключом и нашёл Event. - Я объясняю шифрование хранимых данных через KMS и раскрытие во время исполнения.
- Я могу спроектировать внешнюю ротацию и обновление секрета.
Критерий: предсказать UID Pod, число перезапусков, окружение и файл после изменения ConfigMap.
4. Сеть
- Я получил ClusterIP Service и готовые EndpointSlices.
- Я разрешил FQDN Service из Pod внутри кластера.
- Я проверил HTTP через Service из кластера, а не только port-forward.
- Я сломал селектор, доказал пустой EndpointSlice и исправил без перезапуска.
- Я различаю
port,targetPort, порт контейнера и именованный порт. - Я объясняю CNI, плоскость данных Service и CoreDNS как разные уровни.
- Я проверил поддержку NetworkPolicy в CNI разрешённым и запрещённым контрольными запросами.
- Я не называю принятую NetworkPolicy применённой без контрольной проверки.
- Я объясняю замороженный API Ingress и его контроллер, а также CRD и контроллер Gateway API.
- Я получил реальный status и запрос внешней точки входа либо записал непроверенный пробел зависимости.
Критерий: нарисовать путь запроса от клиента до процесса Python и доказательство каждого перехода.
5. Хранение данных
- Я сравнил жизненные циклы файловой системы контейнера,
emptyDirи PVC. - Я получил PVC
Boundи доказательства PV, класса, provisioner и политики возврата. - Я сохранил счётчик после замены Pod.
- Я вызвал непривязанный PVC и диагностировал его по Events PVC.
- Я объясняю RWO (узел) против RWOP (Pod).
- Я не считаю режим доступа блокировкой или репликацией приложения.
- Я записал различия снимка, резервной копии и восстановления.
- Я знаю, что снимок etcd не содержит байты PVC.
- Я обосновал Deployment без состояния и внешнюю БД для итогового проекта.
Критерий: назвать судьбу данных при перезапуске контейнера, удалении Pod, удалении PVC с Delete/Retain и потере кластера.
6. Проверки, ресурсы и планирование
- Я показал отдельные эффекты startup, readiness и liveness.
- Я вызвал drain readiness и наблюдал переход EndpointSlice.
- Я проверил корректное завершение, preStop и бюджет SIGTERM.
- Я получил класс QoS и объяснил критерии.
- Я вызвал FailedScheduling невыполнимым запросом ресурсов.
- Я вызвал OOMKilled и получил доказательства причины и кода завершения.
- Я различаю ограничение CPU и OOM памяти.
- Я объясняю LimitRange/ResourceQuota.
- Я использовал топологическое распределение и метки узлов и объяснил обязательные и предпочтительные правила.
- Я объясняю taint/toleration без «toleration притягивает».
Критерий: по симптому Pending назвать первые три команды доказательств без журналов.
7. Развёртывание, масштабирование и нарушения доступности
- Я провёл успешный rollout и получил историю ревизий.
- Я сломал rollout образа, сохранил доступность старой версии и выполнил rollback.
- Я объясняю округление и ёмкость
maxSurge/maxUnavailable. - Я знаю, что масштабирование не создаёт ревизию.
- Я установил Metrics Server или записал пробел зависимости.
- Я вызвал масштабирование HPA под измеренной нагрузкой и объяснил знаменатель запроса ресурсов.
- Я проверил поведение HPA, минимум, максимум и окно уменьшения.
- Я применил PDB и получил disruptionsAllowed.
- Я выполнил drain, проверил сервис и обязательно uncordon.
- Я объясняю, что PDB не защищает от отказа узла и прямого удаления.
- Я различаю HPA, VPA и autoscaler узлов.
Критерий: за 15 минут провести неудачный rollout → доказательства → undo → отмена исходника → проверка пользовательского пути.
8. Безопасность
- Namespace применяет закреплённый PSS
restrictedv1.36. - Pod работает без root, с корнем только для чтения, seccomp RuntimeDefault
и удалёнными capabilities (
ALL). - Основное приложение не монтирует токен ServiceAccount без потребности в API.
- Role разрешает
getконкретного ConfigMap, но не Secrets,listи другой namespace. - Я выполнил положительный и отрицательный
auth can-iи фактическую проверку внутри Pod. - Я различаю аутентификацию, авторизацию и admission.
- Я вызвал запрет PSS admission и понял разницу серверного и клиентского dry-run.
- Я составил модель угроз и остаточные риски.
- Я объясняю digest, подпись и сканирование образа как разные меры защиты.
- Я выбрал namespace или отдельный кластер по угрозе арендатора.
- Я считаю
exec,debugи создание Pod разрешениями, чувствительными к учётным данным.
Критерий: найти риск повышения привилегий в чужом манифесте и предложить
проверяемую меру защиты, а не cluster-admin.
9. Наблюдаемость и диагностика
- Я различаю метрики, журналы, трассировки, Events, status и аудит.
- Я использовал
logs --previous, контейнер-c,--since/--tail/--timestamps. - Я использовал точечный JSONPath и пользовательские колонки без дампа Secret.
- Я применял
exec,debug --profile=restricted,port-forwardпо цели. - Я переходил к доказательствам узла только при коррелирующем с узлом симптоме.
- Я расследовал все восемь сценариев на правильном уровне.
- Я ни разу не использовал перезапуск первым действием в итоговых записях об инцидентах.
- Я сохранил пакет доказательств и проверил его на учётные данные.
- Я проверил исходный пользовательский путь после исправления.
- Я связал сигнал тревоги с SLI и регламентом, а не только с CPU Pod.
Критерий: случайный инцидент — влияние, гипотеза, три команды, исправление, проверка и очистка за 10 минут.
10. Доставка и промышленная эксплуатация
- Рендеринг Kustomize
devиprodдетерминирован. - Клиентский и серверный dry-run выполнены, разница объяснена.
- Я проверил семантику кодов завершения
kubectl diff. - Secret исключён из результата рендеринга и доставляется отдельно.
- Я объясняю компромиссы исходного YAML, Kustomize и Helm.
- Я описал владение полями, расхождение и риск
pruneв GitOps. - Я записал текущую стабильную версию, совместимость версий и дату доступа к источнику.
- Я составил порядок обновления без пропусков и проверки дополнений и вебхуков.
- Я проверил устаревшие API в манифестах и план фактических запросов.
- Я определил границы резервных копий etcd и приложения и требование восстановления.
- Я сделал план ёмкости с
maxSurge, отказом узла и запасом. - Я определил SLI, SLO, бюджет ошибок и порог остановки.
- Я сравнил управляемый и самостоятельный кластер по разделённой ответственности и TCO.
Критерий: одностраничный план обновления содержит контрольную группу, SLO, резервную копию и восстановление, rollback и владельцев.
Финальный проверочный манифест
Этот Job проверяет Service после развёртывания:
apiVersion: batch/v1
kind: Job
metadata:
name: python-api-final-smoke
namespace: kube-course
labels:
app.kubernetes.io/name: python-api-final-smoke
app.kubernetes.io/part-of: kube-python-course
spec:
backoffLimit: 1
ttlSecondsAfterFinished: 300
template:
metadata:
labels:
app.kubernetes.io/name: python-api-final-smoke
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: smoke
image: busybox:1.37.0
command:
- sh
- -c
- >-
wget -qO- http://python-api/health/ready
| grep -q '"status":"ready"'
resources:
requests: {cpu: 10m, memory: 16Mi}
limits: {cpu: 100m, memory: 64Mi}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
kubectl apply --dry-run=server -f /tmp/final-smoke.yaml
kubectl apply -f /tmp/final-smoke.yaml
kubectl wait job/python-api-final-smoke -n kube-course \
--for=condition=Complete --timeout=120s
kubectl logs job/python-api-final-smoke -n kube-course
Ожидаются Job в состоянии Complete и код завершения 0; пустые журналы допустимы, потому
что используется grep -q. При ошибке нужны доказательства по Service, DNS,
политики и readiness.
90-минутный практический экзамен
- 0–15: предварительная проверка контекста, рендеринг, серверный dry-run,
развёртывание
dev. - 15–25: проверить три перехода: прямой Pod, Service внутри кластера и пользовательский port-forward.
- 25–40: изменение конфигурации, слепок окружения и файл, управляемый rollout.
- 40–60: два случайных сценария, восстановление на основе доказательств.
- 60–70: положительная и отрицательная проверки RBAC и запрет PSS.
- 70–80: неудачный rollout образа, rollback и исправление исходника.
- 80–90: финальная контрольная проверка, просмотр доказательств, очистка или передача устойчивого состояния.
Зачёт: завершено не менее восьми разделов, секреты не раскрыты, изменений в
неверном контексте нет, оба инцидента локализованы на правильном уровне, rollback
проверен. Для job-ready дополнительно: не более двух подсказок и
причинно-следственное объяснение. Для эксплуатационной траектории: запуск в реальном
целевом окружении с политиками, CNI/CSI, внешним входом, метриками, SLO и проверкой
восстановления.
Практическое упражнение
Попросите коллегу наблюдать экзамен и ставить:
- 0 — только заявление без доказательств;
- 1 — команда успешна, объяснение неполно;
- 2 — предсказание, доказательство, механизм и восстановление или ограничение.
Сумма не менее 16/20 по десяти выбранным навыкам — зачёт. Повторите только слабые аспекты, а не весь курс.
Самостоятельная задача
Удалите кластер и через неделю выполните экзамен с чистого журнала рабочей станции, не копируя команды глав. Критерий приёмки: воспроизводимость после частичного забывания, а не кратковременное узнавание.
Сломанный сценарий
Если финальная проверка находится в Pending, не читайте журналы Service первым
действием. Решение:
kubectl get job,pod -n kube-course \
-l app.kubernetes.io/name=python-api-final-smoke
kubectl describe pod <smoke-pod> -n kube-course
kubectl get events -n kube-course \
--field-selector involvedObject.name=<smoke-pod>
Если Pod находится в Running или Failed, тогда проверяйте журналы и код Job, DNS и Service. Один симптом «контрольная проверка не прошла» имеет разные уровни; phase определяет следующее доказательство.
Проверочный список дерева диагностических решений
Не могу поставить [x]
├─ команда не выполнялась → лабораторная работа, а не проверка теории
├─ вывод есть, механизм не объясняю → перечитать нужную главу + воспроизвести
├─ ожидаемое не совпало → исследовать среду/версию, не копировать ожидаемый результат
├─ дополнение недоступно → записать пробел в зависимостях + установить/проверить или оставить без отметки
├─ ограничение kind → нужна среда эксплуатационной траектории
└─ данные чувствительны → повторно получить целевой/отредактированный вывод
Уровни завершения
- Повторить основы: отмечено менее 60% или произошла любая критическая ошибка безопасности — неверный контекст, утечка секрета или принудительное удаление без решения о риске.
- Job-ready: не менее 80%, практический зачёт, не менее шести сценариев отказа, 15–19 баллов итогового проекта, ограничения названы честно.
- Эксплуатационная траектория завершена: не менее 90%, 20–24 балла итогового проекта в реальном целевом окружении, доказательства политик, сети, внешнего входа, метрик, восстановления, контрольного обновления и SLO. Это не означает конец обучения и готовности к дежурствам.
Типичные ошибки и заметка о безопасности и стоимости
Типичные ошибки: отметка за чтение; скопированный ожидаемый вывод; скрытая неудачная команда; снимок экрана Secret; локальный кластер назван промышленным; пробел дополнения отмечен пройденным; очистка без доказательства политики возврата. Хранение доказательств тоже стоит денег и несёт риск приватности: задайте срок хранения и маскирование. Повторные кластеры и образы занимают диск. Не проводите разрушающие упражнения эксплуатационного экзамена без ограниченной авторизации, окна изменений и rollback.
Самопроверка
- Что требуется кроме успешной команды?
- Можно ли отметить NetworkPolicy без запрещающей контрольной проверки?
- Что делать с пробелом дополнения?
- Почему экзамен повторяется через неделю?
- Какая критическая ошибка отменяет зачёт?
Ответы: 1) наблюдаемый инвариант, механизм и восстановление или ограничение; 2) нет; 3) записать и установить с проверкой либо оставить неотмеченным; 4) проверка самостоятельной воспроизводимости; 5) изменение в неверном контексте, раскрытие секрета или небезопасное разрушающее действие.
Резюме и источники
Проверочный список завершает курс доказательствами. Вернитесь к MAIN, критериям итогового проекта и таблице версий перед новым целевым кластером.