LINUX.ORG.RU
ФорумAdmin

Zabbix шаблон для Kubernetes: ошибка на Get State Metrics

 , ,


0

2

Коллеги, а кто-то использует zabbix для мониторинга kubernetes?

Я тут месяц назад обновился до zabbix 6.0, и пошёл радостно прикручивать мониторинг kubernetes (понимаю, что есть prometheus, но так как у меня вообще весь мониторинг в zabbix, то хочется и кубик туда впихнуть). Иду сюда: https://www.zabbix.com/integrations/kubernetes

По инструкции, ставлю сначала zabbix helm, потом прикручиваю cluster monitoring. Работает всё, кроме одной, но важной функции.

Kubernetes: Get state metrics выдаёт ошибку

{«error»:«Error: cannot get URL: Timeout was reached.»}

Пробовал менять таймаут, устанавливать другой вариант kube-state-metrics (не из состава zabbix), менять API URL (уже как жест отчаяния, остальное то работает; при смене получал error 403), даже пробовал развернуть абсолютно новый кластер с абсолютно новым zabbix - ошибка та же. Конечно, пробовал и смотреть, что там в гите заббикса - но там в этой части без изменений.

Кубик развёрнут из kubespray, версия kubernetes 1.21.5

Могу сюда кинуть код скрипта, который забирает эти данные, но вопрос: кто-то вообще этим мониторингом пользуется? Хочу понять, это у меня радиус кривизны рук зашкаливает, или это всё-таки общая проблема?

Ответ на: комментарий от pinachet

Вот. В общем-то это - скрипт по умолчанию, забирающий данные. Я его не менял.

var Kube = {
    params: {},
    metrics_endpoint: undefined,

    setParams: function (params) {
        ['api_endpoint', 'token', 'state_endpoint_name'].forEach(function (field) {
            if (typeof params !== 'object' || typeof params[field] === 'undefined'
                || params[field] === '') {
                throw 'Required param is not set: "' + field + '".';
            }
        });

          Kube.params = params;
          if (typeof Kube.params.api_endpoint === 'string' && !Kube.params.api_endpoint.endsWith('/')) {
              Kube.params.api_endpoint += '/';
          }
    },

    apiRequest: function (query) {
        var response,
            request = new HttpRequest(),
            url = Kube.params.api_endpoint + query;

        request.addHeader('Content-Type: application/json');
        request.addHeader('Authorization: Bearer ' + Kube.params.token);

        Zabbix.log(4, '[ Kubernetes ] Sending request: ' + url);

        response = request.get(url);

        Zabbix.log(4, '[ Kubernetes ] Received response with status code ' + request.getStatus() + ': ' + response);

        if (request.getStatus() < 200 || request.getStatus() >= 300) {
            throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
        }

        if (response !== null) {
            try {
                response = JSON.parse(response);
            }
            catch (error) {
                throw 'Failed to parse response received from Kubernetes API. Check debug log for more information.';
            }
        }

        return {
            status: request.getStatus(),
            response: response
        };
    },

    getMetricsEndpoint: function () {
        var result = Kube.apiRequest('v1/endpoints'),
            endpoint = undefined;

        if (typeof result.response !== 'object'
            || typeof result.response.items === 'undefined'
            || result.status != 200) {
            throw 'Cannot get endpoints from Kubernetes API. Check debug log for more information.';
        };

        result.response.items.forEach(function (ep) {
            if (ep.metadata.name === Kube.params.state_endpoint_name && Array.isArray(ep.subsets)) {
                if (typeof ep.subsets[0].addresses !== 'undefined') {
                    var subset = ep.subsets[0];

                    endpoint = {
                        address: subset.addresses[0].ip,
                        port: port = subset.ports.filter(function (port) {
                            return port.name === 'http';
                        })[0].port || 8080
                    }
                }
            }
        });

        Kube.metrics_endpoint = endpoint;
        return endpoint;
    },

    getStateMetrics: function () {
        if (typeof Kube.metrics_endpoint === 'undefined') {
            throw 'Cannot get kube-state-metrics endpoints from Kubernetes API. Check debug log for more information.';
        }

        var response,
            request = new HttpRequest(),
            url = 'http://' + Kube.metrics_endpoint.address + ':' + Kube.metrics_endpoint.port + '/metrics';

        request.addHeader('Content-Type: application/json');
        request.addHeader('Authorization: Bearer ' + Kube.params.token);

        Zabbix.log(4, '[ Kubernetes ] Sending request: ' + url);

        response = request.get(url);

        Zabbix.log(4, '[ Kubernetes ] Received response with status code ' + request.getStatus() + ': ' + response);

        if (request.getStatus() < 200 || request.getStatus() >= 300) {
            throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
        }

        if (response === null) {
            throw 'failed to get Kubernetes state metrics. Check debug log for more information.';
        }

        return response;

    }
};

try {
    Kube.setParams(JSON.parse(value));

    var metricsEndpoint = Kube.getMetricsEndpoint(),
        stateMetrics = Kube.getStateMetrics();

    return stateMetrics;
}
catch (error) {
    error += (String(error).endsWith('.')) ? '' : '.';
    Zabbix.log(3, '[ Kubernetes ] ERROR: ' + error);
    return JSON.stringify({ error: error });
}
stav_artefakt ★★
() автор топика
Ответ на: комментарий от pinachet

Да, я прописываю адрес API, и токен. Адрес в формате:

https://192.168.1.20:6443

Эндпоинт zabbix-kube-state-metrics (прописан в кубике после установки helm)

Как я сказал, остальные метрики с такими параметрами работают. Но я также пробовал, например, добавлять /api в конце, или /metrics

Ещё важный момент: если я через Lens открываю страницу метрик, то там я вижу их без проблем. То есть, проблема именно в настройках заббикса.

stav_artefakt ★★
() автор топика
Последнее исправление: stav_artefakt (всего исправлений: 3)