Kube/Pythonproduction course
Курс · RU93-skill-checklist.md

93. Проверочный список навыков и итоговый практический экзамен

Незнакомый термин? Откройте словарь Kubernetes и терминов курса.

Назначение, предварительные знания и результаты обучения

Это не список «знаю термин». Ставьте [x], только если выполнили команду, сохранили нечувствительные доказательства и объяснили наблюдаемое поведение. Нужны все главы и итоговый проект.

После проверочного списка у вас будет:

  • проверяемая матрица навык → команда → доказательство → объяснение;
  • 90-минутный практический экзамен;
  • список пробелов промышленной эксплуатации, которые локальный kind не может закрыть;
  • объективное решение: повторить основы, перейти к job-ready или к треку промышленной эксплуатации.

Требования к доказательствам

Для каждого пункта запишите:

Дата/версия кластера/контекст:
Команда(ы) и код выхода:
Наблюдаемый инвариант (без скопированного ожидаемого вывода):
Почему это произошло (контроллер/путь данных):
Сбой/восстановление:
Ограничение:

Не прикладывайте kubeconfig, токены, данные Secret или непроверенный пакет поддержки. Снимок экрана без команды, объекта и версии слабее текстового доказательства.

1. Окружение и модель API

  • Я проверил ОС, CPU, RAM, диск, cgroup и сервер провайдера контейнеров.
  • Я проверил контрольную сумму закреплённых исполняемых файлов kubectl и kind.
  • Я создал и удалил конкретный kube-course, не изменив чужой кластер.
  • Я могу объяснить путь kubectlсервер APIetcd/контроллер.
  • Я показал spec.replicas, status.readyReplicas, generation и observedGeneration.
  • Я доказал цепочку владения DeploymentReplicaSetPod.
  • Я удалил управляемый 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 restricted v1.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-минутный практический экзамен

  1. 0–15: предварительная проверка контекста, рендеринг, серверный dry-run, развёртывание dev.
  2. 15–25: проверить три перехода: прямой Pod, Service внутри кластера и пользовательский port-forward.
  3. 25–40: изменение конфигурации, слепок окружения и файл, управляемый rollout.
  4. 40–60: два случайных сценария, восстановление на основе доказательств.
  5. 60–70: положительная и отрицательная проверки RBAC и запрет PSS.
  6. 70–80: неудачный rollout образа, rollback и исправление исходника.
  7. 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.

Самопроверка

  1. Что требуется кроме успешной команды?
  2. Можно ли отметить NetworkPolicy без запрещающей контрольной проверки?
  3. Что делать с пробелом дополнения?
  4. Почему экзамен повторяется через неделю?
  5. Какая критическая ошибка отменяет зачёт?

Ответы: 1) наблюдаемый инвариант, механизм и восстановление или ограничение; 2) нет; 3) записать и установить с проверкой либо оставить неотмеченным; 4) проверка самостоятельной воспроизводимости; 5) изменение в неверном контексте, раскрытие секрета или небезопасное разрушающее действие.

Резюме и источники

Проверочный список завершает курс доказательствами. Вернитесь к MAIN, критериям итогового проекта и таблице версий перед новым целевым кластером.