Pull to refresh

k8s: подготовка к CKS

Level of difficultyMedium
Reading time11 min
Views4.2K

Привет всем, в продолжении CKA сегодня получил следующий сертификат CKS - Certified Kubernetes Security Specialist (ID Number: LF-lq76nh25g0) и хотел бы поделиться рекомендациями для успешной сдачи экзамена. Не претендую на истину в последней инстанции, а лишь делюсь личным опытом и впечатлениями. Возможно кому-то будет полезно.

Казалось бы, у нас нет ничего особого нового, мы просто поменяли контекст с общего на безопасность, и если CKA был относительно не сложным экзаменом, то вот CKS был прямо испытанием. Я смог пройти его только со второй попытки, в первой набрал 64% из необходимых 67%, вторая попытка была успешная и завершилась с результатом 83%.

И так, основная проблема, как бы это странно не звучало - время, а точнее его не хватка. Времени сильно не хватает. Напомню, что продолжительность экзамена 120 минут, вам дается 16-18 вопросов, лично у меня было 16, т.е. в среднем 7,5 минуты на вопрос. Но в отличие от CKA здесь задачи более объемные и как правило требуют больше времени на решение.

Теория

Здесь не будет ничего эдакого, я купил курс от kodekloud от уже известного нам по первой статье 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$.

Настоятельно рекомендую пройти эти сессии, в спокойной обстановке, когда никто не отвлекает и не мешает, у меня была возможность только на выходных. Так же в эмуляторе есть возможность посмотреть правильные ответы, но я советую воспользоваться этой возможностью только в крайнем случае, например, невозможности решить задачу самостоятельно и/или с помощью google.

Так как на экзамене можно использовать только несколько сторонних сайтов, как правило это документация к k8s, falco, etcd, то во время сессий я так же настоятельно советую открыть в веб проводнике https://kubernetes.io/docs/ и весь поиск производить только на самом сайте. Напоминаю, во время экзамена нельзя пользоваться поисковиками, даже если ссылка будет вести на разрешенный сайт. Это поможет привыкнуть к окружению, которое будет на реальном экзамене.

При подготовке практической части я использовал окружения от kodekloud, т.н. playgrounds

Ничего выдающегося, но экономит очень много времени и сил, когда вам надо быстро проверить какую то задачу.

Подготовка к экзамену

Ничем не отличается от CKA. Все тоже самое, как я описывал в первой статье. Все также просят показать уши на камеру и кто у вас сидит под столом )))

Экзамен

Ничем не отличается от CKA, естественно кроме самих вопросов.

Tips & tricks

Поделюсь советами, которые помогут более эффективно сдать экзамен.

  1. Будьте особо внимательны к вопросам, которые относятся к изменениям в kube apiserver и/или etcd. Если в результате ваших изменений вы получите не работающий kubeapi server/etcd, то все задачи, которые относились к этому кластеру - будут считаться не решенными. Что приведет к большой потери баллов. Напомню, что проходной бал - 67%.

  2. Если вас просят запустить 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

Так же не забываем, что в аннотации мы указываем имя контейнера, а не пода

  1. Если в задании требуется сохранить вывод в файл, то скорее всего это надо делать на student node (изначальная нода), и путь уже будет существовать, если такого пути нет, то скорее всего вы делаете что-то не так. Как вариант, вы забыли вернуться на изначальный хост. Аналогично и с ресурсами, если в задании сказано что ns уже создан, а вы видите что его нет, скорее всего вы забыли поменять контекст либо не вышли с master/worker node предыдущего кластера. Всего на экзамене 5 или 6 кластеров.

  2. Некоторые задания можно выполнять только на master/worker нодах, например там будут установлены kube-bench/trivy и т.п. рода утилиты. Обычно об этом явно говорится в задании, но не всегда. Например, если вам надо настроить аудит, то это можно сделать только на мастер ноде, но об этом не будут явно говорить. Для того чтобы быстро подключиться, делаем вывод нод k get node после смены контекста и затем ssh master-node-name или ssh worker-node-name

  3. Минимизируйте использование сторонних сайтов с документацией. Так как сама среда работает не особо быстро, а многие 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).
  1. Сэкономить еще немного времени так же поможет kubectl explainНапример, вас попросили добавить readOnlyRootFilesystem, но вы не помните точного написание и где именно надо указывать - используйте kubectl explain в сочетании с ключом --recursive=true

