-
Kubernetes, EFK (ElasticSearch, Fluent-bit, Kibana) 구성k8s 2024. 2. 26. 10:17
도입 이유
쿠버네티스는 시스템을 유지하기 위해 자체적으로 오류를 감지하고 복구하는 메커니즘을 가지고 있습니다. (self-healing기능) 예를 들어 컨테이너가 비정상적으로 종료되거나 반응이 없을 때, 해당 Pod를 자동으로 재시작 합니다. Pod가 재시작되면 해당 Pod가 사용하던 컨테이너 인스턴스는 제거되고, 새로운 컨테이너와 인스턴스가 생성되는 과정에 기존 컨테이너 로컬 저장소에 있던 로그 파일들은 삭제가 됩니다. Pod안에 임시 볼륨이 삭제되고 새로운 파일 시스템이 생성되기 때문입니다. 하지만 운영을 하는 입장에서 왜 Pod가 재시작이 되었는지 알아야 되기 때문에 컨테이너가 살아있을때 외부 로그 저장소에 로그를 수집,저장,분석하여 서비스의 안정성 및 로그 관리를 위해 EFK를 도입 했습니다.
개념
클러스터 내의 모든 노드에서 로그를 수집하기 위해 Fluent Bit을 DaemonSet으로 배포하여 로그를 수집하여 중앙의 Elasticsearch로 전달 합니다. Elasticsearch는 전달받은 로그에 대해 저장 및 검색 기능을 제공하며 Kibana는 이 로그들을 쿼리하고 시각화 할수 있게 해줍니다. 이 세가지 컴포넌트가 함께 작동하여 로그 관리 및 분석 파이프라인을 구성합니다.
설치 과정
Elasticsearch 최신버전은 helm을 통해 설치해주자
helm repo add elastic https://helm.elastic.co helm install elasticsearch elastic/elasticsearch
설치가 완료되었으면 설치된 모든 오브젝트를 확인하자 서비스에 elasticsearch-master 가 있어야 한다. 그리고 모든 pods 가 running 으로 전환되는 것을 확인하자.
kubectl get all
port-forward 를 하고, index 리스트를 조회해서 정상적으로 동작하는지 확인하자.
포트포워딩을 하고 인덱스를 조회할 때 8. 이후 버전부터 보안이 강화되어 helm차트에서 다운받을때 자동으로 생성되는 패스워드와 기본 아이디값을 입력해줘야된다.
# 자동으로 생성된 패스워드 조회 kubectl get secret elasticsearch-master-credentials -o go-template='{{.data.password | base64decode}}' # 고정 아이디 값은 elastic 이지만 조회하는 명령어이다. kubectl get secret elasticsearch-master-credentials -o go-template='{{.data.username | base64decode}}'
-k 옵션을 줘서 cURL 인증서 검증을 무시하고 -u 명령어를 통해 아이디와 패스워드를 입력하여 조회하자# -k 옵션을 줘서 cURL에 인증서 검증을 무시 curl -k -u elastic:vpyBZSyphcx1fjiG https://localhost:30000/_cat/indices\?v
성공적으로 조회가 되었다.
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
다음으로 Kibana를 설치하자
helm install kibana elastic/kibana
마찬가지로 포트포워딩을 하여 Kibana에 접속해보자
다음은 Fluent-bit을 설치해보자
Fluent-bit은 helm차트가 아닌 yaml파일로 구성하였다.
fluentbit-serviceaccount.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: fluent-bit namespace: monitoring
fluentbit-role.yaml
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluent-bit-read rules: - apiGroups: [""] resources: - namespaces - pods verbs: ["get", "list", "watch"]
fluentbit-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fluent-bit-read roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: fluent-bit-read subjects: - kind: ServiceAccount name: fluent-bit namespace: monitoring
fluentbit-configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config namespace: monitoring labels: k8s-app: fluent-bit data: fluent-bit.conf: | [SERVICE] Flush 1 Log_Level info Daemon off Parsers_File parsers.conf @INCLUDE filter-kubernetes.conf @INCLUDE input-kubernetes.conf @INCLUDE output-elasticsearch.conf input-kubernetes.conf: | [INPUT] Name tail Tag kube.* Path /var/log/containers/*.log Parser docker DB /var/log/flb_kube.db Mem_Buf_Limit 5MB Skip_Long_Lines On Refresh_Interval 10 filter-kubernetes.conf: | [FILTER] Name kubernetes Match kube.* Kube_URL https://kubernetes.default.svc Merge_Log On Keep_Log Off K8S-Logging.Parser On K8S-Logging.Exclude Off output-elasticsearch.conf: | [OUTPUT] Name es Match * Host ${FLUENT_ELASTICSEARCH_HOST} Port ${FLUENT_ELASTICSEARCH_PORT} Logstash_Format On Logstash_Prefix fluent-bit Retry_Limit False HTTP_User elastic HTTP_Passwd vpyBZSyphcx1fjiG tls on tls.verify off Suppress_Type_Name On parsers.conf: | [PARSER] Name docker Format json Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%L Time_Keep On
fluentbit-daemonset.yaml
apiVersion: apps/v1 kind: DaemonSet metadata: name: fluent-bit namespace: monitoring spec: selector: matchLabels: k8s-app: fluent-bit-logging template: metadata: labels: k8s-app: fluent-bit-logging spec: containers: - name: fluent-bit image: fluent/fluent-bit:latest imagePullPolicy: Always env: - name: FLUENT_ELASTICSEARCH_HOST value: "elasticsearch-master" - name: FLUENT_ELASTICSEARCH_PORT value: "9200" - name: FLUENT_ELASTICSEARCH_HTTPS value: "on" - name: FLUENT_ELASTICSEARCH_USER value: "elastic" - name: FLUENT_ELASTICSEARCH_PASSWORD value: "S77RMGFWQo2geB1O" volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: journal mountPath: /journal readOnly: true - name: fluent-bit-config mountPath: /fluent-bit/etc/ terminationGracePeriodSeconds: 10 volumes: - name: varlog hostPath: path: /var/log - name: journal hostPath: path: /var/log/journal - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: fluent-bit-config configMap: name: fluent-bit-config serviceAccountName: fluent-bit tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule
모든 설정을 apply 해주고 kibana에 접속해 Management → Stack Management → Data views 에서 Create data view에서 fluent-bit- Index pattern 추가해주고 Discover에서 확인하면 끝이 난다!
다음은 Kibana dashboard 설정하는 방법을 정리할 예정이다.
'k8s' 카테고리의 다른 글
Kubernetes, Telepresence사용한 로컬 환경 구성 (1) 2024.03.05 Kubernetes,Prometheus Alertmanager 구성 (0) 2024.02.22 Kubernetes, OpenSearch를 이용한 로그 모니터링 (0) 2024.01.18 Kubernetes, 자원할당과 스케일 조정 그리고 오토스케일링 (0) 2024.01.10 Kubernetes, Probe 와 Application Lifecycle (0) 2024.01.08