본문으로 건너뛰기

Kubernetes 모드 설치

모든 핵심 문서를 확인했습니다. 이제 상세한 답변을 작성합니다.


exemONE Kubernetes 모드 신규 설치 가이드

참고 문서:


1. 시스템 요구사항

1-1. 서버 사양

구분CPUMemorySSD - Storage(월)
최소8 core16 GB0.5 TB
권장16 core32 GB1 TB

인스턴스 개수별 사양:

인스턴스CPUMemoryStorage(월)
5개2 core4 GB125GB
10개4 core8 GB250GB
20개8 core16 GB0.5 TB
40개16 core32 GB1 TB
  • HDD의 경우 성능이 심하게 떨어지기 때문에 SSD 권장
  • 디스크 사용량은 모니터링 대상과 수집 양에 따라 다를 수 있으므로, 구축 후 일별 사용량을 체크하여 필요 시 디스크 증설 또는 보관 주기 수정 필요

1-2. 지원 환경

항목내용
실행 환경Kubernetes 클러스터 (docker 또는 containerd 런타임)
설치 파일exemone-kubernetes-pkg-{version}.tar.gz
설치 명령어sh generate.shsh apply.sh
관리 도구kubectl 명령어

2. 포트 정보

Target출발지도착지TypePort포트 사용 내용
exem-host-agentunix 장비ReceiverTCP9010범용 TCP 요청 및 응답
exem-host-agentlinux, windows 장비ReceivergRPC9009범용 gRPC 요청 및 응답
exem-k8s-agent모니터링 대상 장비ReceivergRPC9009범용 gRPC 요청 및 응답
exem-container-agent모니터링 대상 장비ReceivergRPC9009범용 gRPC 요청 및 응답
exem-db-agent수집 서버Target DBTCPDB Listener PortDB 지표 수집
exem-java-agent모니터링 대상 장비ReceiverTCP9010범용 TCP 요청 및 응답
Cloud-ReceiverTCP443클라우드 데이터 수집
모니터링 사용자 PC사용자 PCGatewayHTTPS8443WEB UI 접속 포트
HTTP8080WEB UI 접속 포트
ClickHouseTCP8123수집 데이터 저장
PostgreSQLTCP5432메타 데이터 저장

3. 수집 서버 모듈 구성 (총 16개)

설치 후 kubectl get pods로 확인 시, 모든 Pod가 Running 상태여야 합니다.


4. 핵심 제약조건

exemone-api와 exemone-receiver Pod는 반드시 동일한 Node에서 실행되어야 합니다.

이를 위해 Worker Node에 라벨을 설정하고, Deployment의 nodeSelector로 제어합니다.

라벨 설정:

kubectl label nodes worker-node1 workload=exemone-k8s

Deployment nodeSelector 설정 (파일: {SET_NAME}/deployment.yaml):

...
spec:
selector:
matchLabels:
app: exemone-receiver
replicas: 1
template:
...
spec:
nodeSelector:
workload: exemone-k8s # 또는 kubernetes.io/hostname: worker-node1
...

5. Kubernetes 모드 신규 설치 절차 (단계별)

[Phase 1] 사전 설정

단계 1. Storage Class 생성

exemONE 서비스 데이터를 저장할 Storage Class가 미리 생성되어 있어야 합니다.

StorageClass 매니페스트 예시:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage-exemone-k8s
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
kubectl apply -f storageclass.yaml

단계 2. Namespace 생성

exemONE 서비스를 실행할 Namespace를 생성합니다.

kubectl create namespace exemone-k8s

단계 3. Worker Node 라벨 설정 (제약조건 적용)

api와 receiver가 동일 노드에서 실행되도록 라벨을 설정합니다.

kubectl label nodes worker-node1 workload=exemone-k8s

[Phase 2] 패키지 압축 해제

단계 1. 패키지 파일 압축 해제

tar xvzf exemone-kubernetes-pkg-v3.0.1.0.tar.gz

