#kubernetes #kubernetes-ingress #kong #kong-plugin #kong-ingress
Вопрос:
Я развернул некоторые API-интерфейсы в службе Azure Kubernetes и экспериментировал с Kong, чтобы иметь возможность использовать некоторые из его функций, таких как ограничение скорости и ограничение IP-адресов, но это не всегда работает должным образом. Вот объекты плагина, которые я использую:
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: kong-rate-limiting-plugin
annotations:
kubernetes.io/ingress.class: kong
labels:
global: 'true'
config:
minute: 10
policy: local
limit_by: ip
hide_client_headers: true
plugin: rate-limiting
---
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: kong-ip-restriction-plugin
annotations:
kubernetes.io/ingress.class: kong
labels:
global: 'true'
config:
deny:
- {some IP}
plugin: ip-restriction
Первая проблема заключается в том, что когда я попытался применить эти плагины по всему кластеру, установив глобальную метку»true», как описано здесь, я получил эту ошибку при применении ее с помощью kubectl:
metadata.labels: Invalid value: "\"true\"": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')
Вторая проблема заключается в том, что, хотя я использовал KongClusterPlugin и установил для global значение «true», мне все равно пришлось явно добавлять плагины в объект ingress, чтобы они работали. Вот мой вход:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ing
annotations:
konghq.com/plugins: kong-rate-limiting-plugin,kong-ip-restriction-plugin
konghq.com/protocols: https
konghq.com/https-redirect-status-code: "301"
namespace: default
spec:
ingressClassName: kong
...
И вот моя услуга:
apiVersion: v1
kind: Service
metadata:
name: my-svc
namespace: default
spec:
externalTrafficPolicy: Local
type: LoadBalancer
...
Третья проблема заключается в том, что, установив limit_by на ip, я ожидал, что он будет ограничивать скорость на IP, но я заметил, что он заблокирует всех клиентов, когда порог будет достигнут коллективно клиентами. Я попытался смягчить это, сохранив IP-адрес клиента и установив для externalTrafficPolicy значение Local в объекте службы, поскольку я подумал, что, возможно, объекты Kubernetes не получали IP-адрес фактического клиента. Теперь поведение, ограничивающее скорость, кажется более разумным, однако иногда кажется, что оно возвращается в прежнее состояние и случайным образом возвращает HTTP 429. Другая проблема, которую я вижу здесь, заключается в том, что я могу установить для externalTrafficPolicy значение Local только в том случае, если для типа службы установлено значение LoadBalancer или NodePort. Я установил, что мой сервис имеет тип LoadBalancer, который раскрывает его публично и, похоже, является проблемой. Было бы иронично, что использование контроллера входа, который должен защищать службу, скорее раскрывает ее. Я что-то здесь упускаю или в этом нет смысла?
Четвертая проблема заключается в том, что плагин ограничения IP, похоже, не работает. Мне удалось успешно вызвать API-интерфейсы с компьютера с IP-адресом, который я ввел в «config.deny».
Пятая проблема заключается в том, что количество раз в минуту, которое я должен использовать API, чтобы получить HTTP 429, не соответствует значению, которое я поместил в «config.minute».
Комментарии:
1. попробуйте добавить базу данных, такую как redis, в бэкэнд для плагина и протестируйте, возможно, вы увидите лучший результат
2. 1) Вы включили журналы доступа? Можете ли вы увидеть там внешний IP-адрес? 2) Возможно, он получает IP-адрес балансировщика нагрузки только в том случае, если он находится за балансировщиком нагрузки. 3) Попробуйте проверить мой пример задачи конга здесь
3. ваша четвертая проблема, похоже, не связана. Для пятого, есть гоночное условие по дизайну, у вас может быть немного больше, чем ожидалось. Цель состоит в том, чтобы защитить не с точной скоростью
4. Какой IP вы получаете, это реальный внешний ip или внутренний ? Использование заголовка может быть лучше, чем использование ip-адреса подключения