Banzai Logging Operator Nedir?

Fluentd ve Fluent-bit tabanlı Kubernetes için logging operatörüdür. Fluentbit her node’a DeamonSet olarak kurulur. Bu sayede Container ve Uygulama loglarını toplar. Fluent Bit, Kubernetes API’sini sorgular ve verileri podlarla alakalı meta verilerle zenginleştirir bu verileri de Fluentd’ye aktarır. Fluentd logları alır, filtreler ve birden çok alıcıya aktarabilir.

logging

Banzai Logging Operator Özellikleri

  •  Namespace isolation
  •  Native Kubernetes label selectors
  •  Secure communication (TLS)
  •  Configuration validation
  •  Multiple flow support (multiply logs for different transformations)
  •  Multiple output support (store the same logs in multiple storage: S3, GCS, ES, Loki and more…)
  •  Multiple logging system support (multiple fluentd, fluent-bit deployment on the same cluster)
image 1

Fluentd ve Fluent Bit Kullanım Senaryosu

Kubernetes’de, Fluent Bit, node başına bir DaemonSet olarak dağıtılacak, küme başına dağıtılan bir Fluentd’ye veri toplayıp iletecek ve verileri işleyen ve etiketleri temel alan farklı kaynaklara yönlendiren bir toplayıcı olarak görev yapacaktır.

fluentbit fluentd

Fluent Bit elbette kendi başına kullanılabilir, ancak toplama yetenekleri ve diğer çözümlerle entegrasyon için çok daha az miktarda eklenti ile sunabileceği çok az şeyi vardır. Bu nedenle Fluentd ile kullanımı daha iyi bir senaryo sunmaktadır.

Ön Hazırlık

Kullanılan Kubernetes

Bu yazı içerisinde kullanılan Kubernetes versiyonu: v1.23.10

Namespace’in Oluşturulması

Helm Chartları kuracağımız bir namespace oluşturalım.

kubectl create ns efk

Helm Repolarının Eklenmesi

Kurulumda kullanacağımız Elastic ve Banzai repolarını helm’e ekleyelim.

helm repo add rancher-charts https://charts.rancher.io
helm repo add elastic https://helm.elastic.co

Helm Repomuzu güncelleyelim.

helm repo update

Banzai logging chart’ı fetch edelim.

helm fetch rancher-charts/rancher-logging-crd
helm fetch rancher-charts/rancher-logging

Kubernetes Üzerine Elasticsearch Kurulumu

Aşağıdaki helm komutu ile kurulumu efk namespace’i üzerinde başlatıyoruz.

Eğer tek node olarak localde çalışıyorsanız Elastic’in helm ile kurulurken 1 node’a kurulması için aşağıdaki parametreleri kullanabilirsiniz.

–set replicas=1 –set minimumMasterNodes=1
helm install elasticsearch elastic/elasticsearch --namespace efk

Ardından rollout’un bittiğini görebilmek adına aşağıdaki kontrol komutumuzu çalıştırıyoruz.

kubectl rollout status sts/elasticsearch-master --namespace=efk
Waiting for 3 pods to be ready...
Waiting for 2 pods to be ready...
Waiting for 1 pods to be ready...
partitioned roll out complete: 3 new pods have been updated...

Servisimizin adının elasticsearch-master olduğunu görüyoruz. Kibana kurarken servis ismi ile ulaşacağımızdan bunu not etmeniz önemi.

image 2

Kubernetes Üzerine Kibana Kurulumu

Aşağıdaki Helm komutu ile efk namespace’i üzerinde Kibanayı servis adımızı baz alarak kuruyoruz.

Eğer tek node olarak localde çalışıyorsanız Elastic’in helm ile kurulurken 1 node’a kurulması için aşağıdaki parametreleri kullanabilirsiniz.

–set replicas=1 –set minimumMasterNodes=1
helm install kibana elastic/kibana --set env.ELASTICSEARCH_URL=http://elasticsearch-master:9200 --namespace efk

Kibana podumuzun çalışır vaziyette (1/1) olduğunu kontrol edelim.

kubectl get pods --namespace=efk | grep kibana
kibana-kibana-7759ccf877-6rhbc   1/1     Running   0          2m14s

Kibana arayüzümüze bağlanmadan önce Elastic şifremizi öğrenmek için aşağıdaki komutu çalıştıralım.

kubectl get secrets --namespace=efk elasticsearch-master-credentials -ojsonpath='{.data.password}' | base64 -d

Şimdi Kibana arayüzüne bağlanmak için servisimizi port-forward ile localimize 8080 portundan iletelim.

kubectl port-forward –namespace efk svc/kibana-kibana 8080:5601 &

Kullanıcı adımız: elastic

Şifremiz: Yukarıdaki komutla secret içerisinden aldığımız şifredir

image 3

Kubernetes Üzerime Test Logu Oluşturmak İçin Test Podu Oluşturma