단계 2. installer 폴더로 이동 후 내부 패키지 압축 해제

cd exemone-kubernetes/installer
tar xvzf exemone-kubernetes.tar.gz

단계 3. exemone-kubernetes 폴더로 이동

cd exemone-kubernetes

[Phase 3] 이미지 로드

exemONE 서비스를 사용할 모든 Node에 이미지를 로드해야 합니다.

  • 이미지 폴더 위치: exemone-kubernetes/image/

Docker 사용 시:

docker load -i <이미지>.tar.gz
# 예시) docker load -i bitnami-kafka-3.3.2-debian-11-r5.tar.gz

# 이미지 로드 검증
docker images | grep exemone

containerd 사용 시:

namespace의 경우, k8s.io가 일반적이나 환경에 따라 다를 수 있습니다.

ctr -n k8s.io images import <이미지>.tar.gz
# 예시) ctr -n k8s.io images import bitnami-kafka-3.3.2-debian-11-r5.tar.gz

# 이미지 로드 검증
ctr -n k8s.io images ls | grep exemone

containerd에서 invalid tar header 에러 발생 시:

gunzip -k <이미지>.tar.gz    # gzip 압축 해제
ctr -n k8s.io images import <이미지>.tar

# 예시
gunzip -k bitnami-kafka-3.3.2-debian-11-r5.tar.gz
ctr -n k8s.io images import bitnami-kafka-3.3.2-debian-11-r5.tar

[Phase 4] 수집 모듈 설치

스크립트 실행 위치: exemone-kubernetes/installer/exemone-kubernetes

단계 1. generate.sh 실행 (yaml 파일 생성)

generate.sh는 templates 폴더 내 yaml 파일을 사용하여 exemONE 수집 모듈 생성을 위한 yaml 파일을 신규 생성합니다.

sh generate.sh

실행 시 입력하는 설정 옵션:

Please enter set name: exemone
Please enter namespace: exemone-k8s
Please enter cluster domain: cluster.local
Please enter storage class name: local-storage-exemone-k8s

create yaml files
Directory exemone created
Files copied
replace variables in yaml files
done!
설정 옵션설명
SET NAME희망하는 폴더 이름 (해당 폴더에 yaml 파일이 생성됨)
NAMESPACE설치할 네임스페이스
CLUSTER_DOMAIN클러스터 도메인 (일반적으로 cluster.local)
STORAGE_CLASS_NAMEPV 생성에 사용할 Storage Class (사전 설정 필요)

generate.sh 실행 후 SET_NAME으로 지정한 폴더 안에 다음과 같은 yaml 파일들이 생성됩니다: deployment.yaml, statefulset.yaml, pvc.yaml, service.yaml, configmap.yaml

단계 2. apply.sh 실행 (설치)

SET_NAME 폴더에 있는 yaml 파일들을 Kubernetes 클러스터에 apply합니다.

sh apply.sh
Please enter set name: exemone

persistentvolumeclaim/exemone-db-agent-configs created
persistentvolumeclaim/exemone-db-agent-logs created
persistentvolumeclaim/exemone-db-agent-queries created
persistentvolumeclaim/exemone-cloud-agent-configs created
persistentvolumeclaim/exemone-cloud-agent-logs created
persistentvolumeclaim/exemone-cloud-agent-queries created
persistentvolumeclaim/exemone-receiver-logs created
persistentvolumeclaim/exemone-core-logs created
persistentvolumeclaim/exemone-core-db created
persistentvolumeclaim/exemone-alerter-logs created
persistentvolumeclaim/exemone-ingester-logs created

[Phase 5] 설치 확인

단계 1. Pod 및 PVC 배포 확인

kubectl get pods -n exemone-k8s
kubectl get pvc -n exemone-k8s

예상 결과:

[root@localhost ~]# kubectl get pods -n exemone-k8s
NAME READY STATUS RESTARTS AGE
exem-container-agent-2hktr 1/1 Running 0 119m
exem-container-agent-72948 1/1 Running 0 119m
...

