Kubernetes — это система управления контейнерами, разработанная для автоматизации развертывания, масштабирования и управления приложениями, упакованными в контейнеры. Она была создана компанией Google на основе своей 15-летней практики в эксплуатации индустриальных нагрузок в разных компаниях и может считаться стандартом контейнерной оркестрации.
В Kubernetes существует такое понятие, как под. Это наименьшая базовая единица развертывания, которая объединяет один или несколько контейнеров и связанные с ними ресурсы. Они играют важную роль при применении сетевых политик в рассматриваемой системе, а именно — выступают в качестве источника и назначения трафика, к которому применяются правила доступа и безопасности. Каждый под имеет свой уникальный IP-адрес внутри кластера, что позволяет управлять сетевым трафиком на уровне подов.
Сетевые политики в Kubernetes — это относительно новая функциональность сервиса, состоящая из набора правил, определяющих, какие поды или их группы могут взаимодействовать между собой через сетевые соединения внутри кластера. Сетевые политики помогают пользователям контролировать трафик и настраивать безопасность, ограничивая доступ к определенным сервисам или подам.
В настоящей статье мы рассмотрим сетевые политики в Kubernetes, а также примеры их применения.
В данном разделе мы расскажем об основных преимуществах использования сетевых политик в Kubernetes:
Сетевые политики позволяют пользователями определить строгие правила доступа к сетевому трафику между подами. Это позволит предотвратить попытки несанкционированного доступа и минимизирует поверхность атак.
Сетевые политики используются при создании изолированных сетевых зон внутри кластера. Пользователь может определить различные правила доступа для разных неймспейсов, подавляя возможность пересечения сетевого трафика между приложениями разных групп. Это будет особенно полезно в мультитенантных средах, где несколько клиентов или команд могут использовать один кластер Kubernetes.
Сетевые политики также упрощают процесс управления сетевыми соединениями в кластере. Пользователи могут выполнить настройку как общих правил, так и индивидуальных для конкретных компонентов.
Правила самоисключения или self-healing повышают отказоустойчивость приложений. Например, если один из подов выйдет из строя, весь трафик будет автоматически перенаправлен на работающие экземпляры, обеспечивая тем самым непрерывность работы.
kube
NetworkPolicy в Kubernetes — это механизм управления сетевыми политиками. Он предназначен для определения правил доступа для сетевого трафика между подами в кластере. С помощью NetworkPolicy пользовать может ограничить входящий и исходящий сетевой трафик на основе различных атрибутов: IP-адресов, портов и меток.
Чтобы реализовать сетевые политики, понадобится сетевой плагин, поддерживающий NetworkPolicy.
Ниже перечислим основные поля, которые включает в себя NetworkPolicy:
apiVersion
— данное поле отвечает за версию API, которая используется для определения NetworkPolicy. Например, для Kubernetes версии 1.22 значение рассматриваемого поля может быть networking.k8s.io/v1
.kind
— указывает на тип объекта NetworkPolicy. В случае с сетевыми политиками, значение kind
будет NetworkPolicy
.metadata
— поле, содержащее метаданные объекта NetworkPolicy (имя, неймспейс, аннотации и метки).spec
— данное поле определяет основные параметры и правила сетевой политики. Внутри поля могут быть расположены следующие подполя:podSelector
— указывает на поды, к которым будет применяться сетевая политика.policyTypes
— определяет типы политик, применяемых к выбранным подам. Существует два типа политик для подов — это ingress
и egress
. Пользователь может указать либо один из типов, либо сразу оба.ingress
— содержит список правил доступа для входящего сетевого трафика.egress
— содержит список правил доступа для исходящего сетевого трафика. status
— содержит информацию о состоянии сетевой политики. В нем могут содержаться условия (conditions), которые отражают текущее состояние политики. Ниже приведем простой пример сетевой политики, содержащей все вышеописанные поля:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-network-policy
namespace: example-namespace
labels:
app: example-app
spec:
podSelector:
matchLabels:
app: example-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
ports:
- protocol: TCP
port: 80
egress:
- to:
- podSelector:
matchLabels:
app: allowed-app
ports:
- protocol: TCP
port: 443
status:
conditions:
- type: NetworkPolicyReady
status: "True"
lastTransitionTime: "2023-06-27T12:00:00Z"
Здесь создается сетевая политика с именем example-network-policy
в неймспейсе example-namespace
. Политика применяется к подам с меткой app: example-app
и содержит оба типа политик. Правило ingress
разрешает входящий TCP-трафик на порту 80 из подов с меткой app: allowed-app
. Правило egress
разрешает исходящий TCP-трафик на порту 443 к подам с меткой app: allowed-app
. Поле status
указывает на то, что политика готова к использованию.
В данной главе мы приведем некоторые распространенные среди пользователей сетевые политики. Другие примеры вы можете изучить в специальном репозитории GitHub.
Рассматриваемая в данной подглаве политика подразумевает блокировку всего трафика для подов приложения. Подобная политика может пригодиться пользователю в следующих случаях:
Вариант использования:
В первую очередь, необходимо запустить под nginx с специальными метками, также указав порт:
kubectl run web --image=nginx --labels app=web,env=prod --expose --port 80
Теперь включим временный под и отправим запрос к службе:
$ kubectl run --rm -i -t --image=alpine test-$RANDOM -- sh
/ # wget -qO- http://web
После успешного запуска и отправки запроса, составим NetworkPolicy и сохраним ее в файл banning-all-traffic.yaml
:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: banning-all-traffic
spec:
podSelector:
matchLabels:
app: web
ingress: []
Осталось применить ее к кластеру:
$ kubectl apply -f banning-all-traffic.yaml
Теперь протестируем работу сетевой политики и повторим запуск пода и отправку запроса:
$ kubectl run --rm -i -t --image=alpine test-$RANDOM -- sh
/ # wget -qO- --timeout=2 http://web
Если вы получили сообщение о том, что время загрузки истекло — значит, все выполнено успешно!
Пользователь может ограничить трафик для приложения, разрешив его от определенных подов и запретив от других. Подобная политика может пригодиться пользователю в следующих случаях:
Вариант использования:
Допустим, приложение представляет собой сервер REST API, помеченный метками app=example2
и role=api
:
kubectl run apiserver --image=nginx --labels="app=example2,role=api" --expose --port=80
Тогда сетевая политика для ограничения трафика будет выглядеть следующим образом:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: traffic-restriction
spec:
podSelector:
matchLabels:
app: example2
role: api
ingress:
- from:
- podSelector:
matchLabels:
app: example2
Сохраним ее в файл traffic-restriction.yaml
и применим к кластеру:
kubectl apply -f traffic-restriction.yaml
Чтобы проверить работу сетевой политики, запустим под с меткой app=example2
и без нее.
Под с меткой app=example2
:
$ kubectl run test-$RANDOM --rm -i -t --image=alpine --labels="app=example2,role=frontend" -- sh
/ # wget -qO- --timeout=2 http://apiserver
Под без метки:
$ kubectl run test-$RANDOM --rm -i -t --image=alpine -- sh
/ # wget -qO- --timeout=2 http://apiserver
В первом случае трафик должен быть разрешен, а во втором ограничен.
Разрешение всего трафика для приложений может понадобиться после применения политики запрета всего трафика, чтобы разрешить доступ к приложению из всех подов в указанном пространстве имен.
Вариант использования:
Запустим web-приложение:
kubectl run web --image=nginx --labels="app=web" --expose --port=80
Напишем соответствующую сетевую политику:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: resolution-all-traffic
namespace: default
spec:
podSelector:
matchLabels:
app: web
ingress:
- {}
Здесь используется правило пустого входа — {}
. Оно разрешает входящий трафик как в текущем пространстве имен, так и в любых иных. Правило пустого входа равносильно следующему фрагменту:
- from:
- podSelector: {}
namespaceSelector: {}
Сохраним политику в файле resolution-all-traffic.yaml
и применим ее к кластеру:
$ kubectl apply -f resolution-all-traffic.yaml
Вы также можете применить политику запрета трафика, чтобы проверить, что применение resolution-all-traffic.yaml
приведет к ее аннулированию.
Наконец, проверим работу написанной политики:
$ kubectl run test-$RANDOM --rm -i -t --image=alpine -- sh
/ # wget -qO- --timeout=2 http://web
В результате вы должны увидеть, что трафик успешно разрешен.
Выгодные тарифы на облако
В данной статье мы изучили сетевые политики кластера Kubernetes, разобрали их синтаксис и привели примеры для более детального понимания их работы. Исходя из всей информации, можно сделать вывод, что сетевые политики позволяют гибко настраивать правила доступа и контролировать сетевой трафик внутри кластера. Их применение обеспечивает безопасность, изоляцию и упрощенное управление в вашем кластере Kubernetes.
В статье представлена общая информация о сетевых политиках. Для более детального изучения рекомендуется обращаться к официальной документации и проводить дополнительные исследования с учетом особенностей вашего кластера и требований вашего приложения.