Kubernetes üzerinde saniyede 1 kere log’a veri ekleyen bir pod’u ayağa kaldırıyoruz.

kubectl apply -f https://raw.githubusercontent.com/sezersanlikan/monitoring/master/test-log-pod.yaml --namespace efk

İlgili podun loglarını kontrol ediyoruz.

kubectl logs -f test-log-pod -n efk
image 4

Kubernetes üzerine Banzai Logging Operator Kurulumu

Aşağıdaki Helm komutu ile gerekli Logging için CRD leri cattle-logging-system namespace üzerine kuruyoruz.

helm install rancher-logging-crd ./rancher-logging-crd-101.0.0+up3.17.7.tgz -n cattle-logging-system --create-namespace

CRD’leri kontrol edelim.

kubectl get crd | grep banzai
clusterflows.logging.banzaicloud.io              2022-12-05T07:34:32Z
flows.logging.banzaicloud.io                     2022-12-05T07:34:32Z
hosttailers.logging-extensions.banzaicloud.io    2022-12-05T07:34:32Z
eventtailers.logging-extensions.banzaicloud.io   2022-12-05T07:34:32Z
clusteroutputs.logging.banzaicloud.io            2022-12-05T07:34:32Z
outputs.logging.banzaicloud.io                   2022-12-05T07:34:32Z
loggings.logging.banzaicloud.io                  2022-12-05T07:34:32Z

Banzai Logging’i kurmadan evvel Helm Chart’a vereceğimiz custom YAML dosyasını aşağıda komut ile hazırlayalım.

cat <<EOF >> helm-rancher-logging.yaml
additionalLoggingSources:
  aks:
    enabled: false
  eks:
    enabled: false
  gke:
    enabled: false
  k3s:
    container_engine: systemd
    enabled: false
    stripUnderscores: false
  kubeAudit:
    auditFilename: ''
    enabled: false
    fluentbit:
      logTag: kube-audit
      tolerations:
        - effect: NoSchedule
          key: node-role.kubernetes.io/controlplane
          value: 'true'
        - effect: NoExecute
          key: node-role.kubernetes.io/etcd
          value: 'true'
    pathPrefix: ''
  rke:
    enabled: false
    fluentbit:
      log_level: info
      mem_buffer_limit: 5MB
  rke2:
    enabled: true
    stripUnderscores: false
affinity: {}
annotations: {}
createCustomResource: false
debug: false
disablePvc: true
extraArgs:
  - '-enable-leader-election=true'
fluentbit:
  filterKubernetes:
    Merge_Log: ''
    Merge_Log_Key: ''
    Merge_Log_Trim: ''
    Merge_Parser: ''
  inputTail:
    Buffer_Chunk_Size: ''
    Buffer_Max_Size: ''
    Mem_Buf_Limit: ''
    Multiline_Flush: ''
    Skip_Long_Lines: ''
  resources: {}
  tolerations:
    - effect: NoSchedule
      key: node-role.kubernetes.io/controlplane
      value: 'true'
    - effect: NoExecute
      key: node-role.kubernetes.io/etcd
      value: 'true'
fluentd:
  bufferStorageVolume: {}
  livenessProbe:
    initialDelaySeconds: 30
    periodSeconds: 15
    tcpSocket:
      port: 24240
  nodeSelector: {}
  resources: {}
  tolerations: {}
fullnameOverride: ''
global:
  cattle:
    systemDefaultRegistry: ''
    systemProjectId: p-m6j7g
  dockerRootDirectory: ''
  psp:
    enabled: true
  rkeWindowsPathPrefix: c:\
  seLinux:
    enabled: false
http:
  port: 8080
  service:
    annotations: {}
    clusterIP: None
    labels: {}
    type: ClusterIP
image:
  pullPolicy: IfNotPresent
  repository: rancher/mirrored-banzaicloud-logging-operator
  tag: 3.17.7
imagePullSecrets: []
images:
  config_reloader:
    repository: rancher/mirrored-jimmidyson-configmap-reload
    tag: v0.4.0
  fluentbit:
    repository: fluent/fluent-bit
    tag: 1.8.3
  fluentbit_debug:
    repository: fluent/fluent-bit
    tag: 1.8.3-debug
  fluentd:
    repository: rancher/mirrored-banzaicloud-fluentd
    tag: v1.14.6-alpine-5
  nodeagent_fluentbit:
    os: windows
    repository: rancher/fluent-bit
    tag: 1.8.3
loggingOverlay: {}
monitoring:
  serviceMonitor:
    additionalLabels: {}
    enabled: false
    metricRelabelings: []
    relabelings: []
nameOverride: ''
namespaceOverride: ''
nodeAgents:
  tls:
    enabled: false
nodeSelector:
  kubernetes.io/os: linux