[root@localhost ~]# kubectl get pvc -n exemone-k8s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
exemone-alerter-logs Bound pvc-92108ca2-ddc3-4d8c-b54c-6ec352b7abb8 512Mi RWO local-storage-exemone-k8s 4h1m
exemone-api-class Bound pvc-c54d63b2-79d6-48b0-a661-e4959366a59a 512Mi RWO
...

단계 2. exemone-api와 exemone-receiver 동일 노드 배포 검증

kubectl get pods -n exemone-k8s -o wide | grep -E 'exemone-api|exemone-receiver'

예상 결과 (동일 Node 확인):

exemone-api-6d66444566-trzdp        1/1     Running       0          4h2m   10.244.2.22    worker-node1            <none>           <none>
exemone-receiver-95d99f5bb-g9wfz 1/1 Running 0 4h2m 10.244.2.18 worker-node1 <none> <none>

두 Pod가 동일한 worker-node1에서 실행되고 있으면 정상입니다.


6. 매니페스트(YAML) 설정 상세

6-1. 생성되는 주요 YAML 파일

generate.sh 실행 시 templates 폴더의 yaml 파일을 기반으로, 입력한 변수값이 치환되어 {SET_NAME} 폴더에 yaml 파일이 생성됩니다.

치환되는 변수 목록:

변수설명
${namespace}Namespace
${clusterDomain}클러스터 도메인
${storageClassName}Storage Class 이름
${dbAgentVersion}exemone-db-agent 이미지 버전
${receiverVersion}exemone-receiver 이미지 버전
${coreVersion}exemone-core 이미지 버전
${alerterVersion}exemone-alerter 이미지 버전
${ingesterVersion}exemone-ingester 이미지 버전
${gatewayVersion}exemone-gateway 이미지 버전
${apiVersion}exemone-api 이미지 버전
${frontVersion}exemone-front 이미지 버전
${nginxVersion}exemone-nginx 이미지 버전
${postgresqlVersion}exemone-postgresql 이미지 버전
${clickhouseVersion}exemone-clickhouse 이미지 버전
${redisVersion}exemone-redis 이미지 버전
${kafkaVersion}exemone-kafka 이미지 버전

6-2. StorageClass 매니페스트 예시

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage-exemone-k8s
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

6-3. StatefulSet 매니페스트 예시 (PostgreSQL)

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: exemone-postgresql
namespace: ${namespace}
labels:
io.exem: "true"
io.exem.prod: exemone
io.exem.one.type: middleware
io.exem.one.app: postgresql
spec:
selector:
matchLabels:
app: exemone-postgresql
serviceName: "exemone-postgresql"
replicas: 1
template:
metadata:
labels:
app: exemone-postgresql
spec:
volumes:
- name: exemone-postgresql-initdbd
configMap:
name: exemone-postgresql-initdbd
defaultMode: 420
- name: exemone-postgresql-data
persistentVolumeClaim:
claimName: exemone-postgresql-data
containers:
- name: exemone-postgresql
image: maxgauge/exemone-postgres:${postgresqlVersion}
ports:
- name: postgres
containerPort: 5432
protocol: TCP
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: exemone-postgresql-password
key: password
volumeMounts:
- name: exemone-postgresql-initdbd
mountPath: /docker-entrypoint-initdb.d
- name: exemone-postgresql-data
mountPath: /var/lib/postgresql/data/pgdata
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "4"
memory: "10Gi"
imagePullSecrets:
- name: regcred

6-4. Deployment nodeSelector 설정 (api/receiver 동일 노드 배포)

spec:
selector:
matchLabels:
app: exemone-receiver
replicas: 1
template:
spec:
nodeSelector:
workload: exemone-k8s # 또는 kubernetes.io/hostname: worker-node1

6-5. .env 파일 (모듈 버전 관리)

