Kubernetes에 ELK(Elasticsearch) 구축하기 #1

2022. 6. 16. 16:02프로그래밍 개발(Development)/k8s

반응형

엘라스틱서치(Elasticsearch)는 분산형 RESTful 검색 및 분석 엔진으로 엘라스틱 스택(Elastic Stack)의 중심에 위치하고 있으며, 엘라스틱 스택은 차세대 데이터 플랫폼으로 자리 잡고 있습니다.

 

Elastic Stack의 주요 기술은 아래와 같습니다.

  • Elasticsearch : 검색·분석·데이터 저장소 역할
  • Beats : 데이터 수집 역할(Filebeat, Metricbeat, Packetbeat, Winlogbeat, Auditbeat, Heartbeat, Functionbeat)
  • Logstash : 정제·전처리를 수행
  • Kibana : 시각화·관리 기능

Linux 또는 Wondows에 직접 설치가 가능하나, 컨테이너로 배포시 scale-out의 장점과 OS의 따른 영향을 받지 않기 때문에 쿠버네티스에 ELK를 구축하는 방법을 알아보겠습니다.

 

먼저 Namespace를 생성 후 진행 하겠습니다. namespace 이름은 elk로 생성

apiVersion: v1
kind: Namespace
metadata:
  name: elk

 

Elasticsearch

Elasticsearch의 경우 Deployment로 구성하게 되면 Pod가 종료 될시 컨테이너 내의 데이터가 모두 삭제가 되기 때문에, 데이터를 유지 할 수 있는 StatefulSet으로 구성하여야 합니다.

 

1. elasticsearch-configmap.yaml

elasticsearch.yml 파일을 configmap으로 관리하기 위하여 생성한다.

상황에 따라 Master node, data node, ingest node 로 구성하여 관리할 수 있다.

필자는 우선 최소한의 구성으로 설정하여 구축하도록 하겠다.

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: elk
  name: elasticsearch-config
  labels:
    app: elasticsearch
    #role: data
data:
  elasticsearch.yml: |-
    cluster.name: ${CLUSTER_NAME}	# 클러스터 이름
    #node.name: ${NODE_NAME}		# 노드 이름
    #discovery.seed_hosts: ${NODE_LIST}			# 노드 리스트
    #cluster.initial_master_nodes: ${MASTER_NODES}	# 마스터 노드
    network.host: 0.0.0.0			# 외부 접근
    #node:					# 노드 정보 옵션
    #  master: false
    #  data: true
    #  ingest: false
    #xpack.security.enabled: true		# X pack의 경우 보안설정
    #xpack.monitoring.collection.enabled: true

 

2. elasticsearch-persistentvolume.yaml

Persistent Volume(PV)란 관리자에 의해 생성된 볼륨으로 사용자가 Persistent Volume Claim(PVC)을 통해 PV에 볼륨을 요청을 하고 그에 맞는 볼륨이 있을 경우 바인딩하여 할당한다.

 

컨테이너내의 elasticsearch data를 worker node의 Host Path(서버 경로)로 백업이 되어 Pod가 종료되어도 데이터는 유지가 된다.

 

replicas 수에 따라 Pod가 0,1,2,3 등 순차적으로 생성이 되기 때문에 PV 또한 수량을 맞춰 주어야 한다.

StatefulSet과 PVC - PV 구성

apiVersion: v1
kind: PersistentVolume
metadata:
  namespace: elk
  name: elasticsearch-pv
  labels:
    name: elasticsearch
