ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • k8s에 Logstash 환경 구축하기
    환경 구축 2024. 10. 28. 00:00

    자동목차


    지난번 포스팅에서는 elastic 환경을 구축해봤습니다.

    https://shinebyul.tistory.com/73

     

    k8s에 Elasticsearch 환경 구축하기

    자동목차  진행중인 프로젝트에서 query dsl 을 사용해서 검색기능을 구현했었는데,제목, 카테고리, 해시태그 등에서 키워드를 찾다보니 join 연산이 많이 필요했습니다.그러다보니 검색 성능이

    shinebyul.tistory.com

     

    elasticsearch 서버 만으로도 검색 기능을 구현할 수는 있지만, 그럼 DB 내용을 업데이트 할 때마다 Elasticsearch에 데이터를 같이 넣어주어야하겠죠?

    Logstash의 파이프라인을 이용한다면 db에 저장된 내용을 알아서 수집해서 elasticsearch 로 데이터를 넣어주도록 할 수 있습니다!

     

    따라서 이번 포스팅에서는 Logstash 환경을 구축해보겠습니다.

     

     

    Logstash 환경 구축

    1️⃣  파이프라인 작성

    먼저 파이프라인를 구축해보겠습니다.

     

    파이프라인은 크게 input, output 세 필드로 구분돼있는데요, 

    쉽게 말해

    - input은 db를 가져오는 부분,

    - filter는 가공하고 처리하는 부분,

    - output은 가져롸서 처리한 데이터를 es로 보내는 부분입니다.

    저는 필드는 필요없는 부분이라 생략했습니다.

     

    input {
      jdbc {
        jdbc_driver_library => "/usr/share/logstash/mariadb-java-client-3.4.1.jar"
        jdbc_driver_class => "org.mariadb.jdbc.Driver"
        jdbc_connection_string => "jdbc:mariadb://mariadb-slave-svc.default.svc.cluster.local:3306/elk"
        jdbc_user => "root"
        jdbc_password => "qwer1234"
    
        # sql_last_value -> logstash에서 내부적으로 다루는 마지막 실행 시간 변수
        #  마지막 실행 시간 이후에 업데이트된 updated_at 컬럼 값을 기준으로 데이터를 가져옴
        statement => "SELECT * FROM member WHERE COALESCE(modified_at, created_at) > :sql_last_value"
        
        schedule => "*/10 * * * * *" # 10초마다 실행
      }
    }
    output {
      elasticsearch {
        hosts => ["http://elasticsearch:9200"] #Statefulset으로 pod 만들었을 때
        # hosts => ["http://elasticsearch-eck:9200"] #eck로 pod 만들었을 때
        user => "elastic"  # Elasticsearch 인증 사용자
        password => "qwer1234"  # Elasticsearch 사용자 비밀번호
        index => "elk-data" # 없으면 새로 만들어서 저장
      }
      stdout { }
    }

     

    input

    1. db에 접근해 쿼리를 날리기 위해서는 jdbc driver가 필요합니다. 

    jdbc_driver_library => "/usr/share/logstash/mariadb-java-client-3.4.1.jar"
    jdbc_driver_class => "org.mariadb.jdbc.Driver"

    /usr/share/logstash/ 이 경로는 로그스태시 서버의 경로인데요, 여기서 jdbc driver를 가져다 쓰려면 먼저 이 경로에 jdbc driver를 넣어주어야 하겠죠? 이 부분은 아래에서 설명드리겠습니다

     

    2. 연결할 db의 주소, user, password를 작성해줍니다.

    jdbc_connection_string => "jdbc:mariadb://mariadb-slave-svc.default.svc.cluster.local:3306/elk"
    jdbc_user => "root"
    jdbc_password => "qwer1234"

     

    'mariadb-slave-svc.default.svc.cluster.local' 이 주소는 k8s내의 슬레이브 db 주소입니다.

    💡 db는 default namespace, logstash는 elk라는 namespace에 있습니다.
    다른 네임스페이스끼리는 서비스이름 만으로는 연결이 안되기 때문에 경로를 다 적어주어야합니다.
    mariadb-slave-svc가 아닌 mariadb-slave-svc.default.svc.cluster.local라고 적은 이유도 이때문입니다.

     

    3. statement 부분이 db로부터 데이터를 가져오기 위한 쿼리문입니다.

    statement => "SELECT * FROM member WHERE COALESCE(modified_at, created_at) > :sql_last_value"
    
    schedule => "*/10 * * * * *" # 10초마다 실행

     

    중복된 데이터를 가져오지 않게 하기위해서 modified_at, created_at 그리고 sql_last_value를 사용해 최근 수정됐거나 생성된 데이터만 가져오도록 했습니다.

    깃허브 참고하시면 더 복잡한 파이프라인 예시가 있으니 참고해주세요😄

     

    :sql_last_value는 마지막으로 날린 쿼리 시간을 기억하는 플래그입니다. 초기에는 1970년도로 설정돼있어서 파이프라인이 처음 돌 때는 모든 db의 데이터를 가져오게됩니다. 

     

    schedule => "*/ 5 * * * *" 는 5분마다 쿼리를 날리는 코드입니다.

    크론 방식으로, 다양한 시간 설정이 있지만 여기서는 따로 설명하지 않겠습니다

     

    output

    output에는 연결할 es 주소, user, password 그리고 해당 쿼리로 가져온 데이터를 저장할 인덱스를 적어주면 됩니다.

    elasticsearch {
      hosts => ["http://elasticsearch:9200"] #Statefulset으로 pod 만들었을 때
      # hosts => ["http://elasticsearch-eck:9200"] #eck로 pod 만들었을 때
      user => "elastic"  # Elasticsearch 인증 사용자
      password => "qwer1234"  # Elasticsearch 사용자 비밀번호
      index => "elk-data" # 없으면 새로 만들어서 저장
    }

     

    es환경 구축하면서 외부 플러그인을 사용하는 경우(ECK)와 사용하지 않는 경우(Statefulset)를 나눴었는데요, 그에 맞는 Service주소를 적어주면 됩니다.

     

    2️⃣ ConfigMap 작성

    이렇게 작성한 파이프라인을 k8s에 배포된 logstash가 읽게 하기 위해 configMap으로 작성해보겠습니다

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: logstash-config
      namespace: elk
    data:
      logstash.conf: |
        input {
          jdbc {
            jdbc_driver_library => "/usr/share/logstash/mariadb-java-client-3.4.1.jar"
            jdbc_driver_class => "org.mariadb.jdbc.Driver"
            jdbc_connection_string => "jdbc:mariadb://mariadb-slave-svc.default.svc.cluster.local:3306/elk"
            jdbc_user => "root"
            jdbc_password => "qwer1234"
    
            # sql_last_value -> logstash에서 내부적으로 다루는 마지막 실행 시간 변수
            #  마지막 실행 시간 이후에 업데이트된 updated_at 컬럼 값을 기준으로 데이터를 가져옴
            statement => "SELECT * FROM member WHERE COALESCE(modified_at, created_at) > :sql_last_value"
    
            schedule => "*/10 * * * * *" # 10초마다 실행
          }
        }
    
        output {
          elasticsearch {
            hosts => ["http://elasticsearch:9200"] #Statefulset으로 pod 만들었을 때
            # hosts => ["http://elasticsearch-eck:9200"] #eck로 pod 만들었을 때
            user => "elastic"  # Elasticsearch 인증 사용자
            password => "qwer1234"  # Elasticsearch 사용자 비밀번호
            index => "elk-data" # 없으면 새로 만들어서 저장
          }
          stdout { }
        }

     

     

    3️⃣ Deployment 작성

    이제 이 작성한 로그스태시 파이프라인 컨피그맵을 이용해 로그스태시 deployment를 만들어줍니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: logstash
      namespace: elk
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: logstash
      template:
        metadata:
          labels:
            app: logstash
        spec:
          containers:
            - name: logstash
              image: docker.elastic.co/logstash/logstash:7.17.16
              ports:
                - containerPort: 50000
                  name: logs-tcp
                - containerPort: 9600
                  name: logs-monitor
              volumeMounts:
                - name: logstash-config
                  mountPath: /usr/share/logstash/pipeline/logstash.conf
                  subPath: logstash.conf
                - name: mariadb-driver
                  mountPath: /usr/share/logstash/mariadb-java-client-3.4.1.jar
                  subPath: mariadb-java-client-3.4.1.jar
              env:
                - name: LOGSTASH_JAVA_OPTS
                  value: "-Xms256m -Xmx1g"
          volumes:
            - name: logstash-config
              configMap:
                name: logstash-config
            - name: mariadb-driver
              configMap:
                name: mariadb-driver

     

    여기서 볼륨설정하는 부분을 보면, logstash configmap(pipeline)과 mariadb driver를 볼륨 마운트 해주고 있습니다.

     

    logstash configmap은 이미 작성했고, mariadb driver를 컨피그맵으로 만들어 볼륨설정 되도록 해보겠습니다.

     

    mariadb-jdbc-driver 파일로 ConfigMap 만들기

    1. mariadb driver 를 다운받는다.

    https://downloads.mariadb.com/Connectors/java/connector-java-2.6.2/

     

    2. scp로 로컬 컴퓨터에 있는 다운로드 파일을 마스터 노드에 넣어준다.

    scp 로컬경로/mariadb-java-client-3.4.1.jar [마스터노드사용자]@[마스터노드 ip]:/home/test 

    scp 로컬경로/mariadb-java-client-3.4.1.jar test@123.123.123.123:/home/test 

     

    3. 마스터에 ssh로 접속해서 해당 파일을 이용해 컨피그맵을 만든다

    test@master:~$ kubectl create configmap [컨피그맵 이름] --from-file=/home/test/mariadb-java-client-3.4.1.jar -n [네임스페이스 이름] 


    아래 명령어를 사용하면 잘 만들어졌는지 확인 가능
    kubectl describe configmap [컨피그맵 이름] -n [네임스페이스 이름]

     

    이렇게 하면 logstash 구축에 필요한 과정은 끝났습니다.

    해당 yml 파일들을 이용해 logstash를 구축한 후에 로그를 보면 설정한 시간이 되면 작성했던 select쿼리가 날라가는 것을 볼 수 있습니다.

     

    깃허브 주소

    필요한 파일들을 정리해둔 깃허브 주소입니다.

    https://github.com/shinebyul/elk_k8s_setting

     

    GitHub - shinebyul/elk_k8s_setting: k8s에 elk 환경 세팅하기

    k8s에 elk 환경 세팅하기. Contribute to shinebyul/elk_k8s_setting development by creating an account on GitHub.

    github.com

Designed by Tistory.