파일 위치: exemone-kubernetes/installer/exemone-kubernetes/.env

.env 파일에서 각 모듈의 이미지 버전을 관리하며, 모듈 패치 시 이 파일의 버전을 변경한 후 apply.sh를 재실행합니다.


7. bash 스크립트를 실행할 수 없는 환경

generate.sh / apply.sh를 실행할 수 없는 경우, templates/ 폴더 아래 yaml 파일에서 위 변수 문자열을 수동으로 치환하여 각 오브젝트를 kubectl apply -f로 직접 적용할 수 있습니다.


8. 수집 모듈 삭제

스크립트 실행 위치: exemone-kubernetes/installer/exemone-kubernetes

sh delete.sh
  • apply.sh에서 적용한 모든 exemONE 서비스 모듈 및 데이터가 삭제됩니다.
  • SET_NAME으로 생성한 폴더 내의 YAML 파일도 함께 삭제됩니다.

데이터(PVC) 유지가 필요한 경우

delete.sh 파일에서 아래 라인을 주석 처리해야 합니다:

# kubectl delete -f ./$SET_NAME/pvc.yaml

9. 모듈 패치 방법

9-1. 개별 모듈 패치

  1. 이미지 로드: 모든 Node에 신규 이미지 로드
  2. .env 파일 수정: 패치할 모듈의 버전 정보를 변경
vi exemone-kubernetes/installer/exemone-kubernetes/.env
  1. apply.sh 실행:
sh apply.sh
  1. 정상 구동 확인:
kubectl get pods -n exemone-k8s

상세 가이드: Kubernetes 모듈 패치 가이드

9-2. 패키지 패치 (template/script 변경 포함)

신규 패치 버전에서 template이나 script 파일이 변경된 경우 아래 절차를 따릅니다:

  1. 기존 홈 디렉토리 백업:
mv exemone-kubernetes exemone-kubernetes.bak
  1. 신규 패키지 압축 해제:
tar -xzvf exemone-kubernetes-pkg-v3.0.508.21.tar.gz
  1. 모든 Node에 이미지 로드
  2. 기존 디렉토리에서 StorageClass 확인:
cd exemone-kubernetes.bak/installer/exemone-kubernetes
cat exemone/pvc.yaml | grep -m 1 storageClassName
  1. 기존 YAML에서 사용자가 수정한 부분(NodeSelector, 리소스 제한 등)을 신규 templates에 반영
  2. generate.sh 실행 → apply.sh 실행

상세 가이드: Kubernetes 패키지 패치 가이드


10. PostgreSQL 13→17 업데이트 (선택사항)

exemONE의 PostgreSQL을 13에서 17로 업데이트하는 경우 아래 절차를 따릅니다.

주의사항:

  • delete.sh 실행 시 기존 데이터가 삭제되므로 권장하지 않습니다
  • Pod 재생성 시 기존 PVC와 동일한 Node에서 실행되어야 합니다
  • 수집 모듈 패치와 함께 진행 시, 수집 모듈 패치 후 PostgreSQL 업데이트 진행
  • 반드시 최신 패키지 파일에서 진행 필요

업데이트 절차 요약:

  1. exemone-postgresql의 Pod, StatefulSet 이름 확인
  2. exemone-api의 Pod, Deployment 이름 확인
  3. exemone-api Pod 정지 (replicas 0):
kubectl -n <namespace> scale deploy <deploy 이름> --replicas 0
  1. PostgreSQL 데이터 백업:
kubectl -n <namespace> exec <postgres 파드> -- pg_dumpall -U postgres > pg13_dump.sql
  1. PG 기존 PVC 유지 (제거하지 않음)
  2. exemone-postgresql StatefulSet 제거:
kubectl -n <namespace> delete statefulset <statefulset 이름>
  1. PVC 이름 변경하여 추가 (exemone-postgresql-data-17)
  2. StatefulSet 수정 (volume, volumeMounts 이름 변경)
  3. generate.sh → PVC 생성 → StatefulSet 생성
  4. 데이터 복원:
