• NCP(Naver Cloud Platform) - Search Engine Server + Fluent bit 연동 (feat. {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Action/metadata line [1] contains an unknown parameter [_type]"}],"type":"illegal_argument_exception","reason":"

    2024. 7. 12.

    by. Daramu

    일전에 Fluent bit의 글을 쓴적이 있는데, 관련해서 말이 너무 부실하기도 하고, 설정법이나 ACG에 대한 이야기도 빠져있어서 한번 제대로 해보려한다.

     

    1. Search Engine Service(이하 SES)

    많이들 착각하는 것이 SES는 단순한 대시보드(Dashboard)라는 것이다.

    SES가 자체적으로 Log를 수집한다거나, 무엇인가 다이나믹한 동작을 하지는 않는 것이다.

     

    그렇기에 사용자는 직접 Log를 쏴줘야 하고, 이 때 선택하는 옵션이 "로그 수집기"이다.

    로그 수집기는 몇가지가 있다. 대표적으로 익숙한 것이 ELK스택의 LogStash이다.

     

    다만 ELK는 라이센스에 관한 시비가 존재한다.

    내부망이나 개인 로컬PC(이게 내부망과 같은 의미이기는 하지만) 에서는 문제가 없지만 이것을 기업이 판매할 수는 없다.

    대표적으로 AWS와 NCP가 그러하다.

     

    그런 정책에 반발하여 나온것이 OpenSearch로, AWS가 프로젝트를 이끌고 있다.

    ==========================

     

    대강의 이야기는 여기까지이며, 본론을 넘어가자면 라이센스의 문제로 미래가 불투명 하기에 ELK스택은 사용하지 않을 것이다.

     

    그렇기에 대용으로 OFO를 사용할 것이다. 순서대로

    OpenSearch, Fluent bit, OpenSearchDashboard 정도 되겠다.

     

    우선 OpenSearch 관련은 NCP의 SES를 사용하여 처리할 것이고, Fluent bit 는 마찬가지로 NCP의 NKS(Naver Kubernetes Service)의 환경에서 구축할 것이다.

     

    NKS 장점이자 단점은 마스터 노드에 접근이 불가능 하다는 것이다.

    좋게 말하면 귀찮은게 없는거고 불편하게 말하면 뭘 할수가 없는 것이다(ㅋㅋ)

     

    1. SES 생성

     

    NCP 콘솔에서 SES를 검색하여 들어가서 Cluster 생성 버튼을 클릭한다.

    여기서 이름과 Search Engine 버전을 고를 수 있는데, 이 버전에 OpenSearch와 ElasticSearch가 존재한다.

    우리는 위에서 말했듯이 라이센스 이슈가 매복해있기에, OpenSearch로 생성한다.

     

     

    그 후에는 LB의 Target Group을 생성할 차례다.

    TCP로 하며, 포트는 80번으로 열어준다.

    내부에 포트 포워딩으로 80번으로 접근하면 알아서 WEB이 존재하는 Port로 연결해준다.

     

    적용 Target에 SES 매니저 노드를 넣어준다.

    네이밍 규칙은 {입력한 SES이름}-m-xxxx 이다.

     

    그렇게 생성을 완료했다면, 이제는 LB를 만들 차레이다.

    생성은 네트워크 로드밸런서로 생성한다.

    마찬가지로 TCP 80을 리스너로 설정하고, Target Group에 위에서 만든 그룹을 추가하면 끝이다.

     

     

    마지막으로 "매니저 노드 ACG"에 LB로의 인바운드를 허용하면 끝이다.

     

    그럼 생성한 LB를 통해 접근한다면 Opensearch 홈페이지에 접근이 가능하다.

     

     

     

    이제 그릇이 완성되었으니 그릇에 올릴 음식을 준비하면 된다.

     

    다만 그 전에 확인해야할 것이 존재한다. LB 80포트->SES 매니저노드 에서 SES 매니저 노도 ACG에 LB를 열었듯이, 이번에는 NKS 9200포트->SES매니저 노드 이므로 해당하는 ACG도 열어야 한다.

     

    매니저 노드의 ACG에 인바운드로 "NKS Node"의 접근을 허용한다.

     

    생성한 NKS에 접근해서 SA, CM, DS 를 생성한다.

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: fluentbit
      namespace: fluentbit-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: fluentbit
    rules:
      - apiGroups: [""]
        resources:
          - namespaces
          - pods
          - nodes
          - nodes/proxy
        verbs:
          - get
          - list
          - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: fluentbit
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: fluentbit
    subjects:
      - kind: ServiceAccount
        name: fluentbit
        namespace: fluentbit-system
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: fluent-bit-config
      namespace: fluentbit-system
      labels:
        k8s-app: fluent-bit
    data:
      fluent-bit.conf: |
        [SERVICE]
            Flush         1
            Log_Level     info
            Daemon        off
            Parsers_File     /fluent-bit/etc/parsers.conf
        @INCLUDE input-kubernetes.conf
        @INCLUDE filter-kubernetes.conf
        @INCLUDE output-opensearch.conf
    
      input-kubernetes.conf: |
        [INPUT]
            Name             tail
            Path             /var/log/containers/*.log
            Tag              kube.*
            Parser           cri
            Mem_Buf_Limit    0
            Skip_Long_Lines  On
    
      filter-kubernetes.conf: |
        [FILTER]
            Name             kubernetes
            Match            kube.*
            Kube_URL         https://kubernetes.default.svc:443
    
      output-opensearch.conf: |
        [OUTPUT]
            Name            opensearch
            Match           *
            Host            매니저노드IP
            Port            9200
            HTTP_User       ID
            HTTP_Passwd     PW
            tls             On
            tls.verify      Off
            Index           nks-%Y.%m.%d
            Suppress_Type_Name on
    
      parsers.conf: |
        [PARSER]
            # http://rubular.com/r/tjUt3Awgg4
            Name cri
            Format regex
            Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<message>.*)$
            Time_Key    time
            Time_Format %Y-%m-%dT%H:%M:%S.%L%z
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentbit-daemonset
      namespace: fluentbit-system
      labels:
        app.kubernetes.io/name: fluentbit
    spec:
      selector:
        matchLabels:
          name: fluentbit
      template:
        metadata:
          labels:
            name: fluentbit
        spec:
          serviceAccountName: fluentbitds
          containers:
            - name: fluent-bit
              imagePullPolicy: Always
              image: fluent/fluent-bit:latest
              ports:
              - containerPort: 9090
              volumeMounts:
                - name: varlog
                  mountPath: /var/log
                - name: varlibdockercontainers
                  mountPath: /var/lib/docker/containers
                  readOnly: true
                - name: fluent-bit-config
                  mountPath: /fluent-bit/etc/
          volumes:
            - name: varlog
              hostPath:
                path: /var/log
            - name: varlibdockercontainers
              hostPath:
                path: /var/lib/docker/containers
            - name: fluent-bit-config
              configMap:
                name: fluent-bit-config

     

    하나 추가된 것이있다.

    이건 NCP의 문제가 아니라 Fluent bit의 문제이다.

    _type 필드가 삭제되어 발생하는 에러로 

     

    [2024/07/12 07:19:32] [error] [engine] chunk '1-1720768765.719681802.flb' cannot be retried: task_id=3, input=tail.0 > output=opensearch.0
    [2024/07/12 07:19:32] [error] [engine] chunk '1-1720768764.719033335.flb' cannot be retried: task_id=2, input=tail.0 > output=opensearch.0
    [2024/07/12 07:19:32] [error] [output:opensearch:opensearch.0] HTTP status=400 URI=/_bulk, response:
    {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Action/metadata line [1] contains an unknown parameter [_type]"}],"type":"illegal_argument_exception","reason":"Action/metadata line [1] contains an unknown parameter [_type]"},"status":400}

    이런 에러가 발생한다.

     

    해법은 아니지만 임시방편으로 가능한 방법은 yaml파일에도 있지만 아래의 옵션을 추가하는 것이다.

    Suppress_Type_Name on

     

    적용 한 후에 동작시키면?

     

    깔끔히 잘 돌아간다.

     

     

    그럼 이제 OpenSearch 대시보드로 돌아간다.

    Configmap을 만들때 Index라는 옵션을 넣어서 해당 이름으로 Index가 생성되고 있을것이다.

    Index           nks-%Y.%m.%d

     

    해당 사실은 좌측상단 메뉴 -> 최하단 Index Management -> Indexes 에서 확인이 가능하다.

     

     

    그리고 대시보드를 클릭하면 Index pattern을 생성하라고 할것이다.

     

     

    생성하라하니 생성해주면 되는데, 생성한 index 네임이 시간별이다. 즉, 내일은 내일 일자로 새로운 index가 생성된다.

    그렇기에 무턱대고 index 이름을 적으면 안되고, *(뒤 모두 포함)을 사용해서 Index Pattern을 생성한다.

     

     

     

    그리고 Discover로 돌아가보면?

     

     

     

    완료.

     

     

     

     

    댓글