티스토리 뷰

Kubernetes 환경에서 Logging 및 Monitoring을 위한 환경 구성에 대하여 알아보도록 하자.

먼저 사용되는 구성요소들은 다음과 같다.

  • logging
    • Fluent-bit (각 노드) -> elasticsearch -> grafana / kibana
  • monitoring
    • node_exporter (각 노드) -> prometheus -> grafana

각 구성요소는 다음과 같은 구성으로 이루어진다.

component helm chart namspace persistence volume etc
ElasticSearch elastic/elasticsearch(helm.elastic.co) LMA 사용  
Fluentbit stable/fluent-bit LMA 미사용 elasticsearch로 log 전달
prometheus-operator stable/prometheus-operator LMA 사용
(influxDB와 같은 TSDB 를 backend로 사용)
grafana disable
grafana stable/grafana LMA 미사용
(혹은 mysql과 같은 RDB backend 사용)
datasources 추가
- prometheus
- elasticsearch
  • 꼭 위와 같이 구성할 필요는 없다.
    다만 위와 같은 구성을 왜 하게 되었는지를 이해하고 고민하여 구성하면 좋을것이라 생각된다.

ElasticSearch

다음과 같은 방식으로 설치를 진행한다.

helm repo add elastic https://helm.elastic.co
helm fetch --untar elastic/elasticsearch
cd elasticsearch
helm install elasticsearch -f values.yaml --version 7.8.1 . -n lma

Fluent-bit

Daemonset으로 Fluent-bit이 각 worker마다 동작된다.

각 worker에는 /var/log 디렉토리 밑에 containers라는 디렉토리 내에 각 container의 log를 저장하게 된다.

[root@worker001 containers]# ls -al | grep phpldapadmin
lrwxrwxrwx.  1 root root  107  8월  6 04:26 phpldapadmin-b689945cf-t5np5_openldap_phpldapadmin-ba2ef4b7b92929b34b6b51963cb24082f23a30b6b2a1cf59c7fd20db816db6c2.log -> /var/log/pods/openldap_phpldapadmin-b689945cf-t5np5_47b9067b-b0bb-43d4-8110-349186f8455e/phpldapadmin/0.log
lrwxrwxrwx.  1 root root  121  8월  6 04:26 phpldapadmin-b689945cf-t5np5_openldap_phpldapadmin-init-template-64c584632411657e267183bafe811fc5fe6f4c610bbcaea729d03244916ee096.log -> /var/log/pods/openldap_phpldapadmin-b689945cf-t5np5_47b9067b-b0bb-43d4-8110-349186f8455e/phpldapadmin-init-template/0.log
[root@infra-worker001 containers]# docker ps | grep phpldapadmin
ba2ef4b7b929        3b8feb83bfba                     "/container/tool/run"    2 hours ago          Up 2 hours                              k8s_phpldapadmin_phpldapadmin-b689945cf-t5np5_openldap_47b9067b-b0bb-43d4-8110-349186f8455e_0
0b594fa70cbe        k8s.gcr.io/pause:3.1             "/pause"                 2 hours ago          Up 2 hours                              k8s_POD_phpldapadmin-b689945cf-t5np5_openldap_47b9067b-b0bb-43d4-8110-349186f8455e_0

실제 kubernetes환경에서 동작되는 container들은 위와 같이 log를 남기는것을 확인해볼수 있다.

fluent-bit을 배포하면 worker의 갯수와 동일한 (daemonset으로 동작되기 때문에) 갯수로 pod가 동작되는것을 확인할 수 있다.

Fluent-bit 배포후 elasticsearch에서 해당 index를 검색해보면 아래와 같이 출력된다.

실제 indexname으로 직접 확인해보면 다음과 같이 mappings properties가 출력된다.

prometheus-operator

단순 prometheus 보다 관리와 유지보수가 좀더 효율적인 operator를 선택하여 배포하자.

(참고로 prometheus-operator는 node-exporter 및 kube-state-metrics 가 함께 설치되어 손쉽게 모니터링이 가능하다.)

helm fetch --untar stable/prometheus-operator
cd prometheus-operator

vaules.yaml내에 다음과 같은 scrap을 수행할 target을 추가한다.
(기본적으로 node-exporter 및 kube-state-metrics에 대한 정보는 gathering 되도록 되어 있다.
하여 추가적인 metric 정보의 수집이 필요한 경우 아래 설정을 추가한다.)

# 배포된 kubernetes 환경이 아닌 별도의 kvm이 동작되는 서버에서 metric 정보를 가져오도록 설정
     additionalScrapeConfigs:
     - job_name: libvirt-exporter
       scrape_interval: 60s
       static_configs:
       - targets: ['192.168.1.2:9177']

# 배포된 kubernetes 환경에서 동작중인 exporter를 통해 metric 정보를 가져오도록 설정
     - job_name: mysql-exporter
       scrape_interval: 60s
       static_configs:
       - targets: ['mysql-exporter.namespace.svc.cluster.local:9104']

이후 아래와 같이 helm으로 prometheus-operator를 배포한다.

helm install prometheus -f values.yaml . -n lma

Grafana

배포

Prometheus-Operator로 배포해도 되지만 별도의 helm chart로 배포하였다.
큰 이유가 있는것은 아니고 관리의 편리함을 위해 별도의 grafana helm chart를 사용했다.