kubectl cp ./pg13_dump.sql <namespace>/<postgres 파드>:/tmp/pg13_dump.sql
kubectl -n <namespace> exec -it <postgres 파드> -- psql -U postgres -f /tmp/pg13_dump.sql
  1. exemone-api 재시작:
kubectl -n <namespace> scale deploy exemone-api --replicas 1

상세 가이드: Kubernetes PostgreSQL 13→17 업데이트 가이드


11. 설치 후 정상 작동 확인 리스트

11-1. Pod 상태 확인

kubectl get pods -n exemone-k8s
  • 모든 Pod가 Running 상태인지 확인
  • RESTARTS 횟수가 계속 증가하지 않는지 확인

11-2. api/receiver 동일 노드 확인

kubectl get pods -n exemone-k8s -o wide | grep -E 'exemone-api|exemone-receiver'

11-3. 비정상 Pod 로그 확인

Pod가 CrashLoopBackOff 등 비정상 상태인 경우:

kubectl logs -n exemone-k8s <Pod 이름>

11-4. 웹 화면 접속 확인

  • 브라우저에서 https://[Gateway 서비스 IP]:8443 또는 http://[Gateway 서비스 IP]:8080으로 접속
  • 로그인이 정상적으로 되는지 확인
  • 로그인 실패 시 exemone-api Pod 로그 확인 필요

11-5. 에이전트 상태 확인

  • HOST 기본 뷰: Active / Inactive 상태 확인

  • Database 기본 뷰: Active / No Signal 상태 확인

  • Kubernetes Pod 뷰: Running 상태 확인

  • WAS 기본 뷰: Active 상태 확인

inactive 또는 nosignal인 경우, 수집서버 ↔ 타겟 서버 간 네트워크 및 포트(9009/9010) 방화벽 확인이 필요합니다.


12. Helm Chart 관련

참고 문서에서 확인한 바에 따르면, exemONE Kubernetes 설치는 Helm Chart 방식이 아닌 자체 스크립트 기반(generate.sh + apply.sh)으로 YAML 매니페스트를 생성·배포하는 방식을 사용합니다. generate.sh가 templates 폴더의 YAML 파일에 변수를 치환하여 배포용 YAML을 생성하는 역할을 하므로, Helm의 템플릿 렌더링과 유사한 기능을 수행합니다.


13. 주의사항

  1. 제약조건 필수: exemone-api와 exemone-receiver Pod는 반드시 동일 Node에 배포해야 합니다. nodeSelector 또는 kubernetes.io/hostname 라벨로 제어하세요.
  2. SSD 필수: HDD 사용 시 심각한 성능 저하가 발생합니다.
  3. 모든 Node에 이미지 로드: 이미지는 서비스를 사용할 모든 Worker Node에 로드해야 합니다.
  4. Storage Class 사전 생성: generate.sh 실행 전에 Storage Class가 반드시 존재해야 합니다.
  5. Namespace 사전 생성: apply.sh 실행 전에 Namespace가 반드시 존재해야 합니다.
  6. 패키지 파일 준비: 설치 파일(exemone-kubernetes-pkg-{version}.tar.gz)은 제품기술팀에 문의하여 준비합니다.
  7. delete.sh 사용 주의: PVC 데이터를 유지하려면 반드시 kubectl delete -f ./$SET_NAME/pvc.yaml 라인을 주석 처리한 후 실행하세요.
  8. PostgreSQL 업데이트 순서: 수집 모듈 패치와 함께 진행 시, 수집 모듈 패치를 먼저 진행한 후 PostgreSQL 업데이트를 진행해야 합니다.
  9. containerd 환경: containerd 사용 시 이미지 import에 ctr -n k8s.io images import 명령어를 사용하되, invalid tar header 에러 발생 시 gunzip으로 압축 해제 후 .tar 파일로 import하세요.