클라우드/Kubernetes

[RKE2] KTCloud 서버 ElasticSearch 설치

세브웁스 2024. 12. 31. 20:00
반응형

🚀 KT Cloud 기반 RKE2 클러스터에 ELK 스택 구축하기 (Filebeat 연동 트러블슈팅 포함) 🚀

KT Cloud 환경에 RKE2 (Rancher Kubernetes Engine 2) 클러스터를 구축하고, ELK 스택 (Elasticsearch, Kibana, Filebeat)을 배포하여 로그를 수집 및 시각화하는 과정을 상세하게 기록합니다. 최소 사양 환경에서의 구축 과정과 Filebeat 연동 시 발생했던 트러블슈팅 경험을 공유하여 유사한 환경을 구축하시는 분들에게 도움이 되고자 합니다.

최소 사양:

  • Master Node: 2 Core / 4GB RAM
  • Agent Node: 2 Core / 2GB RAM

 

 

 

⚙️ 1단계: RKE2 클러스터 구축

1. Master Node (KT Cloud 1번 서버)

Bash
 
# Swap 비활성화
sudo swapoff -a
sudo sed -i -e '/swap/d' /etc/fstab

# RKE2 다운로드 및 설치
curl -sfL https://get.rke2.io | sh -

# RKE2 서비스 활성화 및 시작
sudo systemctl enable rke2-server.service
sudo systemctl start rke2-server.service
journalctl -u rke2-server -f

# kubectl 명령어 환경 변수 등록 및 별칭 설정
mkdir ~/.kube/
cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
export PATH=$PATH:/var/lib/rancher/rke2/bin/
echo 'export PATH=/usr/local/bin:/var/lib/rancher/rke2/bin:$PATH' >> ~/.bashrc
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
source ~/.bashrc

 

2. Worker Node (KT Cloud 2번 서버)

# RKE2 다운로드 및 Agent 모드로 설치
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -

# RKE2 Agent 서비스 활성화
sudo systemctl enable rke2-agent.service
mkdir -p /etc/rancher/rke2/

# 마스터 노드 연동 설정 (9345, 6443 포트 방화벽 허용 필요)
# 마스터 노드의 /var/lib/rancher/rke2/server/node-token 내용 확인
cat /var/lib/rancher/rke2/server/node-token

# 에이전트 노드 설정 파일 생성 및 마스터 정보, 토큰 입력
mkdir -p /etc/rancher/rke2/
cat /etc/rancher/rke2/config.yaml
server: https://<마스터_노드_IP>:9345
token: <마스터_노드_토큰>

# RKE2 Agent 서비스 시작 및 로그 확인
sudo systemctl start rke2-agent.service
journalctl -u rke2-agent -f

💾 2단계: Persistent Volume (PV) 생성

Elasticsearch 데이터 저장을 위한 PV를 생성합니다.

/tmp/elastic/pvall.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: es-pv-01
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/es-data-01
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: es-pvc-01
  namespace: elk
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      kubernetes.io/hostname: hyun-test # Master Node 이름
# PV 적용
[root@hyun-test ~]# k apply -f /tmp/elastic/pvall.yaml

☸️ 3단계: Helm 설치

ELK 스택 배포를 위해 Helm을 설치합니다.

# Helm 다운로드
wget https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz

# 압축 해제
tar -zxvf helm-v3.7.0-linux-amd64.tar.gz

# 실행 파일 이동
sudo mv linux-amd64/helm /usr/local/bin/helm

# Helm 버전 확인
helm version

🔍 4단계: Elasticsearch 배포

Elasticsearch를 Helm을 이용하여 배포합니다.

/tmp/elastic/ela_values.yaml

YAML
 
clusterName: elasticsearch
replicas: 1
minimumMasterNodes: 1
esConfig:
  elasticsearch.yml: |
    network.host: 0.0.0.0
    discovery.seed_hosts: ["elasticsearch-master-headless"]
    cluster.initial_master_nodes: ["elasticsearch-master-0"]
resources:
  requests:
    cpu: "256m"
    memory: "1Gi"
  limits:
    cpu: "512m"
    memory: "1Gi"
volumeClaimTemplate:
  accessModes: [ "ReadWriteOnce" ]
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi
 
# Elasticsearch 배포
helm install elasticsearch elastic/elasticsearch -n elk --values /tmp/elastic/ela_values.yaml

# Elasticsearch 서비스 확인
[root@hyun-test elastic]# k get svc -n elk
NAME                            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
elasticsearch-master            NodePort    10.43.70.121   <none>        9200:30000/TCP,9300:30846/TCP   21m

 

Elasticsearch 접속 정보:

  • IP: 마스터 노드 IP
  • Port: 30000
  • ID: elastic
  • Password: Password1!

 

📊 5단계: Kibana 배포

Kibana를 Helm을 이용하여 배포합니다.

