install ELK (elastic, logstash, kibana) with elastalert on k8s

0
807

halo sobat sekolahlinux, kali ini saya akan coba memberikan sedikit tutorial bagaimana install ELK di kubernetes dan juga bagaimana cara memasang alert pada elastic dengan elastalert, oke yuk langsung masuk ke materinya.

 

Install HELM

pada step ini saya akan menggunakan tool helm untuk installasi elk pada k8s, sebelumnya sobat perlu mendownload dan install helm 3, untuk tutorial install helmnya sobat bisa lihat url dibawah ini

  • https://helm.sh/docs/intro/install/

 

Setup ELK (elastic, logstash, kibana) with HELM

selanjutnya sobat perlu menambahkan repo helm milik elastic, yang mana repo ini nantinya sobat akan gunakan untuk install elasticsearch, logstash dan kibana

helm repo add elastic https://helm.elastic.co

oh iya pada saat saya membuat tutorial ini saya menggunakan chart & app elasticsearch, logstash & kibana versi 7.9.1, untuk melihat semua versi yang ada di repo sobat bisa menggunakan perintah dibawah ini

helm search repo elastic/elasticsearch -l
helm search repo elastic/logstash -l
helm search repo elastic/kibana -l

lalu jika sobat ingin melihat version yang terpasang saat ini sobat bisa menggunakan perintah dibawah

helm search repo elastic/elasticsearch
helm search repo elastic/logstash
helm search repo elastic/kibana

selanjutnya kita perlu download values dari elasticsearch, logstash dan kibana degan command dibawah ini

helm inspect values elastic/elasticsearch > elastic.yaml
helm inspect values elastic/logstash > logstash.yaml
helm inspect values elastic/kibana > kibana.yaml

jika sudah sekarang coba buka values elastic.yaml dan coba lihat pada bagian paramater ini dibawah ini dan sesuaikan valuesnya dengan yang ada dibawah ini

service:
  labels: {}
  labelsHeadless: {}
  type: NodePort
  nodePort: ""
  annotations: {}
  httpPortName: http
  transportPortName: transport
  loadBalancerIP: ""
  loadBalancerSourceRanges: []

clusterHealthCheckParams: "wait_for_status=yellow&timeout=1s"

lalu selanjutnya buka values logstash.yaml dan coba lihat pada bagian paramater ini dibawah ini dan sesuaikan valuesnya dengan yang ada dibawah ini, pada filter saya menambahkan grok untuk parsing log access dan error nginx

logstashPipeline:
   logstash.conf: |
          input {
              beats {
                  port => "5044"
                  ssl => false
              }
          }
          filter {
              grok {
                  match => { "message" => ['(?<time>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) .%{LOGLEVEL:level}. (?<pid-threadid>%{POSINT}#%{NUMBER}.) %{GREEDYDATA:log}"}','%{IP:client_ip} (?<ident>-) (?<auth>-) \[%{HTTPDATE:timestamp}\] "%{WORD:methode} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} %{GREEDYDATA:log}'] }
              }
          }
          output {
              elasticsearch {
                  hosts => ["elasticsearch-master:9200"]
                  index => "%{[@metadata][beat]}-%{[@metadata][version]}"
              }
          }

service:
  annotations: {}
  type: NodePort
  ports:
    - name: beats
      port: 5044
      protocol: TCP
      targetPort: 5044
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080

lalu selanjutnya buka values kibana.yaml dan coba lihat pada bagian paramater ini dibawah ini dan sesuaikan valuesnya dengan yang ada dibawah ini

service:
  type: NodePort
  loadBalancerIP: ""
  port: 5601
  nodePort: ""
  labels: {}
  annotations: {}
    # cloud.google.com/load-balancer-type: "Internal"
    # service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
    # service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    # service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
    # service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true"
  loadBalancerSourceRanges: []
    # 0.0.0.0/0

selanjutnya jika sudah jalankan perintah dibawah ini untuk installasinya

helm install elastic -f elastic.yaml elastic/elasticsearch
helm install logstash -f logstash.yaml elastic/logstash
helm install kibana -f kibana.yaml elastic/kibana

 

Setup Elastalert

untuk setup elastalert ini kita akan menggunakan beberapa file manifest k8s yang kamu bisa download di

  • https://github.com/akbaribnu/elk-with-elastalert/tree/master/elastalert

download 3 file dari repo diatas yaitu file

configmap-config.yaml  
configmap-rules.yaml  
deployment.yaml

file configmap-config.yaml berisi config elastalert config.yaml, kurang lebih isinya seperti dibawah ini, dan untuk referensi lengkapnya kalian bisa mengunjungi doc dari elastalert di https://elastalert.readthedocs.io/en/latest/running_elastalert.html#downloading-and-configuring

