CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서     CNAP 클라우드 플랫폼 GitOps 대시보드를 직접 체험해보세요  —  실시간 CI/CD, 모니터링, 보안 관제를 한 곳에서    

ECK Stack (Elasticsearch & Kibana)

ECK Operator로 Elasticsearch 클러스터와 Kibana를 배포합니다.


1. 개요

Elasticsearch 3노드 클러스터와 Kibana 1노드를 배포합니다. TLS는 Ingress에서 종료하며 내부 통신은 평문입니다. podAntiAffinity (required)로 각 Elasticsearch Pod가 반드시 별도 노드에 스케줄링되므로 워커 노드 3개 이상이 필요합니다.


2. 사전 요구사항

  • ECK Operator: database 네임스페이스에 설치 완료 (2-05-eck-operator.md)
  • 워커 노드: 3개 이상 (Elasticsearch podAntiAffinity required 조건)
  • TLS Secret: cnapcloud.com-tlsdatabase 네임스페이스에 존재 (cert-manager + reflector)
  • DNS: kibana.cnapcloud.com 등록

3. 디렉터리 구조

eck/ek/
├── Makefile
└── kustomize/
    ├── base/
    │   ├── kustomization.yaml          # secretGenerator, 리소스 목록
    │   └── resources/
    │       ├── elasticsearch.yaml      # Elasticsearch 3노드 클러스터
    │       ├── kibana.yaml             # Kibana 1노드
    │       └── ingress.yaml            # Kibana Ingress (kibana.cnapcloud.com)
    └── overlays/
        ├── dev/
        │   └── kustomization.yaml      # namespace: database, TZ=Asia/Seoul
        └── dev-arm64/
            └── kustomization.yaml      # dev + _JAVA_OPTIONS=-XX:UseSVE=0 (ARM64용)

4. 사전 설정

Elasticsearch 인증에 사용할 Secret을 base/kustomization.yamlsecretGenerator로 생성합니다.

secretGenerator:
  - name: es-elastic-user
    type: kubernetes.io/basic-auth
    literals:
      - username=elastic
      - password=<password>
      - roles=superuser

주의: password 값을 평문으로 Git에 커밋하지 않습니다. SOPS로 암호화하거나 외부 Secret 관리 도구를 사용합니다.


5. 배포

5.1 배포 설정

base/resources/elasticsearch.yaml — 주요 설정:

  • 노드 수: 3 (master + data + ingest 통합)
  • sysctl: vm.max_map_count=262144, fs.file-max=65536 (initContainer)
  • podAntiAffinity: required — 각 Pod를 반드시 별도 노드에 배치
  • preStop: 종료 전 샤드 재배치 후 대기 (최대 280초)
  • TLS: 비활성화 (Ingress에서 종료)

ARM64 노드에 배포하는 경우 overlays/dev-arm64를 사용합니다. SVE 명령어 비호환 문제를 피하기 위해 _JAVA_OPTIONS=-XX:UseSVE=0을 추가합니다.

5.2 배포 실행

make preview  # 적용 전 매니페스트 확인
make apply    # 클러스터에 적용 (x86)

# ARM64 노드인 경우
make preview DEPLOY_ENV=dev-arm64
make apply DEPLOY_ENV=dev-arm64

6. 설치 후 검증

6.1 CRD 상태 확인

kubectl get elasticsearch,kibana -n database

예상 결과 — 두 리소스 모두 health: green, phase: Ready:

NAME                                              HEALTH   NODES   VERSION   PHASE
elasticsearch.elasticsearch.k8s.elastic.co/...   green    3       7.17.16   Ready

NAME                                   HEALTH   NODES   VERSION   AGE
kibana.kibana.k8s.elastic.co/kibana    green    1       7.17.16   ...

6.2 Elasticsearch 클러스터 헬스 확인

kubectl exec -n database elasticsearch-es-default-0 -- \
  curl -s -u elastic:<password> http://localhost:9200/_cluster/health?pretty

예상 결과:

{
  "status" : "green",
  "number_of_nodes" : 3,
  "active_shards_percent_as_number" : 100.0
}

6.3 Kibana UI 접근 확인

브라우저에서 https://kibana.cnapcloud.com 접속 시 Kibana 로그인 화면이 표시됩니다. elastic / <password>로 로그인합니다.


7. Troubleshooting

7.1 Elasticsearch Pod Pending — podAntiAffinity 충족 불가

증상: Elasticsearch Pod 중 일부가 Pending 상태

원인: requiredDuringSchedulingIgnoredDuringExecution 조건으로 3개 Pod가 각각 별도 노드를 요구하는데 가용 노드 부족

해결: 워커 노드를 3개 이상으로 확장하거나, elasticsearch.yamlpodAntiAffinitypreferredDuringSchedulingIgnoredDuringExecution으로 변경합니다.

7.2 vm.max_map_count 오류

증상: Elasticsearch Pod가 max virtual memory areas vm.max_map_count [65530] is too low 오류로 기동 실패

원인: sysctl initContainer 실행 실패 또는 권한 부족

해결: initContainer가 privileged: true로 설정되어 있는지 확인합니다. PodSecurityPolicy 또는 Security Context가 privileged 실행을 차단하는 경우 노드에 직접 sysctl -w vm.max_map_count=262144를 적용합니다.

7.3 Kibana — Elasticsearch 연결 실패

증상: Kibana Pod가 기동 후 kibana_task_manager 인덱스 생성 중 오류

원인: Elasticsearch가 아직 green 상태가 아니거나 es-elastic-user Secret 불일치

해결: Elasticsearch phase: Ready 확인 후 Kibana Pod를 재시작합니다.


8. 제거

주의: make delete로 Elasticsearch를 삭제하면 PVC가 남아 있어도 데이터 복구가 어렵습니다. 삭제 전 스냅샷 백업을 권장합니다.

make delete

PVC는 별도로 삭제해야 합니다.

kubectl delete pvc -n database -l elasticsearch.k8s.elastic.co/cluster-name=elasticsearch