/tmp/elastic/kib_values.yaml

YAML
 
elasticsearchHosts: ["http://elasticsearch-master:9200"]
resources:
  requests:
    cpu: "100m"
    memory: "512Mi"
  limits:
    cpu: "256m"
    memory: "1Gi"
Bash
 
# Kibana 배포
[root@hyun-test elastic]# helm install kibana elastic/kibana -n elk --values /tmp/elastic/kib_values.yaml

# Kibana Pod 및 서비스 확인
[root@hyun-test elastic]# kubectl get pods --namespace=elk -l release=kibana -w
[root@hyun-test elastic]# k get svc -n elk
NAME                            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
elasticsearch-master            NodePort    10.43.70.121   <none>        9200:30000/TCP,9300:30846/TCP   63m
elasticsearch-master-headless   ClusterIP   None           <none>        9200/TCP,9300/TCP               63m
kibana-kibana                   NodePort    10.43.176.67   <none>        5601:30010/TCP                  8m24s

 

Kibana 접속 정보:

  • IP: 마스터 노드 IP
  • Port: 30010

📄 6단계: Filebeat 설치 및 연동

로그를 수집할 서버 (여기서는 Nginx가 설치된 서버라고 가정)에 Filebeat를 설치하고 Elasticsearch와 연동합니다.

# Filebeat 다운로드
cd /tmp
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.7-linux-x86_64.tar.gz
tar -xvf filebeat-7.17.7-linux-x86_64.tar.gz

# /etc/hosts 파일에 Elasticsearch 마스터 노드 등록 (IP 확인 필요)
cat /etc/hosts
172.27.0.97     elasticsearch-master