spec:
  storageClassName: standard
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  claimRef:
    namespace: elk
    name: elasticsearch-persistent-storage-elasticsearch-node-0
  persistentVolumeReclaimPolicy: Delete
  hostPath:
    path: /data/es
    type: DirectoryOrCreate
  • spec.storageClassName : 스토리즈 클래스를 지정하여 해당 클래스에 맞는 PVC와 연결
  • spec.capacity.storage : 사용할 용량을 1GB로 설정
  • spec.volumeMode : Filesystem으로 사용
  • spec.accessModes
    - ReadWriteOnce : 하나의 노드에서만 읽고 쓸 수 있다
    - ReadWriteMany : 여러개의 노드에서만 읽고 쓸 수 있다.
    - ReadOnlyMany : 여러개의 노드에서만 읽기만 가능하다
  • spec.persistentVolumeReclaimPolicy : 반환 정책으로 동적으로 프로비저닝시 기본 반환 정책은 Delete이다
    - Delete(삭제) : PVC을 삭제하면, 볼륨이 자동으로 삭제가 된다.
    - Retain(보존) : 데이터 보존을 위해서는 Retain 정책이 적절하다.
    - Recycle(재활용) : PV의 데이터를 삭제하고 다시 새로운 PVC에서 PV를 사용할 수 있도록 한다
  • spec.claimRef : 특정 PVC를 연결할때, 지정을 하지 않으면 동적 바인딩 됨.
  • spec.claimRef.name : {PVC name}-{StatefulSet name}-{pod index} 으로 구성
  • spec.hostPath.type
    - Directory :  이미 생성된 디렉토리에 매핑하고 없을경우 에러 발생
    - DirectoryOrCreate : 디렉토리가 없으면 생성하여 매핑

ex) 아래와 같은 조건일 경우

PV를 2개 생성하여 첫번째 PV : elastic-volume-elasticsearch-0, 두번째 PV : elastic-volume-elasticsearch-1로 입력

pvc name : elastic-volume

statefulset name : elasticsearch

replicas : 2

 

3. elasticsearch-statefulset.yaml

statefulset으로 elasticsearch pod 생성

apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: elk
  name: elasticsearch-node
  labels:
    app: elasticsearch
    #role: data
spec:
  serviceName: "elasticsearch"
  selector:
    matchLabels:
      app: elasticsearch
  replicas: 1
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        #image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3
        image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.23
        imagePullPolicy: IfNotPresent
        env:
        - name: CLUSTER_NAME
          value: elk-cluster
        #- name: discovery.seed_hosts
        #  value: "elasticsearch"
        - name: discovery.type
          value: single-node
        - name: "ES_JAVA_OPTS"
          value: "-Xms300m -Xmx300m"
        ports:
        - name: rest
          containerPort: 9200
        - name: transport
          containerPort: 9300
        volumeMounts:
        - name: config
          mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
          readOnly: true
          subPath: elasticsearch.yml
        - name: elasticsearch-persistent-storage
          mountPath: /usr/share/elasticsearch/data
        - name: tz-seoul
          mountPath: /etc/localtime
      initContainers:
      - name: fix-permissions
        image: busybox
        command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
        securityContext:
          privileged: true
        volumeMounts:
        - name: elasticsearch-persistent-storage
          mountPath: /usr/share/elasticsearch/data
      volumes:
      - name: config
        configMap:
          name: elasticsearch-config
      - name: tz-seoul
        hostPath:
          path: /usr/share/zoneinfo/Asia/Seoul
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "gp2"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: standard
      resources:
        requests:
          storage: 1Gi

4. elasticsearch-service.yaml

내부 연결용과 외부 연결용으로 2개의 서비스 생성 (상황에 따라 서비스 생성을 하면 된다.)

apiVersion: v1
kind: Service
metadata:
  namespace: elk
  name: elasticsearch
  labels:
    app: elasticsearch
spec:
  clusterIP: None
  ports:
  - name: rest
    port: 9200
  - name: transport
    port: 9300
  selector:
    app: elasticsearch
---
kind: Service
apiVersion: v1
metadata:
  namespace: elk
  name: elasticsearch-nodeport
  labels:
    app: elasticsearch
spec:
  type: NodePort
  ports:
    - nodePort: 30920
      port: 9200
      targetPort: 9200
      protocol: TCP
  selector:
    app: elasticsearch

5. 쿠버네티스 명령어로 생성

$ kubectl apply -f elasticsearch-configmap.yaml
$ kubectl apply -f elasticsearch-persistentvolume.yaml
$ kubectl apply -f elasticsearch-statefulset.yaml
$ kubectl apply -f elasticsearch-service.yaml

curl 명령어로 설치 확인

 

소스코드는 Github에서 다운로드 할 수 있다.

Github : https://github.com/Byeongin-Jeong/kubernetes

 

GitHub - Byeongin-Jeong/kubernetes

Contribute to Byeongin-Jeong/kubernetes development by creating an account on GitHub.

github.com

 

반응형