Как разрешить доступ к приложению внутри кластера только от ingress controller’ов?
Если вы хотите ограничить доступ к вашему приложению внутри кластера ТОЛЬКО от подов ingress’а, необходимо в под с приложением добавить контейнер с kube-rbac-proxy:
Пример Deployment для защищенного приложения
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: my-app
5 namespace: my-namespace
6spec:
7 selector:
8 matchLabels:
9 app: my-app
10 replicas: 1
11 template:
12 metadata:
13 labels:
14 app: my-app
15 spec:
16 serviceAccountName: my-sa
17 containers:
18 - name: my-cool-app
19 image: mycompany/my-app:v0.5.3
20 args:
21 - "--listen=127.0.0.1:8080"
22 livenessProbe:
23 httpGet:
24 path: /healthz
25 port: 443
26 scheme: HTTPS
27 - name: kube-rbac-proxy
28 image: flant/kube-rbac-proxy:v0.1.0 # Рекомендуется использовать прокси из нашего репозитория.
29 args:
30 - "--secure-listen-address=0.0.0.0:443"
31 - "--config-file=/etc/kube-rbac-proxy/config-file.yaml"
32 - "--v=2"
33 - "--logtostderr=true"
34 # Если kube-apiserver недоступен, мы не сможем аутентифицировать и авторизовывать пользователей.
35 # Stale Cache хранит только результаты успешной авторизации и используется, только если apiserver недоступен.
36 - "--stale-cache-interval=1h30m"
37 ports:
38 - containerPort: 443
39 name: https
40 volumeMounts:
41 - name: kube-rbac-proxy
42 mountPath: /etc/kube-rbac-proxy
43 volumes:
44 - name: kube-rbac-proxy
45 configMap:
46 name: kube-rbac-proxy
Приложение принимает запросы на адресе 127.0.0.1, это означает, что по незащищенному соединению к нему можно подключиться только изнутри пода. Прокси же слушает на адресе 0.0.0.0 и перехватывает весь внешний трафик к поду.
Как дать минимальные права для Service Account?
Чтобы аутентифицировать и авторизовывать пользователей с помощью kube-apiserver, у прокси должны быть права на создание TokenReview
и SubjectAccessReview
.
В наших кластерах уже есть готовая ClusterRole — d8-rbac-proxy. Создавать ее самостоятельно не нужно! Нужно только прикрепить ее к Service Account’у вашего Deployment’а.
1---
2apiVersion: v1
3kind: ServiceAccount
4metadata:
5 name: my-sa
6 namespace: my-namespace
7---
8apiVersion: rbac.authorization.k8s.io/v1
9kind: ClusterRoleBinding
10metadata:
11 name: my-namespace:my-sa:d8-rbac-proxy
12roleRef:
13 apiGroup: rbac.authorization.k8s.io
14 kind: ClusterRole
15 name: d8:rbac-proxy
16subjects:
17- kind: ServiceAccount
18 name: my-sa
19 namespace: my-namespace
Конфигурация Kube-RBAC-Proxy
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: kube-rbac-proxy
5data:
6 config-file.yaml: |+
7 excludePaths:
8 - /healthz # Не требуем авторизацию для liveness пробы.
9 upstreams:
10 - upstream: http://127.0.0.1:8081/ # Куда проксируем.
11 path: / # Location прокси, с которого запросы будут проксированы на upstream.
12 authorization:
13 resourceAttributes:
14 namespace: my-namespace
15 apiGroup: apps
16 apiVersion: v1
17 resource: deployments
18 subresource: http
19 name: my-app
Согласно конфигурации, у пользователя должны быть права на доступ к Deployment с именем my-app
и его дополнительному ресурсу http
в namespace my-namespace
.
Выглядят такие права в виде RBAC так:
1---
2apiVersion: rbac.authorization.k8s.io/v1
3kind: Role
4metadata:
5 name: kube-rbac-proxy:my-app
6 namespace: my-namespace
7rules:
8- apiGroups: ["apps"]
9 resources: ["deployments/http"]
10 resourceNames: ["my-app"]
11 verbs: ["get", "create", "update", "patch", "delete"]
12---
13apiVersion: rbac.authorization.k8s.io/v1
14kind: RoleBinding
15metadata:
16 name: kube-rbac-proxy:my-app
17 namespace: my-namespace
18roleRef:
19 apiGroup: rbac.authorization.k8s.io
20 kind: Role
21 name: kube-rbac-proxy:my-app
22subjects:
23# Все пользовательские сертификаты ingress-контроллеров выписаны для одной конкретной группы.
24- kind: Group
25 name: ingress-nginx:auth
Для ingress’а ресурса необходимо добавить параметры:
1nginx.ingress.kubernetes.io/backend-protocol: HTTPS
2nginx.ingress.kubernetes.io/configuration-snippet: |
3 proxy_ssl_certificate /etc/nginx/ssl/client.crt;
4 proxy_ssl_certificate_key /etc/nginx/ssl/client.key;
5 proxy_ssl_protocols TLSv1.2;
6 proxy_ssl_session_reuse on;
Подробнее о том, как работает аутентификация по сертификатам, можно прочитать в документации Kubernetes.
Как сконфигурировать балансировщик нагрузки для проверки доступности IngressNginxController?
В ситуации, когда IngressNginxController
размещен за балансировщиком нагрузки, рекомендуется сконфигурировать балансировщик для проверки доступности
узлов IngressNginxController
с помощью HTTP-запросов или TCP-подключений. В то время как тестирование с помощью TCP-подключений представляет собой простой и универсальный механизм проверки доступности, мы рекомендуем использовать проверку на основе HTTP-запросов со следующими параметрами:
- протокол:
HTTP
; - путь:
/healthz
; - порт:
80
(в случае использования inlet’аHostPort
нужно указать номер порта, соответствующий параметру httpPort.
Как настроить работу через MetalLB с доступом только из внутренней сети?
Пример MetalLB с доступом только из внутренней сети.
1apiVersion: deckhouse.io/v1
2kind: IngressNginxController
3metadata:
4 name: main
5spec:
6 ingressClass: "nginx"
7 inlet: "LoadBalancer"
8 loadBalancer:
9 sourceRanges:
10 - 192.168.0.0/24
Как добавить дополнительные поля для логирования в nginx-controller?
1apiVersion: deckhouse.io/v1
2kind: IngressNginxController
3metadata:
4 name: main
5spec:
6 ingressClass: "nginx"
7 inlet: "LoadBalancer"
8 additionalLogFields:
9 my-cookie: "$cookie_MY_COOKIE"
Как включить HorizontalPodAutoscaling для IngressNginxController?
Важно! Режим HPA возможен только для контроллеров с inlet’ом
LoadBalancer
илиLoadBalancerWithProxyProtocol
. Важно! Режим HPA возможен только приminReplicas
!=maxReplicas
, в противном случае deploymenthpa-scaler
не создается.
HPA выставляется с помощью аттрибутов minReplicas
и maxReplicas
в IngressNginxController CR.
IngressNginxController разворачивается с помощью DaemonSet. DaemonSet не предоставляет возможности горизонтального масштабирования, поэтому создается дополнительный deployment hpa-scaler
и HPA resource, который следит за предварительно созданной метрикой prometheus-metrics-adapter-d8-ingress-nginx-cpu-utilization-for-hpa
. Если CPU utilization превысит 50%, HPA закажет новую реплику для hpa-scaler
(с учетом minReplicas и maxReplicas).
hpa-scaler
deployment обладает HardPodAntiAffinity, поэтому он попытается заказать себе новый узел (если это возможно
в рамках своей NodeGroup), куда автоматически будет размещен еще один Ingress-контроллер.
Примечания:
- Минимальное реальное количество реплик IngressNginxController не может быть меньше минимального количества узлов в NodeGroup, в которую разворачивается IngressNginxController.
- Максимальное реальное количество реплик IngressNginxController не может быть больше максимального количества узлов в NodeGroup, в которую разворачивается IngressNginxController.
Как использовать IngressClass с установленными IngressClassParameters?
Начиная с версии 1.1 IngressNginxController, Deckhouse создает объект IngressClass самостоятельно. Если вы хотите использовать свой IngressClass,
например с установленными IngressClassParameters, достаточно добавить к нему label ingress-class.deckhouse.io/external: "true"
1apiVersion: networking.k8s.io/v1
2kind: IngressClass
3metadata:
4 labels:
5 ingress-class.deckhouse.io/external: "true"
6 name: my-super-ingress
7spec:
8 controller: ingress-nginx.deckhouse.io/my-super-ingress
9 parameters:
10 apiGroup: elbv2.k8s.aws
11 kind: IngressClassParams
12 name: awesome-class-cfg
В таком случае, при указании данного IngressClass в CRD IngressNginxController, Deckhouse не будет создавать объект, а использует уже существующий.
Как отключить сборку детализированной статистики Ingress-ресурсов?
По умолчанию Deckhouse собирает подробную статистику со всех Ingress-ресурсов в кластере, что может генерировать высокую нагрузку на систему мониторинга.
Для отключения сбора статистики добавьте label ingress.deckhouse.io/discard-metrics: "true"
к соответствующему namespace или Ingress-ресурсу.
Пример отключения сбора статистики (метрик) для всех Ingress-ресурсов в пространстве имен review-1
:
1kubectl label ns review-1 ingress.deckhouse.io/discard-metrics=true
Пример отключения сбора статистики (метрик) для всех Ingress-ресурсов test-site
в пространстве имен development
:
1kubectl label ingress test-site -n development ingress.deckhouse.io/discard-metrics=true