Kubernetes 1.7 – Настройка политик безопасности для пода (pod)
В этом руководстве мы рассмотрим политики безопасности для подов в Kubernetes.
По мере развития технологий контейнеров и перехода приложений в кластерные среды определение и внедрение политик безопасности кластеров становится все более важным. Политики безопасности Kubernetes обеспечивают возможность запуска подов и контейнеров только с теми привилегиями, которые им необходимы, а также изолируют их, предоставляя доступ только к ограниченному набору ресурсов. Политики безопасности также позволяют администраторам кластеров контролировать создание ресурсов, ограничивая возможности, доступные для определенных ролей, групп или пространств имен. Более подробно об этом можно прочитать в статье “Kubernetes 1.7 – Настройка RBAC“.
В этом руководстве мы рассмотрим политики безопасности для подов в Kubernetes. Вы узнаете, что это такое, как их создавать и активировать, а также как их тестировать. Стоит также иметь в виду, что политики безопасности применяемые для подов специфичны для правил каждой конкретной организации, использующей Kubernetes, или обычно продиктованы специфичными требованиями вашего конкретного приложения, не стоит ожидать от статьи универсального заклинания, которое магическим образом сделает вашу инфраструктуру еще более безопасной.
Предварительные требования
В этом руководстве мы предполагаем, что:
- У вас есть кластер Kubernetes или установлен Minikube для экспериментов, kubectl настроен на работу с ним, а также в вашем кластере включена поддержка политик безопасности для подов.
- У вас есть понимание того, как работает Kubernetes, а также как взаимодействуют друг с другом его основные сущности.
Еще раз отмечу, что вы можете настраивать и использовать политики безопасности для подов только в том случае, если они включены в вашем Kubernetes кластере. Проверьте эту настройку, запустив команду kubectl get psp. Если не поддерживается, команда вернет следующую ошибку:
the server doesn't have a resource type "podSecurityPolicies".
Если же данная настройка у вас включена, вы увидите следующее сообщение:
$ kubectl get psp
No resources found.
Для тех из вас, кто выполнял установку собственного кластера по статье “Установка кластера Kubernetes 1.7 на CentOS“, все включено и настроено. Для включения поддержки политик безопасности подов в Minukube необходимо запускать его со следующими опциями:
$ minikube start --extra-config=apiserver.GenericServerRunOptions.AdmissionControl=
NamespaceLifecycle,LimitRanger,
ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,
ResourceQuota,DefaultTolerationSeconds,PodSecurityPolicy
Как работают политики безопасности для пода
В Kubernetes политика безопасности для пода представлена ресурсом PodSecurityPolicy. В этом ресурсе перечислены условия, которые должен выполнить каждый для запуска в кластере. Ниже приведен пример политики безопасности под:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false
runAsUser:
rule: MustRunAsNonRoot
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- 'nfs'
hostPorts:
- min: 100
max: 100
Если коротко, то эта политика безопасности реализует следующие правила безопасности:
- Запретить поды, которые работают в привилегированном режиме
- Запретить поды, которым требуются права root
- Запретить поды, которые используют любые диски, кроме NFS
- Запретить поды, которые хотят получить доступ к портам хоста, кроме порта 100
Чуть дальше в этой статье мы рассмотрим эти правила чуть более подробно, но на данный момент давайте рассмотрим саму структуру политик безопасности подов.
- В разделе политики metadataуказано ее имя.
- В разделе spec излагаются ключевые критерии, которым должен удовлетворять под, чтобы иметь возможность запускаться. Далее приведено краткое описание основных доступных вариантов (более подробную информацию вы можете найти в официальной документации Kubernetes):
- Полеprivileged определяет, разрешать ли подам использовать привилегированный режим.Подробнее о привилегированном режиме.
- Поле runAsUser определяет, какие пользователи могут запускать под. Чаще всего оно используется для предотвращения запуска подов из под пользователя root.
- Поле seLinux определяет для подов контекст безопасности SELinux и разрешает запускать поды, соответствующие этому контексту. Подробнее о SELinux.
- Поля supplementalGroups и fsGroup определяют группы пользователей или принадлежащие fsGroup диски, к которым может обращаться конкретный под. Подробнее о fsGroups и дополнительных группах.
- Поле volumes определяет тип(ы) дисков, к которым может обращаться под. Подробнее о дисках.
- Поле hostPorts вместе с соответствующими полями, такими как hostNetwork, hostPIDи hostIPC, ограничивает порты (и другие сетевые сервисы), которые контейнер может получить от хост-системы.
Чтобы лучше разобраться с тем, как политики безопасности для подов работают на практике, давайте рассмотрим общие примеры их использования, а также команды, которые позволят вам добавлять, просматривать и удалять эти политики безопасности в вашем кластере.
Запрет на запуск подов с правами root
Задача запрета запуска контейнеров в подах от пользователя root и тем самым создание более безопасной кластерной инфраструктуры является одной из наиболее распространенных причин для применения политик безопасности к подам. Чтобы увидеть как это работает, давайте создадим следующую политику безопасности и сохраним ее в файл restrict-root.yaml:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: restrict-root
spec:
privileged: false
runAsUser:
rule: MustRunAsNonRoot
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
Активируйте политику следующей командой:
$ kubectl create -f restrict-root.yaml
Проверьте, что политика применилась к вашему кластеру:
$ kubectl get psp
Вы результате вы должны увидеть следующий вывод:
После того, как политика была применена, ее необходимо проверить. Давайте попытаемся запустить контейнер, который требует привилегий root. Один из таких примеров – это контейнер MariaDB от Bitnami. Попробуйте развернуть его с помощью следующей команды:
$ kubectl run --image=nginx --port=80 nginx
Поскольку политика безопасности явно запрещает запуск подов или контейнеров с привилегиями root, этот запрос должен быть отклонен, и вы должны увидеть следующую ошибку в выводе команды kubectl get pods:
container has runAsNonRoot and image will run as root
Чтобы удалить только что созданную политику, выполните команду:
$ kubectl delete psp restrict-root
Теперь давайте создадим более мягкую политику, установив поле runAsUser в runAsAny и сохраните ее в файле allow-root.yaml:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permit-root
spec:
privileged: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
Как и в прошлый раз политика активируется командой:
$ kubectl create -f permit-root.yaml
Теперь удалим предыдущий деплоймент и повторим попытку развертывания контейнера nginx. На этот раз деплоймент должно проходить успешно, так как новая политика безопасности позволяет подам запускаться от любого пользователя, включая пользователя root.
Важно: когда кластер Kubernetes запускается с поддержкой политики безопасности для подов, Kubernetes следует принципу «default-deny». Это означает, что по умолчанию gjls не могут запускаться, если они не соответствуют критериям, определенным в политике безопасности. Это также означает, что если ваш кластер не имеет хотя бы одной политики безопасности для подов, ни один из них не будет запущен, и Kubernetes сообщит вам, что вы должны активировать политику безопасности сообщением об ошибке.
Запрет подам на доступ к дискам определенного типа
Будучи администратором кластера вы можете ограничить доступные варианты хранения информации для запускаемых подов, чтобы минимизировать затраты или предотвратить доступ к той или иной информации, обрабатываемой ими. Это можно легко сделать, указав доступные типы томов в ключе volumes политики безопасности. Для иллюстрации рассмотрим следующую политику, которая ограничивает контейнеры только дисками NFS:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: restrict-volumes
spec:
privileged: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- 'nfs'
Или, например, вот другая политика, разрешающая вашим подам доступ к дискам типов PVC и secret.
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permit-volumes-pvc-secret
spec:
privileged: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- 'persistentVolumeClaim'
- 'secret'
Запрет подам использовать порты хост-системы
Еще одна общая проблема безопасности – это контейнеры, которые получают доступ к ресурсам хоста, таким как хост-порты или сетевые интерфейсы. Политики безопасности Kubernetes позволяют администраторам кластеров внедрять правила для ограничения такого типа доступа. Простым примером является ограничение доступа контейнера к любым портам хоста:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: restrict-ports
spec:
privileged: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
hostPorts:
- min: 0
max: 0
Если есть необходимость разрешить запускать поды, например, с Postgresql, можно разрешить использование его порта:
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permit-port-5432
spec:
privileged: false
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
fsGroup:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
hostPorts:
- min: 5432
max: 5432