Docker + Kubernetes를 통한 EFK 모니터링 구축

사연있는사람·2023년 11월 6일
0

Monitoring

목록 보기
1/1

0. EFK

Elasticsearch + Fluentd + Kibana

  • Fluentd: 로그 수집

  • Elasticsearch: 수집된 로그를 검색 및 분석하여 저장

  • Kibana: ES를 통해 데이터 시각화


구성환경

  • VMware Ubuntu20.04 이미지 활용

  • Manager Node에서 ElasticSearch, Kibana를 Docker Container로 실행

  • Fluentd를 Daemonset으로 K8S 클러스터에 배포하여 log를 수집


사전조건

  • 도커와 쿠버네티스가 설치되어 있어야한다.
  • 편의를 위해 방화벽을 끄고 진행한다.
  • Dockerhub를 이용하여 이미지를 만들고 저장할 것이므로 docker login을 미리 해준다.
  • ElasticSearch 컨테이너 Exited를 방지하기위해 vm.max_map_count를 262144로 변경 해주어야 한다.

진행과정

  1. ElasticSearch, Kibana Docker로 Manager Node에 Container로 실행
  2. Nginx Pod를 Deployment로 배포
  3. Fluentd를 Daemonsets로 배포
  4. Kibana로 정상적으로 동작하는지 확인
  5. 보완사항

1. ElasticSearch, Kibana Docker로 띄우기

1-1. ElasticSearch

구성간에 편의를 위해 http 통신이 되게끔 진행하였습니다.

Docker 작업전 아래 와 같이 입력하여 vm.max_map_count를 변경합니다.
[ Ref ] - vm.max_map_count

sudo sysctl -w vm.max_map_count=262144

ES Dockerfile 작성

# 베이스 이미지로부터 시작합니다.
FROM docker.elastic.co/elasticsearch/elasticsearch:7.10.1

# Root 권한으로 전환하여 패키지를 설치합니다.
USER root

# Elasticsearch 컨테이너에서 Vim을 설치하는 명령어를 실행합니다.
RUN bin/elasticsearch-plugin install analysis-phonetic

# Docker 이미지 내에서 실행될 명령어를 지정합니다.
CMD ["/usr/share/elasticsearch/bin/elasticsearch"]

ElasticSearch Docker build & Run

docker build -t my_elasticsearch .
docker run -d -p 9200:9200 -e "discovery.type=single-node" -e "http.host=0.0.0.0" my_elasticsearch

우선 설정 파일을 확인하기위해 컨테이너 내부로 진입하자

여기서 확인해야 할 파일은 ~/config/elasticsearch.yml 입니다.

sudo docker exec -it 엘라스틱서치 컨테이너명 /bin/bash
elasticsearch@c00a7b999cf1:~$ cat config/elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0

#----------------------- BEGIN SECURITY AUTO CONFIGURATION -----------------------
#The following settings, TLS certificates, and keys have been automatically
#generated to configure Elasticsearch security features on 30-10-2023 17:49:37
#--------------------------------------------------------------------------------

###Enable security features
xpack.security.enabled: true

xpack.security.enrollment.enabled: true

###Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

###Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12
#----------------------- END SECURITY AUTO CONFIGURATION -------------------------

여기서 변경해야 할 값은 xpack.security.enabled 값으로 true에서 false로 변경해주면 됩니다.

[ Ref ]. ElasticSearch Security-Settings

ES 보안 기능을 활성화하는 값으로 false로 비활성화하자.

이는 보안에 대해 사용하지 않는 설정이므로 주의하여 사용할 필요가 있습니다.


1-2. Kibana

Kibana Docker run

  • Masternode(BastionHost)의 IP를 아래에 넣어서 실행시켜줘야합니다.
docker run -d -p 5601:5601 -e "ELASTICSEARCH_HOSTS=http://BastionHost IP:9200" docker.elastic.co/kibana/kibana:7.10.1

1-3. Container 상태 확인

elasticsearch

kibana


2. Nginx 배포하기

먼저 Access.log를 Fluentd가 읽을수 있는 Json 형식으로 바꾼 nginx 이미지를 만들어 주어야합니다.

Dockerfile

# Use an official Nginx image as the base image
FROM nginx:latest

# Copy the custom Nginx configuration that enables JSON format logs
COPY nginx.conf /etc/nginx/nginx.conf

nginx.conf

이 부분에서 access_log를 사용자 설정으로 바꿧는데 그 이유에 대해서는 맨 아래에서 설명하겠습니다.



events {
    worker_connections 1024;
}