# Filebeat 설정 파일 수정 (/tmp/filebeat-7.17.1-linux-x86_64/filebeat.yml)
filebeat.inputs:
- type: filestream
  paths:
    - /var/log/nginx/*.log
output

 

📤 7단계: Filebeat 설정 및 실행

Filebeat를 설치한 서버에서 Elasticsearch로 로그를 전송하기 위한 설정을 진행합니다.

1. /etc/hosts 파일 수정 (Elasticsearch 마스터 노드 등록)

Filebeat 서버에서 Elasticsearch 마스터 노드를 IP 주소로 접근할 수 있도록 /etc/hosts 파일에 다음과 같이 등록합니다. <Elasticsearch_마스터_노드_IP>는 실제 IP 주소로 변경해야 합니다.

 
$ cat /etc/hosts
172.27.0.97     elasticsearch-master

 

2. filebeat.yml 파일 수정

Filebeat 설정 파일(/tmp/filebeat-7.17.1-linux-x86_64/filebeat.yml)을 열어 다음과 같이 수정합니다. paths 항목에는 Nginx 로그 파일 경로를 지정하고, output.elasticsearch 항목에는 Elasticsearch 호스트 정보, 인증 정보, SSL 인증서 경로를 설정합니다.

filebeat.inputs:
- type: filestream
  paths:
    - /var/log/nginx/*.log

output.elasticsearch:
  hosts: ["elasticsearch-master:30000"]
  protocol: "https"
  username: "elastic"
  password: "Password1!"
  ssl.certificate_authorities: ["/tmp/filebeat-7.17.1-linux-x86_64/ca.crt"]
# 위 코드의 ca 파일은 elasticsearch pod 안에 존재

 

3. Elasticsearch Pod 내부의 CA 인증서 복사

Filebeat가 Elasticsearch와 안전하게 통신하기 위해 Elasticsearch Pod 내부의 CA 인증서(ca.crt) 파일을 Filebeat 서버로 복사해야 합니다. 먼저 Elasticsearch 마스터 Pod 이름을 확인합니다.

[root@hyun-test filebeat-7.17.1-linux-x86_64]# k get pod -n elk
NAME                            READY   STATUS    RESTARTS      AGE
elasticsearch-master-0          1/1     Running   2 (28m ago)   3d23h

 

확인된 Pod 이름을 사용하여 Pod 내부로 접속하고 CA 인증서 내용을 확인하여 Filebeat 서버에 동일한 내용으로 파일을 생성합니다.

[root@hyun-test filebeat-7.17.1-linux-x86_64]# k exec -it -n elk elasticsearch-master-0 /bin/bash
elasticsearch@elasticsearch-master-0:~/config/certs$ cat /usr/share/elasticsearch/config/certs/ca.crt
# (CA 인증서 내용 출력)

출력된 CA 인증서 내용을 Filebeat가 설치된 서버의 /tmp/filebeat-7.17.1-linux-x86_64/ca.crt 파일에 그대로 복사하여 저장합니다.

 

4. Filebeat 실행

Filebeat 설정이 완료되면 Filebeat를 실행하여 로그 수집을 시작합니다.

# Filebeat 설치된 경로로 이동
cd /tmp/filebeat-7.17.1-linux-x86_64

# Filebeat 실행
./filebeat -e -c filebeat.yml

✅ 8단계: Filebeat - Elasticsearch 연동 확인

Filebeat가 정상적으로 실행되고 Elasticsearch로 로그를 전송하는지 Kibana 웹 인터페이스를 통해 확인합니다. Kibana에서 Index Pattern을 생성하고, 수집된 Nginx 로그 데이터를 시각화하여 연동 상태를 점검할 수 있습니다.

🛠️ 9단계: 트러블슈팅

1. 리소스 사용량 제한 에러 (Elasticsearch Pod CrashLoopBackOff)

Elasticsearch Pod이 CrashLoopBackOff 상태에 빠지고, describe pod 명령어로 확인 시 CPU 또는 Memory 부족 관련 에러 메시지가 나타날 수 있습니다.

[root@hyun-test elastic]# k describe pod elasticsearch-master-0 -n elk
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  8m12s  default-scheduler  0/1 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
  Warning  FailedScheduling  8m11s  default-scheduler  0/1 nodes are available: 1 Insufficient cpu. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod..
  Warning  FailedScheduling  3m10s  default-scheduler  0/1 nodes are available: 1 Insufficient cpu. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod..

[root@hyun-test elastic]# k describe node hyun-test
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests      Limits
  --------           --------      ------
  cpu                1675m (83%)   200m (10%)
  memory             2610Mi (71%)  192Mi (5%)
  ephemeral-storage  0 (0%)        0 (0%)
  hugepages-1Gi      0 (0%)        0 (0%)
  hugepages-2Mi      0 (0%)        0 (0%)

원인: 노드의 CPU 또는 메모리 자원 부족으로 인해 Elasticsearch Pod이 정상적으로 실행되지 못하는 상황입니다.

해결 방법:

  • 노드 스케일 업: 클러스터의 CPU 및 메모리 자원을 늘리기 위해 노드를 스케일 업합니다.
  • 워커 노드에 파드 배포: Elasticsearch Pod을 Master Node가 아닌 Worker Node에 배포하여 자원 경합을 줄입니다. (NodeSelector 또는 Taint/Toleration 설정)
  • Elasticsearch Pod 리소스 요청/제한 조정: Elasticsearch Helm Chart의 values.yaml 파일에서 Pod의 리소스 요청(requests) 및 제한(limits) 값을 적절하게 조정합니다. 특히 메모리 제한 단위를 m 대신 Gi로 설정하는 것이 중요합니다.
resources:
  requests:
    cpu: "256m"
    memory: "1Gi"
  limits:
    cpu: "512m"
    memory: "1Gi"

 

2. Elasticsearch Pod 변화 상태 조회 시 CrashLoopBackOff 지속 발생

Elasticsearch Pod의 상태를 조회했을 때 Init:0/1 -> PodInitializing -> RunContainerError -> CrashLoopBackOff가 반복되는 경우, Pod 초기화 과정에서 오류가 발생했을 가능성이 높습니다.

[root@hyun-test elastic]#  kubectl get pods --namespace=elk -l app=elasticsearch-master -w
NAME                     READY   STATUS     RESTARTS   AGE
elasticsearch-master-0   0/1     Init:0/1   0          19s
elasticsearch-master-0   0/1     PodInitializing   0          20s
elasticsearch-master-0   0/1     RunContainerError   0          21s
elasticsearch-master-0   0/1     RunContainerError   1 (1s ago)   22s
elasticsearch-master-0   0/1     CrashLoopBackOff    1 (9s ago)   30s
elasticsearch-master-0   0/1     RunContainerError   2 (1s ago)   43s
elasticsearch-master-0   0/1     CrashLoopBackOff    2 (8s ago)   50s

[root@hyun-test elastic]# k describe -n elk pod elasticsearch-master-0
Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error setting cgroup config for procHooks process: unable to set memory limit to 1 (current usage: 2977792, peak usage: 3280896): unknown
  Warning  BackOff    12s (x7 over 72s)  kubelet            Back-off restarting failed container elasticsearch in pod elasticsearch-master-0_elk(6db64879-fb34-4e18-852d-ae949ec391d7)

 

원인: Pod 설정 파일 (ela_values.yaml)에 오타가 있거나, 리소스 요청/제한 설정이 잘못되어 컨테이너 초기화에 실패하는 경우 발생할 수 있습니다. 위 로그에서는 메모리 제한 설정 오류(memory limit to 1)가 원인이었습니다.

 

해결 방법: Pod 설정 파일 (ela_values.yaml)을 꼼꼼히 확인하여 오타를 수정하고, 리소스 요청 및 제한 설정을 올바르게 수정합니다. 특히 메모리 단위를 m이 아닌 Gi로 설정해야 합니다.

resources:
  requests:
    cpu

 

반응형