Настройка контроллера сетевых политик Cilium
В этом сценарии демонстрируется работа сетевых политик уровней L3/L4 и L7
Чтобы использовать контроллер сетевых политик Cilium в кластере:
- Установите и настройте средство наблюдения за сетевыми событиями Hubble UI.
- Создайте тестовое окружение.
- Создайте сетевую политику уровня L3/L4.
- Создайте сетевую политику уровня L7.
Перед началом работы
Подготовьте инфраструктуру
-
Создайте сервисный аккаунт и назначьте ему роли
k8s.tunnelClusters.agent
иvpc.publicAdmin
. -
Создайте группы безопасности для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
Создайте кластер любой подходящей конфигурации.
-
Для полей Сервисный аккаунт для ресурсов и Сервисный аккаунт для узлов выберите
Из списка
и затем выберите созданный сервисный аккаунт из выпадающего списка. -
В блоке Конфигурация мастера выберите следующие значения:
- Публичный адрес —
Автоматически
. - Группы безопасности —
Из списка
. Укажите группы безопасности для кластера.
- Публичный адрес —
-
В блоке Сетевые настройки кластера выберите опцию Включить туннельный режим.
-
-
Создайте для кластера группу узлов любой подходящей конфигурации.
В блоке Сетевые настройки выберите следующие значения:
- Публичный адрес —
Автоматически
. - Группы безопасности —
Из списка
. Укажите группы безопасности для групп узлов.
- Публичный адрес —
-
Если у вас еще нет Terraform, установите его.
-
Получите данные для аутентификации. Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
-
Настройте и инициализируйте провайдер. Чтобы не создавать конфигурационный файл с настройками провайдера вручную, скачайте его
. -
Поместите конфигурационный файл в отдельную рабочую директорию и укажите значения параметров. Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.
-
Скачайте в ту же рабочую директорию файл конфигурации k8s-cilium.tf
. С помощью файла будут созданы ресурсы:-
Сеть.
-
Кластер Managed Service for Kubernetes.
-
Группа узлов для кластера.
-
Сервисный аккаунт, необходимый для работы кластера и его группы узлов.
-
Группы безопасности, которые содержат необходимые правила для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
-
Укажите в файле
k8s-cilium.tf
:- Идентификатор каталога.
- Версию Kubernetes для кластера и групп узлов.
- Имя сервисного аккаунта.
-
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Создайте необходимую инфраструктуру:
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления
. -
Подготовьтесь к работе с кластером
-
Установите kubectl
и настройте его на работу с созданным кластером. - Установите утилиту Cilium CLI
(cilium
).
Установите и настройте Hubble UI
-
Проверьте текущее состояние Cilium в кластере:
cilium status
Cilium, Operator и Hubble Relay должны иметь статус
OK
.Пример результата выполнения команды
/¯¯\ /¯¯\__/¯¯\ Cilium: OK \__/¯¯\__/ Operator: OK /¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode) \__/¯¯\__/ Hubble Relay: OK \__/ ClusterMesh: disabled DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1 Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1 Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1 Containers: cilium Running: 1 cilium-operator Running: 1 hubble-relay Running: 1 Cluster Pods: 5/5 managed by Cilium Helm chart version: Image versions cilium cr.yandex/******/k8s-addons/cilium/cilium:v1.12.9: 1 cilium-operator cr.yandex/******/k8s-addons/cilium/operator-generic:v1.12.9: 1 hubble-relay cr.yandex/******/k8s-addons/cilium/hubble-relay:v1.12.9: 1
-
Создайте файл
hubble-ui.yaml
со спецификацией ресурсов, необходимых для Hubble UI:hubble-ui.yaml
--- apiVersion: v1 kind: ServiceAccount metadata: name: "hubble-ui" namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: hubble-ui-nginx namespace: kube-system data: nginx.conf: | server { listen 8081; listen [::]:8081; server_name localhost; root /app; index index.html; client_max_body_size 1G; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # CORS add_header Access-Control-Allow-Methods 'GET, POST, PUT, HEAD, DELETE, OPTIONS'; add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 1728000; add_header Access-Control-Expose-Headers content-length,grpc-status,grpc-message; add_header Access-Control-Allow-Headers range,keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout; if ($request_method = OPTIONS) { return 204; } # /CORS location /api { proxy_http_version 1.1; proxy_pass_request_headers on; proxy_hide_header Access-Control-Allow-Origin; proxy_pass http://127.0.0.1:8090; } location / { # double `/index.html` is required here try_files $uri $uri/ /index.html /index.html; } # Liveness probe location /healthz { access_log off; add_header Content-Type text/plain; return 200 'ok'; } } } --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: hubble-ui labels: app.kubernetes.io/part-of: cilium rules: - apiGroups: - networking.k8s.io resources: - networkpolicies verbs: - get - list - watch - apiGroups: - "" resources: - componentstatuses - endpoints - namespaces - nodes - pods - services verbs: - get - list - watch - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - get - list - watch - apiGroups: - cilium.io resources: - "*" verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: hubble-ui labels: app.kubernetes.io/part-of: cilium roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: hubble-ui subjects: - kind: ServiceAccount name: "hubble-ui" namespace: kube-system --- kind: Service apiVersion: v1 metadata: name: hubble-ui namespace: kube-system labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: cilium spec: type: "ClusterIP" selector: k8s-app: hubble-ui ports: - name: http port: 80 targetPort: 8081 --- kind: Deployment apiVersion: apps/v1 metadata: name: hubble-ui namespace: kube-system labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: cilium spec: replicas: 1 selector: matchLabels: k8s-app: hubble-ui strategy: rollingUpdate: maxUnavailable: 1 type: RollingUpdate template: metadata: annotations: labels: k8s-app: hubble-ui app.kubernetes.io/name: hubble-ui app.kubernetes.io/part-of: cilium spec: priorityClassName: serviceAccount: "hubble-ui" serviceAccountName: "hubble-ui" automountServiceAccountToken: true containers: - name: frontend image: "quay.io/cilium/hubble-ui:v0.13.0@sha256:7d663dc16538dd6e29061abd1047013a645e6e69c115e008bee9ea9fef9a6666" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8081 livenessProbe: httpGet: path: /healthz port: 8081 readinessProbe: httpGet: path: / port: 8081 volumeMounts: - name: hubble-ui-nginx-conf mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf - name: tmp-dir mountPath: /tmp terminationMessagePolicy: FallbackToLogsOnError - name: backend image: "quay.io/cilium/hubble-ui-backend:v0.13.0@sha256:1e7657d997c5a48253bb8dc91ecee75b63018d16ff5e5797e5af367336bc8803" imagePullPolicy: IfNotPresent env: - name: EVENTS_SERVER_PORT value: "8090" - name: FLOWS_API_ADDR value: "hubble-relay:80" ports: - name: grpc containerPort: 8090 volumeMounts: terminationMessagePolicy: FallbackToLogsOnError nodeSelector: kubernetes.io/os: linux volumes: - configMap: defaultMode: 420 name: hubble-ui-nginx name: hubble-ui-nginx-conf - emptyDir: {} name: tmp-dir
-
Создайте ресурсы:
kubectl apply -f hubble-ui.yaml
Результат выполнения команды
serviceaccount/hubble-ui created configmap/hubble-ui-nginx created clusterrole.rbac.authorization.k8s.io/hubble-ui created clusterrolebinding.rbac.authorization.k8s.io/hubble-ui created service/hubble-ui created deployment.apps/hubble-ui created
-
Проверьте состояние Cilium после установки Hubble UI:
cilium status
Cilium, Operator и Hubble Relay должны иметь статус
OK
. Контейнерhubble-ui
должен находиться в состоянииRunning: 1
.Пример результата выполнения команды
/¯¯\ /¯¯\__/¯¯\ Cilium: OK \__/¯¯\__/ Operator: OK /¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode) \__/¯¯\__/ Hubble Relay: OK \__/ ClusterMesh: disabled Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1 Deployment hubble-ui Desired: 1, Ready: 1/1, Available: 1/1 DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1 Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1 Containers: cilium Running: 1 hubble-relay Running: 1 cilium-operator Running: 1 hubble-ui Running: 1 Cluster Pods: 6/6 managed by Cilium Helm chart version: Image versions cilium cr.yandex/******/k8s-addons/cilium/cilium:v1.12.9: 1 hubble-relay cr.yandex/******/k8s-addons/cilium/hubble-relay:v1.12.9: 1 cilium-operator cr.yandex/******/k8s-addons/cilium/operator-generic:v1.12.9: 1 hubble-ui quay.io/cilium/hubble-ui-backend:v0.13.0@sha256:******: 1 hubble-ui quay.io/cilium/hubble-ui:v0.13.0@sha256:******: 1
-
Получите доступ к веб-интерфейсу Hubble UI, выполнив команду:
cilium hubble ui
Откроется браузер и вы будете перенаправлены в веб-интерфейс Hubble UI.
Примечание
Если вы закроете сессию терминала, в которой выполняется команда, то доступ к веб-интерфейсу будет потерян.
Создайте тестовое окружение
-
Создайте файл
http-sw-app.yaml
со спецификацией ресурсов для тестовых приложений:http-sw-app.yaml
--- apiVersion: v1 kind: Service metadata: name: deathstar spec: type: ClusterIP ports: - port: 80 selector: org: empire class: deathstar --- apiVersion: apps/v1 kind: Deployment metadata: name: deathstar spec: replicas: 2 selector: matchLabels: org: empire class: deathstar template: metadata: labels: org: empire class: deathstar spec: containers: - name: deathstar image: docker.io/cilium/starwars --- apiVersion: v1 kind: Pod metadata: name: tiefighter labels: org: empire class: tiefighter spec: containers: - name: spaceship image: docker.io/tgraf/netperf --- apiVersion: v1 kind: Pod metadata: name: xwing labels: org: alliance class: xwing spec: containers: - name: spaceship image: docker.io/tgraf/netperf
-
Создайте приложения:
kubectl apply -f http-sw-app.yaml
Результат выполнения команды
service/deathstar created deployment.apps/deathstar created pod/tiefighter created pod/xwing created
-
Убедитесь, что созданные поды и сервисы работают:
kubectl get pods,svc
Пример результата выполнения команды
NAME READY STATUS RESTARTS AGE pod/deathstar-c74d84667-6x4gx 1/1 Running 1 7d pod/deathstar-c74d84667-jrdsp 1/1 Running 0 7d pod/tiefighter 1/1 Running 0 7d pod/xwing 1/1 Running 0 7d NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/deathstar ClusterIP 10.96.18.169 <none> 80/TCP 7d service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
-
Посмотрите текущее состояние эндпоинтов Cilium:
kubectl -n kube-system exec daemonset/cilium -- cilium endpoint list
Убедитесь, что сетевые политики не действуют для всех эндпоинтов: в колонках
POLICY (ingress) ENFORCEMENT
иPOLICY (egress) ENFORCEMENT
должно быть указано значениеDisabled
.Пример части результата выполнения команды
Defaulted container "cilium-agent" out of: cilium-agent, clean-cilium-state (init), install-cni-binaries (init) ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 51 Disabled Disabled 2204 k8s:app.kubernetes.io/name=hubble-ui 10.112.0.97 ready k8s:app.kubernetes.io/part-of=cilium k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system k8s:io.cilium.k8s.policy.cluster=default k8s:io.cilium.k8s.policy.serviceaccount=hubble-ui k8s:io.kubernetes.pod.namespace=kube-system k8s:k8s-app=hubble-ui 274 Disabled Disabled 23449 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system 10.112.0.224 ready k8s:io.cilium.k8s.policy.cluster=default k8s:io.cilium.k8s.policy.serviceaccount=kube-dns-autoscaler k8s:io.kubernetes.pod.namespace=kube-system k8s:k8s-app=kube-dns-autoscaler ...
-
Убедитесь, что приложения
tiefighter
иxwing
имеют доступ к API сервисаdeathstar
и возвращают строкуShip landed
, т. к. сетевые политики не активированы:kubectl exec tiefighter -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing && \ kubectl exec xwing -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing
Результаты выполнения обеих команд должны совпадать:
Ship landed Ship landed
-
Перейдите в веб-интерфейс Hubble UI и посмотрите потоки данных для подов и сервисов в пространстве имен
default
.Для всех потоков должен быть вердикт
forwarded
.
Создайте политику L3/L4
Примените политику уровня L3/L4, чтобы заблокировать доступ пода xwing
к сервису deathstar
. Правила доступа для пода tiefighter
останутся без изменений.
Для разграничения доступа подам при создании присвоены Kubernetes-метки:
org: empire
для подаtiefighter
.org: alliance
для подаxwing
.
Политика L3/L4 разрешит доступ к сервису deathstar
только подам с меткой org: empire
.
-
Создайте файл
sw_l3_l4_policy.yaml
со спецификацией политики:sw_l3_l4_policy.yaml
--- apiVersion: "cilium.io/v2" kind: CiliumNetworkPolicy metadata: name: "rule1" spec: description: "L3-L4 policy to restrict deathstar access to empire ships only" endpointSelector: matchLabels: org: empire class: deathstar ingress: - fromEndpoints: - matchLabels: org: empire toPorts: - ports: - port: "80" protocol: TCP
-
Создайте политику
rule1
:kubectl apply -f sw_l3_l4_policy.yaml
Результат выполнения команды:
ciliumnetworkpolicy.cilium.io/rule1 created
-
Снова посмотрите текущее состояние эндпоинтов Cilium:
kubectl -n kube-system exec daemonset/cilium -- cilium endpoint list
Убедитесь, что для эндпоинта, связанного с меткой
k8s:class=deathstar
, действует политика на входящем направлении: в колонкеPOLICY (ingress) ENFORCEMENT
должно быть указано значениеEnabled
.Пример части результата выполнения команды
Defaulted container "cilium-agent" out of: cilium-agent, clean-cilium-state (init), install-cni-binaries (init) ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT ... 3509 Enabled Disabled 52725 k8s:class=deathstar 10.112.0.43 ready k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default k8s:io.cilium.k8s.policy.cluster=default k8s:io.cilium.k8s.policy.serviceaccount=default k8s:io.kubernetes.pod.namespace=default k8s:org=empire ...
-
Проверьте доступность сервиса
deathstar
для подаtiefighter
:kubectl exec tiefighter -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing
Результат выполнения команды:
Ship landed
-
Проверьте отсутствие доступа пода
xwing
к сервисуdeathstar
:kubectl exec xwing -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing
Нажмите Ctrl + C, чтобы прервать выполнение команды. Сетевая политика заблокировала доступ этого пода к сервису.
-
Изучите работу политики:
-
Посмотрите спецификацию и статус политики, выполнив команду:
kubectl describe cnp rule1
-
Перейдите в веб-интерфейс Hubble UI и посмотрите потоки данных для подов и сервисов в пространстве имен
default
.- Для потоков от
tiefighter
кdeathstar.default.svc.cluster.local/v1/request-landing
должен быть вердиктforwarded
. - Для потоков от
xwing
кdeathstar.default.svc.cluster.local/v1/request-landing
должен быть вердиктdropped
.
- Для потоков от
-
Создайте политику L7
В этой части сценария политика доступа для пода tiefighter
будет изменена:
- Доступ к методу API
deathstar.default.svc.cluster.local/v1/exhaust-port
будет запрещен. - Доступ к методу API
deathstar.default.svc.cluster.local/v1/request-landing
будет оставлен без изменений.
Доступ для пода xwing
останется без изменений. Этот под не имеет доступа к deathstar
.
-
Проверьте, что при использовании существующей политики
rule1
подtiefighter
имеет доступ к методуdeathstar.default.svc.cluster.local/v1/exhaust-port
:kubectl exec tiefighter -- curl --silent --request PUT deathstar.default.svc.cluster.local/v1/exhaust-port
Результат выполнения команды:
Panic: deathstar exploded goroutine 1 [running]: main.HandleGarbage(0x2080c3f50, 0x2, 0x4, 0x425c0, 0x5, 0xa) /code/src/github.com/empire/deathstar/ temp/main.go:9 +0x64 main.main() /code/src/github.com/empire/deathstar/ temp/main.go:5 +0x85
-
Создайте файл
sw_l3_l4_l7_policy.yaml
с обновленной спецификацией политики:sw_l3_l4_l7_policy.yaml
--- apiVersion: "cilium.io/v2" kind: CiliumNetworkPolicy metadata: name: "rule1" spec: description: "L7 policy to restrict access to specific HTTP call" endpointSelector: matchLabels: org: empire class: deathstar ingress: - fromEndpoints: - matchLabels: org: empire toPorts: - ports: - port: "80" protocol: TCP rules: http: - method: "POST" path: "/v1/request-landing"
-
Обновите существующую политику
rule1
:kubectl apply -f sw_l3_l4_l7_policy.yaml
Результат выполнения команды:
ciliumnetworkpolicy.cilium.io/rule1 configured
-
Убедитесь, что под
tiefighter
имеет доступ к методуdeathstar.default.svc.cluster.local/v1/request-landing
:kubectl exec tiefighter -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing
Результат выполнения команды:
Ship landed
-
Убедитесь, что доступ к методу
deathstar.default.svc.cluster.local/v1/exhaust-port
для подаtiefighter
запрещен:kubectl exec tiefighter -- curl --silent --request PUT deathstar.default.svc.cluster.local/v1/exhaust-port
Результат выполнения команды:
Access denied
-
Проверьте, что под
xwing
не имеет доступа к сервисуdeathstar
:kubectl exec xwing -- curl --silent --request POST deathstar.default.svc.cluster.local/v1/request-landing
Нажмите Ctrl + C, чтобы прервать выполнение команды.
-
Изучите работу политики:
-
Посмотрите спецификацию и статус политики, выполнив команду:
kubectl describe cnp rule1
-
Перейдите в веб-интерфейс Hubble UI и посмотрите потоки данных для подов и сервисов в пространстве имен
default
:- Для потоков от
tiefighter
кdeathstar.default.svc.cluster.local/v1/request-landing
должен быть вердиктforwarded
. - Для потоков от
tiefighter
кdeathstar.default.svc.cluster.local/v1/exhaust-port
должен быть вердиктdropped
. - Для потоков от
xwing
кdeathstar.default.svc.cluster.local
должет быть вердиктdropped
.
- Для потоков от
-
Удалите созданные ресурсы
Удалите ресурсы, которые вы больше не будете использовать, чтобы за них не списывалась плата:
- Удалите кластер Managed Service for Kubernetes.
- Если для доступа к кластеру или узлам использовались статические публичные IP-адреса, освободите и удалите их.
-
В терминале перейдите в директорию с планом инфраструктуры.
Важно
Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
-
Удалите ресурсы:
-
Выполните команду:
terraform destroy
-
Подтвердите удаление ресурсов и дождитесь завершения операции.
Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.
-