
В этом руководстве мы рассмотрим политики безопасности для подов в Kubernetes.
По мере развития технологий контейнеров и перехода приложений в кластерные среды определение и внедрение политик безопасности кластеров становится все более важным. Политики безопасности Kubernetes обеспечивают возможность запуска подов и контейнеров только с теми привилегиями, которые им необходимы, а также изолируют их, предоставляя доступ только к ограниченному набору ресурсов. Политики безопасности также позволяют администраторам кластеров контролировать создание ресурсов, ограничивая возможности, доступные для определенных ролей, групп или пространств имен. Более подробно об этом можно прочитать в статье «Kubernetes 1.7 — Настройка RBAC».
В этом руководстве мы рассмотрим политики безопасности для подов в Kubernetes. Вы узнаете, что это такое, как их создавать и активировать, а также как их тестировать. Стоит также иметь в виду, что политики безопасности применяемые для подов специфичны для правил каждой конкретной организации, использующей 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 и тем самым создание более безопасной кластерной инфраструктуры является одной из наиболее распространенных причин для применения политик безопасности к подам. Чтобы увидеть как это работает, давайте создадим следующую политику безопасности и сохраним ее в файл 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