Опционально#

Оглавление#

Настроить интеграцию с единым коллектором телеметрии#

Если данные направляются не напрямую в Corax/Kafka Abyss, а в Единый коллектор телеметрии (COTE), то секция OUTPUT в конфигурационном файле для fluent-bit будет выглядеть следующим образом:

    [OUTPUT]
       Name             http
       Match            file.tail
       Host             {{ your-app.push_collector.host }} #имя хоста целевого HTTP-сервера (push-коллектора)
       Port             {{ your-app.push_collector.port }} #порт
       {% if your-app.push_collector.api_key.enabled | bool %}
       Header           ${authentication.api-key.header-name} {{'$'+'{'+'your_api.key'+'}'}} #задается в случае использования Api ключей
       {% endif %}
       URI              {{ your-app.push_collector.self.logs.pipe.endpoint }} #адрес pipeline в формате /push/project/{projectName}/pipeline/{pipelineName}
       Format           json

Здесь используются дополнительные секреты - API-ключи.
Для этого в конфигурации fluent-bit добавьте в configMap с 'application.properties' переменные, начинающиеся на fluent-controller.key.* (имя самого ключа задается вместо *), и путь для файла external-конфигурации, куда будут сохраняться значения данных секретов:

fluent-controller.external.conf.path=/fluent-bit/etc/ext/external.conf
fluent-controller.key.your_api.key=$__vault{kv:DOMAIN/xxxx/KV/:your-app-secret-porperties:your.vault.authentication.api_key.internal_key}

При этом будет сформирован файл с данными секретами; в такой конфигурации как выше, его содержимое будет следующим:

@SET your_api.key=значение_секрета_your.vault.authentication.api_key.internal_key

, а в fluent-bit.conf нужно добавить конструкцию @INCLUDE ${fluent-controller.external.conf.path} для подключения этого файла.

data:
  fluent-bit.conf: |-
{% if your_app.remote_write.push_collector.api_key.enabled | bool %}
    @INCLUDE ${fluent-controller.external.conf.path}
{% endif %}
    [SERVICE]
...

После этого в fluent-bit.conf можно ссылаться на эту(-и) переменную(-ые), используя placeholder ${your_api.key}
Примечание: если вы работаете без Secman, тогда для API-ключей необходимо создать secret (пример):

{% if not (your-app.vault.enabled | bool) and (your-app.api_key.enabled | bool) %}
kind: Secret
apiVersion: v1
metadata:
  name: your-app-fluent-bit-secrets
type: Opaque
data:
  external.conf: |-
    @SET your_api.key=${your.vault.authentication.api-key.internal-key}
{% endif %}

, а в файле deployment описания пода к которому необходимо подключить sidecar (пример dc.yaml) примонтировать этот секрет:

      volumes:
        - name: your-app-fluent-bit-secrets
          secret:
            secretName: your-app-fluent-bit-secrets
            defaultMode: 256
...
      volumeMounts:
      {% if your_app.remote_write.push_collector.api_key.enabled | bool %}
      {% if not (your_app.vault.enabled | bool) %}
        - name: your-app-fluent-bit-secrets
          mountPath: '/fluent-bit/etc/ext'
      {% else %}
        - name: fluent-controller-external-conf #здесь в emptyDir{} fluent-controller-ом будет автоматически создан файл external.conf
          mountPath: '/fluent-bit/etc/ext'
      {% endif %}
      {% endif %}

Бывают случаи, когда нужна возможность задать другие имена файлов сертификата и private-key для Kafka, вместо используемых во fluent-bit.conf ( rdkafka.ssl.certificate.location /vault/secrets/certs/cert.pem
rdkafka.ssl.key.location /vault/secrets/certs/private-key.pem )
для этого нужно в application.properties добавить переменные:

fluentbit-sidecar.kafka.cert.filename=my_certFileName.pem
fluentbit-sidecar.kafka.private-key.filename=my_privatekeyFileName.pem