helm fetch --untar stable/grafana
cd grafana
datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
    - name: Elasticsearch
      type: elasticsearch
      access: proxy
      url: http://elasticsearch-master:9200
      database: "kubernetes_cluster*"
      jsonData:
        timeField: "@timestamp"
        esVersion: 70
      isDefault: true
      editable: true
    - name: Prometheus
      type: prometheus
      url: http://prometheus-prometheus-oper-prometheus:9090
      access: proxy
      isDefault: false
      editable: true
helm install grafana -f values.yaml . -n lma

Dashboard 구성

아래와 같이 index name을 설정한다.

index name의 경우 fleunt-bit에서 다음과 같은 kubernetes_cluster-YYYY.MM.DD 형태로 남겨지도록 되어 있기에 해당 형태를

그대로 가져와 입력한다.

kubernetes_cluster-[YYYY.MM.DD]

이제 실제 모니터링에서 사용될 Dashboard를 추가해보자.

우선 dashboard로 만들어낼 데이터의 대상을 지정하자.

참고

Elastic Cloud on Kubernetes

아래와 같이 ECK(Elastic Cloud on Kubernetes)가 Elastic에서 제공되고 있고
이를 통해 CRD(Custom Resource Definition)을 생성한다.

kubectl apply -f https://download.elastic.co/downloads/eck/1.2.0/all-in-one.yaml

해당 CRD는 ElasticSearch를 Kubernetes 상에 설치하고 잘 관리될 수 있도록 해준다.

아래와 같은 manifest를 생성하여 kubectl create 로 생성하게 되면 앞서 생성했던 Elasticsearch CRD를 이용하여 ElasticSearch가 구동되게 된다.

[root@infra-deploy elastic-cloud-k8s]# cat elasticsearch.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: logging
---
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
  namespace: logging
spec:
  version: 7.8.1
  nodeSets:
  - name: default
    count: 1
    config:
      node.master: true
      node.data: true
      node.ingest: true
      node.store.allow_mmap: false
      xpack.security.enabled: false
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: elasticsearch
  namespace: logging
  labels:
    app: elasticsearch
spec:
  rules:
    - host: elastic.example.com
      http:
        paths:
          - path: 
            backend:
              serviceName: quickstart-es-http
              servicePort: 9200

배포가 완료되면 아래와 같은 resource들이 배포되게 된다.

[root@infra-deploy elastic-cloud-k8s]# kubectl get all -n logging
NAME                          READY   STATUS    RESTARTS   AGE
pod/quickstart-es-default-0   1/1     Running   0          39s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/quickstart-es-default     ClusterIP   None            <none>        9200/TCP   40s
service/quickstart-es-http        ClusterIP   10.222.38.180   <none>        9200/TCP   41s
service/quickstart-es-transport   ClusterIP   None            <none>        9300/TCP   41s

NAME                                     READY   AGE
statefulset.apps/quickstart-es-default   1/1     39s

Elasticsearch 기본 포트인 9200 port로 접속이 가능하게 된다.

NOTE
ECK를 사용하는 것은 enterprise license를 사용하는것과 같다.
즉, OSS license가 아닌 enterprise license를 사용하는 이미지 기반으로 동작되게 된다.
이때 확인해야할 것은 tls가 default로 사용되고 disable이 불가하다.

댓글
  • 프로필사진 Favicon of https://wooogy-egg.tistory.com BlogIcon 한승욱 안녕하세요 ㅎㅎ 구글에서 돌고 돌다가 선생님의 블로그까지
    오게되었습니다. 기본적으로 prometheus는 pull방식? 이고 elk는 push방식이라고 하는데 이 두개가 동시에 같이(한번에 엮여서) 사용될 일은 없는거라고 생각하면 될까요?!?

    위의 예시로 들어주신 쿠버네티스 관점에서 logging, monitoring 각각에는 별개로 적용되는 것이고 두 스택에서 선택을 해야하는 부분이라고 생각하면 될까요?
    (질문이 조금 이상하긴 합니다만 실제 prometheus grafana 조합과 elk가 대립되는 스택인가에 대해 검색하다가 이곳까지 오게되었습니다)
    2021.02.16 04:56 신고
  • 프로필사진 Favicon of https://www.jacobbaek.com BlogIcon jacobbaek Jacob_baek 안녕하세요.
    먼저 질문주신 내용을 제가 이해하기론 두가지 stack (ELK, Prometheus/Grafana)의 용도가 겹치지 않나 하는 의문이라 판단되는데요. 만약 제가 이해한게 맞다면 logging 과 monitoring은 다른 목적으로 사용되게 되기에 logging에 좀더 부합되는 elk의 경우는 장애와 같은 상황에 대한 분석쪽에 좀더 치중되어 있다 보시면 좋을듯하고 Prometheus/Grafana의 경우는 monitoring 즉, 성능이나 장애예방을 위한 용도쪽에 더 치중되어 있다 보시면 좋을거라 생각되네요
    또한 pull/push 방식은 각 stack들의 데이터 수집 방식이기에 port를 같이 사용하지 않는 경우라면 문제될 소지는 없을듯하고 다량의 데이터(log, metric 들)가 존재하는 경우라면 각 stack에 대한 성능 향상을 위한 고려를 위한 데이터 수집방식에 대한 변경이 필요할수도 있을거라 생각됩니다.
    질문을 제가 제대로 이해하고 답변드렸는지 모르겠네요. 조금이나마 도움되셨으면 합니다.
    2021.02.17 11:07 신고
  • 프로필사진 Favicon of https://wooogy-egg.tistory.com BlogIcon 한승욱 감사합니다 부족한 질문이었지만 정말 좋은 답변 감사드립니다!! 좋은 하루 되세요 ㅎㅎ 2021.02.17 21:27 신고
댓글쓰기 폼