$ k explain pod.spec.containers --recursive=true | grep -i rootfilesystem -C10
   resources    <Object>
      limits    <map[string]string>
      requests  <map[string]string>
   securityContext      <Object>
      allowPrivilegeEscalation  <boolean>
      capabilities      <Object>
         add    <[]string>
         drop   <[]string>
      privileged        <boolean>
      procMount <string>
      readOnlyRootFilesystem    <boolean>
      runAsGroup        <integer>
      runAsNonRoot      <boolean>
      runAsUser <integer>
      seLinuxOptions    <Object>
         level  <string>
         role   <string>
         type   <string>
         user   <string>
      seccompProfile    <Object>
         localhostProfile       <string>
  1. Задания относящиеся к falco, часто могут быть решены с помощью sysdig. Например ваc просят сохранить логи в определенном формате для определенного контейнера в определенный файл. Если настраивать falco, то это потребует много времени, в отличие от sysdig

$ sysdig -M 120 -p "%evt.time, %user.name %proc.name" container.id=abcdef123

И мы снова можем сэкономить время, не обращаясь к документации falco, если вы не помните имя переменной

$ sysdig --list | grep time
$ sysdig --list | grep container
$ sysdig --list | grep proc

Аналогичные ключи есть и у команды falco. Если вам необходимо изменить существующее правило и добавить новые поля, а sysdig не доступен. В моем случае, в первый раз sysdig был не установлен в системе и я ставил его через apt, но в результате получил не работающую утилиту, ошибка была связано с неверными модулями для ядра, а времени разбираться просто не было.

Так же в моем случае sysdig работал только с фильтром container.name, а с container.id ничего не выдавал

  1. В задании c ImagePolicyWebhook вам предлагают для проверки корректности настройки файл с ресурсом, в моем случае это был ReplicationController, который немного сбивает с толку, по крайней мере меня. Так как по условию вам говорится, что поды не должны создаваться, но при этом сам ReplicationController создается успешно. Первый раз меня это сбило с толку и я потратил лишние минут 5 на перепроверку всех параметров, затем просто создал pod c тегом latest и увидел в терминале, что мой запрос был заблокирован

  2. В заданиях с сетевыми политиками не забывайте про явную необходимость указывать 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.

После создание сетевой политики рекомендую смотреть ее текстовое описание через k describe networkpolicy allow-app-label

  1. Не используйте СhatGPT. Вы не только не получите полезной информации, а даже наоборот - получите вредную. В который раз убедился, что это абсолютно бесполезная технология, по крайней мере в том виде в котором ее предоставляют на данный момент, имхо.

ок chatgpt

Alex

привет, как я могу логировать response body and request body используя аудит в k8s ? Можешь показать правило для каждого из случаев

ChatGPT

Привет! Для логирования тела запроса (request body) и тела ответа (response body) с использованием аудита в Kubernetes, вам нужно настроить соответствующие аудит-правила. Важно отметить, что логирование тела запроса может представлять потенциальные проблемы с безопасностью, поэтому следует быть осторожным при использовании такого функционала в боевой среде.

Для настройки аудита в Kubernetes, вам нужно отредактировать конфигурацию API-сервера. Вот примеры аудит-правил для логирования тела запроса и ответа:

Логирование тела запроса (request body):

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Request
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - ResponseStarted
  auditPolicy:
    log: true

Логирование тела ответа (response body):

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - RequestReceived
  requestBody: true
  responseBody: true

Обратите внимание, что эти правила предполагают, что вы хотите логировать тела запросов и ответов для операций создания (create), обновления (update) и частичного обновления (patch) ресурсов типа "pods". Вы можете настроить их под свои конкретные потребности, указав различные ресурсы, группы и вербы.

