ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • fluentd를 활용해 kubernetes 로그를 elasticsearch에 저장하고 kibana로 표출 해보자!
    설치&설정 관련 2020. 6. 24. 22:36
    728x90

    fluentd를 활용해 kubernetes 로그를 elasticsearch에 저장하고 kibana로 표출 해보자!

    kubernetes를 셋팅을 하고 다음으로 해야 할일은 모니터링이다.

    그 작업의 기초가 되는일이 바로 로깅을 쌓는 일이다.

    모든 컨테이너의 로그들을 모아서 한 곳에서 확인할 수 있도록 구성했다.

    각 컨테이너에서 로그를 가져오는 것은 fluentd를 이용했다.

    fluentd에서 elasticsearch로 데이터를 적재 하도록 설정하였고, kibana를 통해서 해당 데이터를 표출했다.

    kubernetes <-로그수집- fluentd -데이터 적재-> elasticsearch <-표출- kibana

    구축 순서

    1. elasticsearch
    2. kibana
    3. fluentd

    elasticsearch 구성

    kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.

    # elastic.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: elasticsearch
      labels:
        app: elasticsearch
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: elasticsearch
      template:
        metadata:
          labels:
            app: elasticsearch
        spec:
          containers:
          - name: elasticsearch
            image: elastic/elasticsearch:6.8.6
            env:
            - name: discovery.type
              value: "single-node"
            ports:
            - containerPort: 9200
            - containerPort: 9300
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: elasticsearch
      name: elasticsearch-svc
      namespace: default
    spec:
      ports:
      - name: elasticsearch-rest
        nodePort: 30482
        port: 9200
        protocol: TCP
        targetPort: 9200
      - name: elasticsearch-nodecom
        nodePort: 30930
        port: 9300
        protocol: TCP
        targetPort: 9300
      selector:
        app: elasticsearch
      type: NodePort

    kubectl 명령어를 이용해서 오브젝트를 kubernetes에 생성한다.

    $ kbuectl apply -f elastic.yml
    deployment.apps/elasticsearch created
    service/elasticsearch-svc created

    설정된 노드포트를 통해서 서비스를 확인할 수 있다.

    http://${kubernetes_host}:30842/

    kibana 구성

    kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.

    # kibana.yml
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: kibana
      labels:
        app: kibana
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kibana
      template:
        metadata:
          labels:
            app: kibana
        spec:
          containers:
          - name: kibana
            image: elastic/kibana:6.8.6
            env:
            - name: SERVER_NAME
              value: "kibana.kubenetes.example.com"
            - name: ELASTICSEARCH_URL
              value: "http://elasticsearch-svc.default.svc.cluster.local:9200"
            ports:
            - containerPort: 5601
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: kibana
      name: kibana-svc
      namespace: default
    spec:
      ports:
      - nodePort: 30920
        port: 5601
        protocol: TCP
        targetPort: 5601
      selector:
        app: kibana
      type: NodePort

    연결하는 elasticsearch 주소는 http://elasticsearch-svc.default.svc.cluster.local:9200이다.
    kubectl 명령어를 이용해서 오브젝트를 kubernetes에 생성한다.

    $ kbuectl apply -f kibana.yml
    deployment.apps/kibana created
    service/kibana-svc created

    설정된 노드포트를 통해서 서비스를 확인할 수 있다.

    fluentd 구성

    kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.

    # fluentd.yml
    
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        k8s-app: fluentd
      name: fluentd
      namespace: kube-system
    
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: fluentd
    rules:
      - apiGroups:
          - ""
        resources:
          - "namespaces"
          - "pods"
        verbs:
          - "list"
          - "get"
          - "watch"
    
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: fluentd
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: fluentd
    subjects:
    - kind: ServiceAccount
      name: fluentd
      namespace: kube-system
    
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentd
      namespace: kube-system
      labels:
        k8s-app: fluentd-logging
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      selector:
        matchLabels:
          k8s-app: fluentd-logging
      template:
        metadata:
          labels:
            k8s-app: fluentd-logging
            version: v1
            kubernetes.io/cluster-service: "true"
        spec:
          serviceAccount: fluentd
          serviceAccountName: fluentd
          tolerations:
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
          containers:
          - name: fluentd
            image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
            env:
              - name:  FLUENT_ELASTICSEARCH_HOST
                value: "elasticsearch-svc.default.svc.cluster.local"
              - name:  FLUENT_ELASTICSEARCH_PORT
                value: "9200"
              - name: FLUENT_ELASTICSEARCH_SCHEME
                value: "http"
              - name: FLUENTD_SYSTEMD_CONF
                value: "disable"
              - name: FLUENT_UID
                value: "0"
            resources:
              limits:
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 200Mi
            volumeMounts:
            - name: varlog
              mountPath: /var/log
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
          terminationGracePeriodSeconds: 30
          volumes:
          - name: varlog
            hostPath:
              path: /var/log
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers

    위의 설정에서 보면 /var/log를 모두 로그를 가져오며 가져온 데이터는 http://elasticsearch-svc.default.svc.cluster.local:9200에 적재 한다.

    kubectl 명령어를 이용해서 오브젝트를 kubernetes에 생성한다.

    $ kbuectl apply -f fluentd.yml
    serviceaccount/fluentd created
    clusterrole.rbac.authorization.k8s.io/fluentd created
    clusterrolebinding.rbac.authorization.k8s.io/fluentd created
    daemonset.apps/fluentd created

    설치시 오류 발생에 따른 해결책

    unable to recognize “filebeat-kubernetes.yaml”: no matches for kind “DaemonSet” in version “extensions/v1beta1” 과 같은 오류가 발생한 이유는 apiVersion이 extensions/v1beta1을 사용하지 말고 apps/v1을 사용하도록 되어 있다.

    다음과 같은 오류가 발생할 경우,

    2018-11-26 23:19:44 +0000 [warn]: suppressed same stacktrace
    2018-11-26 23:19:50 +0000 [info]: stats - namespace_cache_size: 3, pod_cache_size: 6, namespace_cache_api_updates: 15, pod_cache_api_updates: 15, id_cache_miss: 15
    2018-11-26 23:20:14 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2018-11-26 23:20:44 +0000 error_class="MultiJson::AdapterError" error="Did not recognize your adapter specification (cannot load such file -- bigdecimal)." plugin_id="out_es"

    debian 계열의 이미지를 사용하면 된다.

    containers:
    - name: fluentd
    image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1

    Did not recognize your adapter specification #230

    설치가 완료되고 나면, 각 worker node에서 기동하는 것을 확인 할 수 있다.

    kibana 설정

    Management => kibana => Index Patterns => Create Index Pattern => "logstash-*" 추가

    위와 같이 처리 하면 다음과 같은 결과를 확인 할 수 있다.

    마치며

    한땀 한땀 설치 kubernetes의 오부젝트에 대하여 더 많이 이해하게 되었다.

    데이터 적재의 형태나, node의 error 로그 적재 등은 좀더 확인해봐야겠다.

    참고자료

    728x90
Designed by Tistory.