apiVersion: v1
kind: ConfigMap
metadata:
  name: elastalert-conf
  namespace: default
data:
  config.yaml: |
        rules_folder: rules
        scan_subdirectories: False
        run_every:
          minutes: 1
        buffer_time:
          minutes: 15
        es_host: elasticsearch-master
        es_port: 9200
        use_ssl: False
        writeback_index: elastalert_status
        writeback_alias: elastalert_alerts
        alert_time_limit:
          days: 2

file configmap-rules.yaml berisi config rule alert elastalert http_404.yaml & http_200.yaml, kurang lebih isinya seperti dibawah ini, dan ini bisa kalian tambahkan dan rubah, untuk referensi lengkapnya kalian bisa mengunjungi doc dari elastalert di https://elastalert.readthedocs.io/en/latest/running_elastalert.html#creating-a-rule

apiVersion: v1
kind: ConfigMap
metadata:
  name: elastalert-rules
  namespace: default
data:
  http_404.yaml: |
        name: alert 404 http code
        type: frequency
        index: filebeat-*
        num_events: 3
        timeframe:
          hours: 1
        filter:
        - query:
            query_string:
              query: "message: akbar AND message: curl AND client_ip: 192.168.99.100"
        alert:
        - "slack"
        slack_webhook_url: "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxx/xxxxxxxx"

  http_200.yaml: |
        name: alert 200 http code
        type: frequency
        index: filebeat-*
        num_events: 3
        timeframe:
          hours: 1
        filter:
        - term:
            response: "200"
        alert:
        - "slack"
        slack_webhook_url: "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxx/xxxxxxxx"

#rule dibawah ini digunakan untuk whitelist alert, jika didalam field yang didaftarkan pada query mengandung value gajah dan jerapah walaupun itu match maka tidak alert tidak akan dikirim, namun sebaliknya jika tidak terdapat value gajah dan jerapah maka akan mengirimkan alert
  access_name.yaml: |
        name: connection timeout
        type: whitelist
        index: kubernetes_cluster-*
        ignore_null: true
        compare_key: kubernetes.container_name
        whitelist:
        - "gajah"
        - "jerapah"
        num_events: 1
        timeframe:
          hours: 1
        realert:
          minutes: 1
        filter:
        - query:
            query_string:
              query: "log: nama AND log: binatang AND kubernetes.namespace_name: production"
        include: ["kubernetes.pod_name", "kubernetes.namespace_name", "log"]
        alert:
        - "slack"
        slack_webhook_url: "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxx/xxxxxxxx"

lalu pada file deployment.yaml berisi paramater seperti dibawah ini

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elastalert-sekolahlinux
  namespace: default
spec:
  revisionHistoryLimit: 1
  strategy:
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app: elastalert
  template:
    metadata:
      labels:
        app: elastalert
    spec:
      containers:
      - name: elastalert-sekolahlinux
        image: sekolahlinux/elastalert
        imagePullPolicy: IfNotPresent
        #imagePullPolicy: Always
        volumeMounts:
        - name: elastalert-conf
          mountPath: "/elastalert/config"
        - name: elastalert-rules
          mountPath: "/elastalert/rules"
        env:
          - name: "CREATED_BY"
            value: "SEKOLAHLINUX-AKBAR"
      volumes:
      - name: elastalert-conf
        configMap:
          name: elastalert-conf
      - name: elastalert-rules
        configMap:
          name: elastalert-rules

selanjutnya kalian bisa apply 3 file diatas

kubectl apply -f configmap-config.yaml 
kubectl apply -f configmap-rules.yaml 
kubectl apply -f deployment.yaml

selanjutnya coba lihat pod di k8s

sekolahlinux@sekolahlinux:~/akbar/elk-with-elastalert/elastalert$ kubectl get pods
NAME                                           READY   STATUS        RESTARTS   AGE
pod/elastalert-sekolahlinux-5bf9fc689c-ntgqg   1/1     Running       0          1s
pod/elasticsearch-master-0                     1/1     Running       0          4h44m
pod/elasticsearch-master-1                     1/1     Running       0          4h44m
pod/elasticsearch-master-2                     1/1     Running       0          4h44m
pod/kibana-kibana-7798666765-mgpvt             1/1     Running       0          4h44m
pod/logstash-logstash-0                        1/1     Running       0          4h44m

jika sudah maka selanjutkan jalankan perintah dibawah ini untuk masuk kedalam pod elastalert

kubectl exec -it elastalert-sekolahlinux-5bf9fc689c-ntgqg bash

selanjutnya dari dalam pods jalankan perintah elastalert-create-index untuk generate indices pada elastic, seperti dibawah ini