http {
    log_format json_logs escape=json
        '{"time_local": "$time_iso8601", '
        '"remote_addr": "$remote_addr", '
        '"request_method": "$request_method", '
        '"request_uri": "$request_uri", '
        '"status": $status, '
        '"body_bytes_sent": $body_bytes_sent, '
        '"http_referer": "$http_referer", '
        '"http_user_agent": "$http_user_agent"}';

    access_log /var/log/nginx/mulrung.log json_logs;

    server {
        listen 80;
        server_name localhost;

        location / {
            root /usr/share/nginx/html;
            index index.html;
        }
    }

Build 및 Push

#본인의 Dockerhub repo와 이미진 네임 태그를 지정해서 빌드를한뒤 push를하자
docker build -t  dockerhubID/name:Tag .
docker push dockerhubID/name:Tag 

nginx.yaml

  • Mount를 시킨이유는 fluentd와 nginx간 Host의 디렉토리에서 log를 읽고 쓰게 하기 위함이다.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3  # 원하는 파드 수로 설정
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: dockerhubID/name:Tag
        ports:
        - containerPort: 80
        volumeMounts:
        - name: varlog
          mountPath: /var/log/nginx
      volumes:
      - name: varlog
        hostPath:
          type: DirectoryOrCreate
          path: /var/log/

배포해보자

kubectl apply -f nginx.yaml

실제로 nginx가 띄워진 Node에 mount가 되었는지 확인해보자

root@worker1:~/Dockerfile# ls /var/log/ | grep mulrung
mulrung.log

3. fluentd Daemonset으로 배포하기

fluentd daemonset 으로 설치하기 위해 메니페스트 파일을 다운받는다.

curl -LJ -o fluentd.yaml https://github.com/fluent/fluentd-kubernetes-daemonset/blob/master/fluentd-daemonset-elasticsearch-rbac.yaml?raw=true

다운받은 fluentd.yaml에서 FLUENT_ELASTICSEARCH_HOST의 value 값을 ElasticSearch를 띄운 호스트의 ip로 변경하면 됩니다.

  containers:
  - name: fluentd
    image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
    env:
      - name:  FLUENT_ELASTICSEARCH_HOST
        value: "[elasticsearch 호스트 ip]"
      - name:  FLUENT_ELASTICSEARCH_PORT
        value: "9200"
      - name: FLUENT_ELASTICSEARCH_SCHEME
        value: "http"

그리고, 이 포스팅에서는 nginx의 Log를 확인할것이므로 수정한 fleunt.conf가 들어간 이미지를 새로 만든다.

  • path /var/log/mulrung.log -> nginx를 배포할때 보면 알수 있듯이 nginx의 access 로그를 사용자 설정으로 만든것이다.
  • host의 IP부분은 수정해야한다.

fluent.conf

<source>
  @type tail
  @id nginx_access
  path /var/log/mulrung.log
  pos_file /var/log/td-agent/nginx-access.log.pos
  tag nginx.access
  format json
  read_from_head true
</source>

<match nginx.access>
  @type elasticsearch
  host [elasticsearch 호스트 ip]
  port 9200
  index_name nginx_access
  type_name nginx_access
  flush_interval 5s
</match>

Dockerfile

# 다운 받은 메니패스트의 기본 이미지명
FROM fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch

# 수정한 conf 파일 Copy
COPY fluent.conf /fluentd/etc/fluent.conf
#본인의 Dockerhub repo와 이미진 네임 태그를 지정해서 빌드를한뒤 push를하자
docker build -t  dockerhubID/name:Tag .
docker push dockerhubID/name:Tag 

그 이후 fleuntd.yaml의 이미지를 Hub에 푸쉬한 이미지로 변경한다.

containers:
     - name: fluentd
       image: dockerhubID/name:Tag

배포해보자

kubectl apply -f fluentd.yaml

4. 확인

  • pod및 Contaienr가 정상적으로 Running중 임을 확인할 수 있다.

  • kibana의 Stack Management > Index Management
    nginx*로 해서 데이터가 쌓이는 것을 확인할 수 있다.
    Create Index pattern을 통해 인덱스 패턴을 만들어주자.

  • Kibana의 Index Pattern에서 nginx*로 설정한 후 discover에서 확인해보자.

  • curl을 통해 nginx에 접속을하게되면 log가 쌓이는것을 볼 수 있다.

5. 사연

사실 이 포스팅은 원래 EKS 환경에서 진행하려고했었다.
하지만 EKS에서는 위와같은 방법으로는 되지않았고 그 원인을 찾다가 지쳐서 로컬환경에서 진행한 내용으로 포스팅하게 되었습니다..

해결해야할 문제들

  1. 쿠버네티스(?) 혹은 EKS 환경에서 nginx의 기본 access 로그인 access.log가 접근이 안된다. 그래서 파일을 새로만들었습니다.
    -> stdout 설정으로 인하여 contaienrs의 로그에 심볼릭링크가 걸려있는듯하다.(?)
  2. EKS에서는 동일하게 진행하여도 왜 안되는지 모르겠다.
    -> gid, uid 기타 설정 생각나는건 다해봤는데 안된다..

0개의 댓글