podLabels: {}
podSecurityContext: {}
priorityClassName: {}
rbac:
  enabled: true
  psp:
    annotations:
      seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default
      seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
    enabled: true
replicaCount: 1
resources: {}
securityContext: {}
serviceAccount:
  annotations: {}
systemdLogPath: /run/log/journal
tolerations:
  - effect: NoSchedule
    key: cattle.io/os
    operator: Equal
    value: linux
EOF

Şimdi Helm Chartı’ı oluşturduğumuz values YAML ile ayağa kaldıralım.

helm install rancher-logging ./rancher-logging-101.0.0+up3.17.7.tgz -n cattle-logging-system -f helm-rancher-logging.yaml

Podları kontrol edelim.

kubectl get pods -n cattle-logging-system

NAME                                                READY   STATUS      RESTARTS   AGE
rancher-logging-685cf9664-xxj9m                     1/1     Running     0          50s
rancher-logging-rke2-journald-aggregator-5wrrr      1/1     Running     0          50s
rancher-logging-root-fluentd-configcheck-ac2d4553   0/1     Completed   0          48s
rancher-logging-root-fluentd-0                      2/2     Running     0          42s
rancher-logging-root-fluentbit-ffxn6                1/1     Running     0          40s

ClusterOutput, ClusterFlows ve Dataview Oluşturma

Local kubernetes olarak Rancher Desktop kullanıyorum. Banzai Logging Operator arayüz konusunda Rancher üzerinden destek vermektedir.

ClusterOutput Oluşturma

Sol menüde bulunan Logging sekmesine giderek ClusterOutput oluşturuyoruz.

image 6

ClusterFlows Oluşturma

Sol menüde bulunan Logging sekmesine gidecek ClusterFlows oluşturuyoruz.

image 11
image 13

Dataview Oluşturma

Kibana arayüzüne giriş yapmıştık. Karşımıza aşağıdaki gibi bir panel çıkacaktır. Explore on my own seçeneğine tıklayıp dashboard’a gidelim.

image 9

Sol menüden Stack Management menüsüne tıklayalım.

image 10

Ardından sol menüden Index Management seçeneğine tıklayarak oluşturduğumuz index’in buraya geldiğinden emin olalım. Index’in buraya düşmesi vakit alabilir.

image 14

Mevcut index’imiz ile Data View oluşturabiliriz. Sol menüden “Data Views” altına gidin ve “Create data view” butonuna basın.

image 15
image 16

Sol menüden “Discover” menüsüne gittiğimizde oluşturduğumuz “Data View” ‘i görebileceğiz artık.

image 17
image 19

2. Senaryo ( Grafana – Loki – Banzai Logging Operator )

Bu senaryoda Elasticsearch ve Kibana yerine Grafana ve Loki kuracağız. Banzai Logging Operator ile logları Lokiye göndereceğiz. Grafana üzerinden Loki data-source ekleyerek Grafana üzerinden loglarımızı izleyebileceğiz.

Loki ve Grafana kurulumu için Bitnami Helm reposunu eklememiz gerekiyor;

helm repo add bitnami https://charts.bitnami.com/bitnami

Loki kurulumu için aşağıdaki Helm komutunu kullanabilirsiniz. Beraberinde Promtail kuruluyor bunu promtail.enabled=false ile disable ediyoruz.

helm upgrade --install loki bitnami/grafana-loki --set promtail.enabled=false --namespace loki-grafana --create-namespace

Grafana kurulumu için aşağıdaki Helm komutunu kullanabilirsiniz.

helm upgrade --install grafana bitnami/grafana --namespace loki-grafana

Grafana’yı ingress ile dışarı verdikten sonra arayüzüne bağlanıp “Data Source” ekliyoruz.

URL kısmına lokinin gateway servisinin adını yazıyoruz;

loki-grafana-loki-gateway.loki-grafana.svc.cluster.local
image 20

Rancher arayüzünden aynı şekilde ClusterOutput ve ClusterFlow oluşturuyoruz. Tek farkı Output’u Loki olarak seçiyoruz. Aynı şekilde URL kısmına da Loki gateway servisimizi başında http olacak şekilde yazıyoruz.

http://loki-grafana-loki-gateway.loki-grafana.svc.cluster.local
image 21

Ek olarak eğer oluşturduğunuz Output’u grafana tarafındada labelleri ayırmak istiyorsanız aşağıdaki YAML parametrelerini Output’u oluşturduktan sonra eklemeniz gerekir.

image 22
spec:
  loki:
    buffer:
      timekey: 1m
    extra_labels:
      env: asdasdasd

Yukarıdaki buffer logun kaç dakikada bir gönderileceğini belirler. Ben 1 dakika olarak ayarladım. Defaultu 10 dakikadır. ENV sizin label keyinizdir, asdasdasd ise label value’sudur.

image 23

Şimdi Grafana üzerinden loglarımızı görelim.

image 24