После внесения изменений в конфигурацию API-сервера, перезапустите его, чтобы изменения вступили в силу. Обратите внимание, что логирование тела запроса и ответа может создать большой объем данных, поэтому рекомендуется использовать его осторожно и только для отладочных или безопасных целей.

Alex

а что это за поля requestBody и responseBody ? Я не вижу таких в документации

ChatGPT

Извините за путаницу. Да, вы правы, в документации Kubernetes прямо указанного поля "requestBody" и "responseBody" нет. Моя ошибка.

Для логирования тела запроса и ответа, вам необходимо использовать поле auditPolicy с параметром log. Однако, стоит отметить, что по умолчанию Kubernetes не включает логирование тела запроса и ответа из соображений безопасности. Вместо этого, в логах сохраняются только хэши тела запроса и ответа.

Пример аудит-правила для логирования тела запроса и ответа:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - RequestReceived
  auditPolicy:
    log: true

В этом примере auditPolicy с параметром log: true указывает API-серверу включить логирование тела запроса и ответа. Однако, учтите, что логирование тела запроса и ответа может привести к большому объему данных и повысить риск утечек конфиденциальной информации, поэтому используйте это с осторожностью и только в безопасных окружениях.

Alex

разве мы получим response body, если будем игнорировать RequestReceived ?

ChatGPT

Извините за недоразумение в предыдущем ответе. Да, вы правы, если вы исключите стадию RequestReceived, то вы потеряете информацию о теле запроса, так как она обрабатывается на этой стадии. Однако, для получения тела ответа, вам все равно нужно будет включить стадию ResponseComplete.

Вот исправленное правило для логирования тела запроса и ответа:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - RequestReceived
  responseReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  auditPolicy:
    log: true

Теперь в этом правиле мы включили исключение стадии RequestReceived и включили стадию ResponseReceived, чтобы получить и тело запроса, и тело ответа в логах аудита.

Alex

что это за стадия ResponseReceived ? В документации я вижу только ResponseStarted и ResponseComplete

ChatGPT

Прошу прощения за путаницу в предыдущих ответах. Да, вы правы, в документации Kubernetes указаны стадии ResponseStarted и ResponseComplete, но не ResponseReceived.

Используйте следующее аудит-правило для логирования тела запроса и ответа:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  responseCompleteEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  auditPolicy:
    log: true

В этом правиле используются стадии RequestResponse, RequestReceived, и ResponseComplete. Стадия RequestReceived включена для логирования тела запроса, а стадия ResponseComplete - для логирования тела ответа. Пожалуйста, используйте это правило в соответствии с вашими требованиями.

Alex

приведи отдельные правило для каждого из случаев

ChatGPT

Извините за путаницу. Вот два отдельных правила для логирования тела запроса и тела ответа:

Логирование тела запроса (request body):

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Request
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - ResponseComplete
  auditPolicy:
    log: true

Логирование тела ответа (response body):

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Response
  responseReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - RequestReceived
  auditPolicy:
    log: true

В первом правиле установлен уровень Request, который логирует тело запроса. Второе правило устанавливает уровень Response, который логирует тело ответа. Оба правила применяются к операциям создания, обновления и частичного обновления ресурсов типа "pods".

Alex

для request body разве нам надо исключить ResponseComplete, а не ResponseStarted ?

ChatGPT

Извините за недоразумение в предыдущих ответах. Да, вы правы. Для логирования тела запроса (request body) и исключения тела ответа (response body), вам нужно исключить стадию ResponseComplete. Вот корректное правило для логирования тела запроса:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Request
  requestReceivedEvents:
  - resources:
    - group: ""
      version: "v1"
      resources: ["pods"]
    verbs: ["create", "update", "patch"]
  omitStages:
    - ResponseComplete
  auditPolicy:
    log: true

Благодарю за замечание, и я надеюсь, что это правило соответствует вашим требованиям.

Первая часть - подготовка к CKA

Tags:
Hubs:
Total votes 8: ↑6 and ↓2+4
Comments2

Articles