, и изменить имена на аналогичные во fluent-bit.conf

Настроить мониторинг sidecar#

Sidecar возвращает метрики в формате Prometheus.
Для этого в проекте с конфигурациями дистрибутива нужно создать файл типа Service (пример svc.yaml) со следующим содержимым:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: your-app
    group: yourapp-grp
  name: 'yourapp-svc-fluent-bit-metrics-${distrib.release.version}'
  annotations:
    prometheus.io.path: /fluent-controller/metrics/prometheus
    prometheus.io.port: '8081'
    prometheus.io.scrape: 'true'
spec:
  ports:
    - name: 9081-tcp
      port: 9081
      protocol: TCP
      targetPort: 9081
  selector:
    deploymentconfig: 'your-app-${distrib.release.version}'
  type: ClusterIP
  sessionAffinity: None

URL для получения метрик: http://your-app-host:8081/fluent-controller/metrics/prometheus

Расчитать лимиты sidecar#

'${your-app.fluent-bit.cpuLimit}' - рекомендуемое значение 300m-400m, уточняется во время проведения НТ;

${your-app.fluent-bit.memLimit}' - можно рассчитать по приблизительной формуле your-app.fluent-bit.memLimit = A + A * 0.1 + ROUND(N / 10) * 5

, где A = 300 MB + Mem_Buf_Limit (всех INPUT плагинов, MB) + rdkafka.queue.buffering.max.kbytes (всех OUTPUT плагинов, MB);

N - количество узлов в кластере kafka, на каждые 10 узлов в кластере для service discovery необходимо дополнительно порядка 5 МБ памяти (округление выполняется в большую сторону)

Так же, в формулу добавляется объем памяти, потребляемой контроллером (~50 mb).

В скрипте запуска своего приложения указать в аргументах запуска путь к конфигурации logger logback: для spring boot

java \
-Dlogging.config="/opt/your-app/conf/logback.xml"
-jar /opt/demo.jar

для остальных

java \
-Dlogback.configurationFile="/opt/your-app/conf/logback.xml" \
-jar /opt/demo.jar

Настроить readiness и liveness пробы sidecar#

Пробы не рекомендуется использовать в deployment, т.к. sidecar не предоставляет REST-сервис, и завершение его с ошибкой должно приводить к рестарту его контейнера, и не должно оказывать влияния на предоставление вашего сервиса (вывод из балансировки), тем не менее, если необходимо, можно описать их так:

          ports:
            - containerPort: 9081
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /fluent-controller/actuator/health/liveness
              port: 9081
            initialDelaySeconds: ${your-app.k8s.deployment.spec.template.spec.containers.livenessProbe.initialDelaySeconds}
            successThreshold: ${your-app.k8s.deployment.spec.template.spec.containers.livenessProbe.successThreshold}
            timeoutSeconds: ${your-app.k8s.deployment.spec.template.spec.containers.livenessProbe.timeoutSeconds}
            periodSeconds: ${your-app.k8s.deployment.spec.template.spec.containers.livenessProbe.periodSeconds}
            failureThreshold: ${your-app.k8s.deployment.spec.template.spec.containers.llivenessProbe.failureThreshold}
          readinessProbe:
            httpGet:
              path: /fluent-controller/actuator/health/readiness
              port: 9081
            initialDelaySeconds: ${your-app.k8s.deployment.spec.template.spec.containers.readinessProbe.initialDelaySeconds}
            timeoutSeconds: ${your-app.k8s.deployment.spec.template.spec.containers.readinessProbe.timeoutSeconds}
            successThreshold: ${your-app.k8s.deployment.spec.template.spec.containers.readinessProbe.successThreshold}
            periodSeconds: ${your-app.k8s.deployment.spec.template.spec.containers.readinessProbe.periodSeconds}
            failureThreshold: ${your-app.k8s.deployment.spec.template.spec.containers.readinessProbe.failureThreshold}