root@elastalert-sekolahlinux-5bf9fc689c-ntgqg:/elastalert# elastalert-create-index
Enter Elasticsearch host: elasticsearch-master
Enter Elasticsearch port: 9200
Use SSL? t/f: f
Enter optional basic-auth username (or leave blank): 
Enter optional basic-auth password (or leave blank): 
Enter optional Elasticsearch URL prefix (prepends a string to the URL of every request): 
New index name? (Default elastalert_status) 
New alias name? (Default elastalert_alerts) 
Name of existing index to copy? (Default None) 
Elastic Version: 7.9.1
Reading Elastic 6 index mappings:
Reading index mapping 'es_mappings/6/silence.json'
Reading index mapping 'es_mappings/6/elastalert_status.json'
Reading index mapping 'es_mappings/6/elastalert.json'
Reading index mapping 'es_mappings/6/past_elastalert.json'
Reading index mapping 'es_mappings/6/elastalert_error.json'
Deleting index elastalert_status_status.
New index elastalert_status created
Done!

maka jika sudah, kita bisa lihat indices hasil generate elastic seperti pada gambar dibawah ini

selanjutnya kita tinggal simulasikan web server nginx yang sudah terpasang filebeat yang mengarah ke logstash di k8s untuk mendapatkan error 404, dalam hal ini saya melakukan random curl pada web server

curl http://192.168.10.100/asdsd
curl http://192.168.10.100/asdsdqw
curl http://192.168.10.100/asdsdas
curl http://192.168.10.100/asds3
curl http://192.168.10.100/asdsd124
curl http://192.168.10.100/asds3

lalu jika sudah coba cek log pods elastalert-sekolahlinux-5bf9fc689c-ntgqg, maka kurang lebih log nya akan seperti dibawah ini

sekolahlinux@sekolahlinux:~/akbar/elk-with-elastalert/elastalert$ kubectl logs -f elastalert-sekolahlinux-5bf9fc689c-rw578
INFO:elastalert:Starting up
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999932 seconds
INFO:elastalert:Queried rule alert 200 http code from 2020-09-14 10:51 UTC to 2020-09-14 10:52 UTC: 0 / 0 hits
INFO:elastalert:Ran alert 200 http code from 2020-09-14 10:51 UTC to 2020-09-14 10:52 UTC: 0 query hits (0 already seen), 0 matches, 0 alerts sent
INFO:elastalert:Queried rule alert 404 http code from 2020-09-14 10:52 UTC to 2020-09-14 10:52 UTC: 0 / 0 hits
INFO:elastalert:Ran alert 404 http code from 2020-09-14 10:52 UTC to 2020-09-14 10:52 UTC: 0 query hits (0 already seen), 0 matches, 0 alerts sent

INFO:elastalert:Background configuration change check run at 2020-09-14 10:53 UTC
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999879 seconds
/usr/local/lib/python3.8/site-packages/urllib3-1.25.10-py3.8.egg/urllib3/connectionpool.py:981: InsecureRequestWarning: Unverified HTTPS request is being made to host 'hooks.slack.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  warnings.warn(
INFO:elastalert:Alert 'alert 404 http code' sent to Slack
INFO:elastalert:Background alerts thread 1 pending alerts sent at 2020-09-14 10:53 UTC
INFO:elastalert:Queried rule alert 200 http code from 2020-09-14 10:51 UTC to 2020-09-14 10:53 UTC: 0 / 0 hits
INFO:elastalert:Ran alert 200 http code from 2020-09-14 10:51 UTC to 2020-09-14 10:53 UTC: 0 query hits (0 already seen), 0 matches, 0 alerts sent
INFO:elastalert:Queried rule alert 404 http code from 2020-09-14 10:52 UTC to 2020-09-14 10:53 UTC: 6 / 6 hits
/usr/local/lib/python3.8/site-packages/urllib3-1.25.10-py3.8.egg/urllib3/connectionpool.py:981: InsecureRequestWarning: Unverified HTTPS request is being made to host 'hooks.slack.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  warnings.warn(
INFO:elastalert:Alert 'alert 404 http code' sent to Slack
INFO:elastalert:Ignoring match for silenced rule alert 404 http code
INFO:elastalert:Ran alert 404 http code from 2020-09-14 10:52 UTC to 2020-09-14 10:53 UTC: 6 query hits (0 already seen), 2 matches, 1 alerts sent
INFO:elastalert:Background configuration change check run at 2020-09-14 10:54 UTC
INFO:elastalert:Background alerts thread 0 pending alerts sent at 2020-09-14 10:54 UTC
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999892 seconds

dan alert di slack pun akan muncul seperti dibawah ini

sekian tutorial kali ini, terimakasih sudah membaca 😀

source git elastalert bisa kamu lihat di:

docker image elastalert yang saya buat bisa kamu temukan disini: