본문으로 바로가기
반응형

이전 포스팅을 통해 Kafka에 대해 간단하게 실습했었다. 이제 메시지들을 주고받는 상황을 시각화 해볼 차례이다.Kafka 실습 (3) - Zookeeper + Kafka + Kafka Manager 설치 및 간단예제

Logstash + Elasticsearch + Kibana 를 이용하여 시각화를 해보자.

Elasticsearch + Kibana

/home/user 경로에 새로운 elasticsearch-kibana-docker-compose.yml 파일을 생성 후 아래 소스를 입력하고 저장한다.

version: '2.2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.3.2
    container_name: elasticsearch
    environment:
      - node.name=elasticsearch
      - discovery.seed_hosts=elasticsearch
      - cluster.initial_master_nodes=elasticsearch # node.name 과 동일해야함 그렇지 않으면 멀티노드의 경우 마스터 선출이 되지않아 클러스터 uuid 가 _na_ 로 표기됨
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - esdata1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200

  kibana:
    image: docker.elastic.co/kibana/kibana:7.3.2
    container_name: kibana
    environment:
      ELASTICSEARCH_URL: "http://elasticsearch:9200"
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch

volumes:
  esdata1:
    driver: local

멀티 노드 구성

version: '2.2'
services:
  es1:
    build:
      context: ./
      dockerfile: ./dockerFiles/esDockerfile
    container_name: es1
    environment:
      - node.name=es1
      - cluster.name=docker-cluster
      - discovery.seed_hosts=es1,es2,es3
      - cluster.initial_master_nodes=es1,es2,es3
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - xpack.security.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - esdata1:/usr/share/es/data
    ports:
      - 9200:9200
      - 9300:9300
    restart: always

  es2:
    build:
      context: ./
      dockerfile: ./dockerFiles/esDockerfile
    container_name: es2
    environment:
      - node.name=es2
      - cluster.name=docker-cluster
      - discovery.seed_hosts=es1,es2,es3
      - cluster.initial_master_nodes=es1,es2,es3
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - xpack.security.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - esdata2:/usr/share/es/data
    ports:
      - 9301:9300
    restart: always
    depends_on:
      - es1

  es3:
    build:
      context: ./
      dockerfile: ./dockerFiles/esDockerfile
    container_name: es3
    environment:
      - node.name=es3
      - cluster.name=docker-cluster
      - discovery.seed_hosts=es1,es2,es3
      - cluster.initial_master_nodes=es1,es2,es3
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - xpack.security.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - esdata3:/usr/share/es/data
    ports:
      - 9302:9300
    restart: always
    depends_on:
      - es1

  kibana:
    image: docker.elastic.co/kibana/kibana:8.3.3
    container_name: kibana
    environment:
      - xpack.reporting.kibanaServer.hostname=localhost
      - ELASTICSEARCH_URL='["http://es1:9200"]'
    ports:
      - 5601:5601
    restart: always
    depends_on:
      - es1
      - es2
      - es3

volumes:
  esdata1:
    driver: local
  esdata2:
    driver: local
  esdata3:
    driver: local

Elasticsearch vm.max_map_count 값 수정

Elasticsearch의 공식 홈페이지에서도 볼 수 있듯이 위의 값이 적어도 262144 여야한다고 한다.vm max map count

따라서 아래 명령어로 설정한다.

sudo /usr/sbin/sysctl -w vm.max_map_count=262144

하지만 위의 방식은 서버가 재부팅 될 경우 설정이 초기화 되므로 아래 방식으로 영구로 적용한다

vi /etc/sysctl.conf
vm.max_map_count=262144

(2022-04-29 UPDATE)

만약 Window Docker 환경의 경우 아래를 이용하여 확인

wsl -d docker-desktop
cd /etc/sysctl.d
cat /proc/sys/vm/max_map_count
echo -e "\nvm.max_map_count = 262144\n" >> /etc/sysctl.d/00-alpine.conf
cat /proc/sys/vm/max_map_count

00-alpine.conf 파일명이 다를 수 있으므로 sysctl.d 에서 ls 명령어로 확인


마찬가지로 다음 명령어를 통해 ElasticsearchKibana를 실행한다.

docker-compose -f elasticsearch-kibana-docker-compose.yml up

Elasticsearch9200 포트를 사용한다. 따라서 정상실행 후 웹으로 접근하면 기본값으로 다음 화면을 볼 수 있다.


Kibana5601 포트를 사용한다. 따라서 정상실행 후 웹으로 접근하면 다음 화면을 볼 수 있다.


LogStash Install

공식홈페이지에서 간단하게 설치 방법을 찾을 수 있다.Logstash Install

무작정 yum을 통해 설치를 할 수 없다. 따라서 위 링크의 내용에 따라 작업이 필요하다.

sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

디렉토리 /etc/yum.repos.d/ 경로 하위에 logstash.repo를 생성한다. (사실 *.repo 파일명은 상관없다)

sudo vi /etc/yum.repose.d/logstash.repo
[logstash-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

위 내용을 입력 후 저장

sudo yum -y install logstash

마지막으로 명령어를 통해 설치를 진행한다.


설치가 완료되면 다음 경로에 설정 파일을 만들어 내용을 추가한다.

sudo vi /etc/logstash/conf.d/kafka-elastic.conf
input {
    kafka {
            bootstrap_servers => "{ip address}:9092"
            topics => ["registered_user"]
    }
}

output {
   elasticsearch {
      hosts => ["{ip address}:9200"]
      index => "registered_user"
      workers => 1
    }
}

{ip address}에는 본인의 IP를 입력한다. 로컬에서 작업하는 거라면 사설 IP를, 서버가 외부라면 Public IP를 입력한다.
포스팅에선 192.168.145.130을 사용했다.


logstash conf

Input Kafka Multiple Topics Setup => Output Elasticsearch Index

  • decorate_events => 이걸 설정해야 @metadata 같이 옵션 사용가능
input {
    kafka {
            bootstrap_servers => "{ip address}:9092"
            topics => ["토픽1", "토픽2", ... , "토픽N"]
            decorate_events => true
            codec => plain { charset => "UTF-8" }
            add_field => {"es_index" => "%{[@metadata][kafka][topic]}"}
    }
}

filter {

    date {
        match => ["timestamp", "YYYY-MM-dd HH:mm:ss"]
        timezone => "Asia/Seoul"
        target => "@timestamp"
    }
    
    json {
        source => "message"
    }

    mutate {
        remove_field => ["timestamp", "message"]
    }

}

output {
   elasticsearch {
      hosts => ["{ip address}:9200"]
      index => "%{es_index}-%{+YYYY.MM.dd}"
   }
}

절대로 json {} 블록을 mutate.remove_field 블록 보다 뒤에 나오면 안된다.
message 값에 대해서 바인딩을 한 후에 삭제해야하기 때문에 뒤에 나오면 안됨!!
그냥 안나와도 되는 값이라면 뒤에 위치해도 상관없음


서비스를 실행하기 위해 다음 명령어를 입력한다.

service logstash start

정상적으로 실행되었는지 확인하기 위해 상태 명령어를 입력하여 Activerunning 인지 확인한다. (죽은 경우 dead)

service logstash status


여기까지 전부 실행되었다면 앞서 만들었던 producer.py을 실행한 후 Kibana의 메뉴 중 index management로 진입하면 새로운 값이 생성되어 있을 것이다.


확인이 되었다면 Kibana 메뉴 중 Index Patterns 라는 메뉴를 클릭하고 Create index pattern을 클릭한다.


인덱스 패턴을 정의하기 위해 확인된 registered_userIndex pattern에 추가하고 다음단계로 이동한다.


Time Filter field name 항목에 @timestamp로 지정하고 Create index pattern 을 눌러 완료한다.

그러면 해당 인덱스 패턴으로 정의 완료된 화면이 나오게 된다.


마지막으로 좌측 메뉴의 Discover 메뉴로 들어가면 registered_user Topic으로 메시지가 들어오는 것이 확인이 되면 끝 !!!


Kibana read-only

다음과 같은 에러 메세지를 확인하면 다음 명령어를 실행

kibana read-only

kibana           | {"type":"log","@timestamp":"2021-02-09T04:54:31Z","tags":["error","task_manager"],"pid":6,"message":"Failed to poll for work: [cluster_block_exception] index [.kibana_task_manager] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]; :: {path:/.kibana_task_manager/_update/Maps-maps_telemetry,query:{if_seq_no:3,if_primary_term:1,refresh:true},body:{doc:{type:task,task:{taskType:maps_telemetry,state:{runs:1,stats:{mapsTotalCount:0,timeCaptured:2021-02-08T07:20:26.277Z,attributesPerMap:{dataSourcesCount:{min:0,max:0,avg:0},layersCount:{min:0,max:0,avg:0},layerTypesCount:{},emsVectorLayersCount:{}}}},params:{},attempts:0,scheduledAt:2021-02-08T07:20:12.516Z,runAt:2021-02-09T04:55:31.314Z,status:running},kibana:{uuid:0177eee7-dcdf-426e-b872-dd68b2e8df06,version:7030299,apiVersion:1}}},statusCode:403,response:{error:{root_cause:[{type:cluster_block_exception,reason:index [.kibana_task_manager] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];}],type:cluster_block_exception,reason:index [.kibana_task_manager] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];},status:403}}"}
curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'
반응형

'DevOps > ELK' 카테고리의 다른 글

Kibana Index Lifecycle policy 및 Snapshot policy 정리 + AWS S3  (1) 2024.02.15