k8s: подготовка к CKS
Привет всем, в продолжении CKA сегодня получил следующий сертификат CKS — Certified Kubernetes Security Specialist (ID Number: LF-lq76nh25g0) и хотел бы поделиться рекомендациями для успешной сдачи экзамена. Не претендую на истину в последней инстанции, а лишь делюсь личным опытом и впечатлениями. Возможно кому то будет полезно.
Казалось бы, у нас нет ничего особого нового, мы просто поменяли контекст с общего на безопасность, и если CKA был относительно не сложным экзаменом, то вот CKS был прямо испытанием. Я смог пройти его только со второй попытки, в первой набрал 64% из необходимых 67%, вторая попытка была успешная и завершилась с результатом 83%.
И так, основная проблема, как бы это странно не звучало — время, а точнее его не хватка. Времени сильно не хватает. Напомню, что продолжительность экзамена 120 минут, вам дается 16–18 вопросов, лично у меня было 16, т.е. в среднем 7,5 минуты на вопрос. Но в отличие от CKA здесь задачи более объемные и как правило требуют больше времени на решение.
Теория
Здесь не будет ничего эдакого, я купил курс на Udemy — «https://kodekloud.com/courses/certified-kubernetes-security-specialist-cks/» от уже известного нам по первой статье Mumshad Mannambeth. На этот раз на Udemy я не брал никакие курсы.
А так же курс на youtube
Практика
Несмотря на наличие mock экзаменов в теоретическом курсе, практики будет явно недостаточно.
Для получения практики я использовал следующие курсы/лабы
https://kodekloud.com/courses/kubernetes-challenges/
https://kodekloud.com/courses/cks-challenges
https://killer.sh/cks
Напоминаю, как показала практика общения в slack канале killer.sh, не все люди знают, что при покупке экзамена, вы получаете две полноценные сессии у killer.sh. Они очень сильно отличаются от бесплатных заданий. Поэтому я очень рекомендую пройти их и разобрать непонятные моменты.
Ссылка на эмулятор будет доступна на странице самого экзамена
Не обращайте внимание на название экзамена, после получения сертификата ссылка на эмулятор пропадает, но принцип будет тот же. Сама сессия представляет приближенное к реальному окружение, где вам дается 22 вопроса и 36 часов, т.е. окружение будет доступно в течение 36 часов с момента его создания. Для каждого экзамена доступно две сессии. Если нужна будет еще дополнительная сессия, то придется покупать отдельно. Стоимость каждой дополнительной сессии — 10$.
Настоятельно рекомендую пройти эти сессии, в спокойной обстановке, когда никто не отвлекает и не мешает, у меня была возможность только на выходных. Так же в эмуляторе есть возможность посмотреть правильные ответы, но я советую воспользоваться этой возможностью только в случае невозможности решить задачу самостоятельно.
Так как на экзамене можно использовать только несколько сторонних сайтов, как правило это документация к k8s, falco, etcd, то во время сессий я так же настоятельно советую открыть в веб проводнике https://kubernetes.io/docs/ и весь поиск производить только на самом сайте. Напоминаю, во время экзамена нельзя пользоваться поисковиками, даже если ссылка будет вести на разрешенный сайт. Это поможет привыкнуть к окружению, которое будет на реальном экзамене.
При подготовке практической части я использовал окружения от kodekloud, т.н. playgrounds
Ничего выдающегося, но экономит очень много времени и сил, когда вам надо быстро проверить какую то задачу.
Подготовка к экзамену
Ничем не отличается от CKA. Все тоже самое, как я описывал в первой статье.
Экзамен
Ничем не отличается от CKA, естественно кроме самих вопросов.
Tips & tricks
Поделюсь советами, которые помогут более эффективно сдать экзамен.
Будьте особо внимательным к вопросам относительно изменений в kube apiserver и/или etcd. Если в результате ваших изменений вы получите не работающий kubeapi server, то все задачи, которые относились к этому кластеру будут считаться не решенными. Что приведет к большой потери баллов. Напомню, что проходной бал — 67%.
Если вас просят запустить pod c определенным apparmor profile, то обращайте внимание на какой ноде необходимо производить запуск, так как профиль привязан к ноде.
Если профиль необходимо применить, например, к deployment, то обращайте внимание в какой именно блок metadata вы добавляете соответствующую аннотацию. Аннотацию необходимо добавлять в
spec.template.metadata.annotations
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# неправильно
container.apparmor.security.beta.kubernetes.io/nginx: localhost/deny-write
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
# а так правильно
container.apparmor.security.beta.kubernetes.io/nginx: localhost/deny-write
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Так же не забываем, что в аннотации мы указываем имя контейнера, а не пода
Если в задании требуется сохранить вывод в файл, то скорее всего это надо делать на student node (изначальная нода), и путь уже будет существовать, если такого пути нет, то скорее всего что-то делаете не то. Как вариант, вы забыли вернуться на изначальный хост. Аналогично и с ресурсами, если в задании сказано что ns уже создан, а вы видите что его нет, скорее всего вы забыли поменять контекст либо не вышли с master/worker node предыдущего кластера.
Некоторые задания можно выполнять только на master/worker нодах, например там будут установлены kube-bench/trivy и т.п. рода утилиты. Обычно об этом явно говорится в задании, но не всегда. Например, если вам надо настроить аудит, то это можно сделать только на мастер ноде, но об этом не будут явно говорить. Для того чтобы быстро подключиться, делаем вывод нод
k get node
после смены контекста и затемssh master-node-name
илиssh worker-node-name
Минимизируйте использование сторонних сайтов с документацией. Так как сама среда работает не особо быстро, а многие hot keys, например, поиск текста на странице не работают вообще, то поиск будет забирать у вас очень много времени, которого катастрофически не хватает.
Если вас просят поменять или задать определенные параметры в kube apiserver или etcd. Используйте для этого уже существующие контейнеры, например, нас попросили установить минимальную версию tls в kube apiserver 1.3, то для этого достаточно выполнить такую команду
$ k exec -it -n kube-system kube-apiserver-controlplane -- kube-apiserver --help | grep tls-min
--tls-min-version string Minimum TLS version supported. Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13
$ k exec -it -n kube-system kube-apiserver-controlplane -- kube-apiserver --help | grep cipher
--tls-cipher-suites strings Comma-separated list of cipher suites for the server. If omitted, the default Go cipher suites will be used.
Мы сразу видим точное название параметра и возможные значения. Список шифров в случае с --tls-cipher-suites
всегда указывается в задании. Перезагрузка etcd у меня занимала 2–3 минуты, следует это учитывать
$ k exec -it -n kube-system etcd-controlplane -- etcd --help | grep cipher
--cipher-suites ''
Comma-separated list of supported TLS cipher suites between client/server and peers (empty will be auto-populated by Go).
Сэкономить еще немного времени так же поможет
kubectl explain
Например, вас попросили добавитьreadOnlyRootFilesystem
, но вы не помните точного написание и где именно надо указывать — используйтеkubectl explain
в сочетании с ключом--recursive=true
$ k explain pod.spec.containers --recursive=true | grep -i rootfilesystem -C10
resources
Задания относящиеся к falco, часто могут быть решены с помощью sysdig. Например ваc просят сохранить логи в определенном формате для определенного контейнера в определенный файл. Если настраивать falco, то это потребует много времени, в отличие от sysdig
$ sysdig -M120 -p "%evt.time, %user.name %proc.name" container.id=abcdef123
И мы снова можем сэкономить время, не обращаюсь к документации falco, если вы не помните имя переменной
$ sysdig --list | grep time
$ sysdig --list | grep container
$ sysdig --list | grep proc
Так же в моем случае sysdig работал только с фильтром container.name
, а с container.id
ничего не выдавал
В задании c ImagePolicyWebhook вам предлагают для проверки корректности настройки файл с ресурсом, в моем случае это был
ReplicationController
, который немного сбивает с толку, по крайней мере меня. Так как по условию вам говорится, что поды не должны создаваться, но при этом самReplicationController
создается успешно. Первый раз меня это сбило с толку и я потратил лишние минут 5 на перепроверку всех параметров, затем просто создал pod c тегом latest и увидел в терминале, что мой запрос был заблокированВ заданиях с сетевыми политиками не забывайте про явную необходимость указывать namespace, если вас просят предоставить доступ к поду с любого namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-label
namespace: db
spec:
podSelector:
matchLabels:
type: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
type: app
Таким образом мы разрешили входящий трафик в namespace=db
для подов из любого namespace c меткой type=app
Так же обратите внимание на следующие примеры
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: frontend
podSelector:
matchLabels:
type: nodejs
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: frontend
- podSelector:
matchLabels:
type: nodejs
у этих правил будет абсолютно разный эффект, хотя отличие всего в один символ.
В первом случае мы разрешаем доступ только подам с меткой type=nodejs
и только с namespace=frontend
Во втором случае мы разрешаем доступ любым подам с namespace=frontend
После создание сетевой политики рекомендую смотреть ее текстовое описание через describe