Container Host Agent 설치 및 파라미터
K8s/컨테이너 환경의 OS 레벨 메트릭을 수집하는 에이전트이다. oshi-core(pure Java) 라이브러리를 사용하여 네이티브 의존 없이 동작한다.
1. 개요
| 항목 | 내용 |
|---|---|
| 배포 위치 | K8s Pod 내 (/opt/flowkat/agent.host.container) |
| 프로세스 형태 | 독립 JVM 데몬 프로세스 |
| 의존 모듈 | Collect Server TCP 6100 연결 필요 |
| 시스템 라이브러리 | oshi-core (pure Java, 네이티브 불필요) |
| 로그 위치 | $AGENT_HOME/logs/ |
2. 필수 설정 (P0)
| 파라미터 | 타입 | 기본값 | conf 키 | 중요도 | 설명 |
|---|---|---|---|---|---|
net_collector_ip | String | 127.0.0.1 | net_collector_ip | 필수 | 수집 서버 IP. K8s 환경에서는 수집 서버 Service IP 또는 ClusterIP. |
net_collector_tcp_port | int | 6100 | net_collector_tcp_port | 필수 | 수집 서버 TCP 포트. |
obj_name | String | "" | obj_name | 필수 | 오브젝트 이름. K8s에서는 Pod 이름 기반 자동 생성. |
monitoring_group_type | String | "" | monitoring_group_type | 필수 | 모니터링 그룹 타입. |
3. 운영 튜닝 (P1 핵심)
| 파라미터 | 타입 | 기본값 | conf 키 | 중요도 | 설명 |
|---|---|---|---|---|---|
net_collector_tcp_session_count | int | 1 | net_collector_tcp_session_count | 핵심 | TCP 세션 수. |
net_collector_tcp_so_timeout_ms | int | 60000 | net_collector_tcp_so_timeout_ms | 핵심 | TCP 소켓 타임아웃(ms). |
net_collector_tcp_connection_timeout_ms | int | 3000 | net_collector_tcp_connection_timeout_ms | 핵심 | TCP 연결 타임아웃(ms). |
disk_warning_pct | int | 70 | disk_warning_pct | 핵심 | 디스크 경고 임계치(%). |
disk_fatal_pct | int | 90 | disk_fatal_pct | 핵심 | 디스크 치명 임계치(%). |
disk_ignore_size_gb | int | 9000 | disk_ignore_size_gb | 핵심 | 디스크 무시 크기(GB). 대형 스토리지 마운트 제외용. |
cpu_warning_pct | int | 70 | cpu_warning_pct | 핵심 | CPU 경고 임계치(%). |
cpu_fatal_pct | int | 90 | cpu_fatal_pct | 핵심 | CPU 치명 임계치(%). |
mem_warning_pct | int | 80 | mem_warning_pct | 핵심 | 메모리 경고 임계치(%). |
mem_fatal_pct | int | 90 | mem_fatal_pct | 핵심 | 메모리 치명 임계치(%). |
log_keep_days | int | 365 | log_keep_days | 핵심 | 로그 보관일. |
K8s 전용 설정
| 파라미터 | 타입 | 기본값 | conf 키 | 중요도 | 설명 |
|---|---|---|---|---|---|
kube | boolean | (자동감지) | kube | 고급 | K8s 환경 여부. 자동 감지되나 수동 설정 가능. |
kube_pod_sequence_name_enabled | boolean | true | kube_pod_sequence_name_enabled | 고급 | K8s Pod 순차 이름 사용. 수집 서버의 kube_pod_seq_heartbeat_ttl_ms와 연동. |
kube_pod_sequence_name_min_length | int | 18 | kube_pod_sequence_name_min_length | 고급 | Pod 이름 최소 길이 기준. |
전체 파라미터 목록은 parameter-inventory.md 참조.
4. 설치 절차
사전 요건
- Java 8 이상
- Collect Server 기동 및 TCP 6100 포트 개방
- K8s Pod에서 수집 서버 네트워크 접근 가능
설치 단계
# 1. 에이전트 디렉토리를 컨테이너 이미지에 포함하거나 Pod에 복사
cp -r agent.host.container /opt/flowkat/agent.host.container
# 2. 설정 파일 수정
vi /opt/flowkat/agent.host.container/conf/flowkat.conf
# 3. 기동
sh /opt/flowkat/agent.host.container/host.sh
# 4. 기동 확인
tail -f /opt/flowkat/agent.host.container/logs/flowkat.log
5. 설정 파일 예시
# /opt/flowkat/agent.host.container/conf/flowkat.conf
# P0: 수집 서버
net_collector_ip=10.96.0.100
net_collector_tcp_port=6100
# P0: 식별
monitoring_group_type=K8S-WORKER
# P1: 알림 임계치
cpu_warning_pct=80
mem_warning_pct=85
6. 주의사항
| 상황 | 주의 내용 |
|---|---|
| Host Agent와 구분 | 물리/VM 서버에는 agent.host(sigar JNI), K8s 환경에는 agent.host.container(oshi-core pure Java)를 사용한다. |
| netstat 부하 | counter_netstat_enabled=true(기본). 대규모 클러스터에서 부하 발생 시 false 설정 검토. |
| Pod 순차 번호 | kube_pod_sequence_name_enabled=true 시 수집 서버가 Pod별 순차 번호를 부여. TTL은 수집 서버의 kube_pod_seq_heartbeat_ttl_ms(기본 120초)로 관리. |
| log_rotation 하위 호환 | log_rotation_enabled(정식 키) + log_rotation_enalbed(Host Agent 오타 폴백) 양쪽 지원. 신규 설정 시 log_rotation_enabled 사용 권장. |
7. 관련 문서
- Host Agent (물리 서버): 11.agent-host.md
- 수집 서버 설정: 14.collect-server.md
8. Container 에이전트 사양
Container 에이전트는 oshi-core(pure Java)를 사용하므로 네이티브 JNI 라이브러리가 없다. K8s Pod 내에서 독립 JVM 데몬으로 동작한다.
| 리소스 | 항목 | 추정값 | 비고 |
|---|---|---|---|
| 메모리 | JVM 힙 (기본) | 256~512 MB (JVM 자동 결정) | -Xmx 미지정. K8s resources.limits.memory 설정으로 상한 제어 권장 |
| 메모리 | oshi-core 객체 캐시 | +10~20 MB | OS 정보 캐싱 |
| 메모리 | 실제 RSS (정상 동작 시) | ~120~180 MB | Metaspace + Heap + oshi 객체 합산 |
| CPU | K8s API 호출 없음 (cgroups 직접 읽기) | < 0.1% | /sys/fs/cgroup 파일 직접 파싱. K8s API 호출 없음 |
| CPU | oshi-core 수집 주기 | < 0.2% | CPU·메모리·디스크·네트워크 주기 수집 |
| Pod 리소스 | requests.memory | 128 Mi | 정상 가동 최소 기준 |
| Pod 리소스 | limits.memory | 256 Mi | OOMKill 방지 상한 |
| Pod 리소스 | requests.cpu | 50 m | 평상시 점유율 기준 |
| Pod 리소스 | limits.cpu | 200 m | 버스트 허용 상한 |
| 디스크 | 로그 위치 | $AGENT_HOME/logs/ | 컨테이너 에이전트/conf/flowkat.conf의 log_dir로 변경 가능 |
| 디스크 | emptyDir 사용량 (PodSeqManager 데이터) | < 1 MB | K8s Pod 순차 번호(kube_pod_sequence_name_enabled=true) 관리 데이터. Pod 재시작 시 초기화됨 |
| 네트워크 | Counter 전송 대역폭 | < 1 KB/초 | Collect Server TCP 6100 연결 |
9. Kubernetes 환경 트러블슈팅
K8s 환경별 알려진 이슈
| # | 증상 | 원인 | 해결 |
|---|---|---|---|
| K-1 | CNI 호환성 문제 (Calico, Cilium) | CNI 네트워크 정책이 에이전트 TCP 통신 차단 | NetworkPolicy 예외 추가 |
| K-2 | istio sidecar 환경에서 에이전트 연결 실패 | initContainer가 istio proxy 초기화 전에 연결 시도 | holdApplicationUntilProxyStarts 설정 |
| K-3 | Pod 재시작 시 에이전트 식별 변경 | PodSeqManager 순차 번호 재할당 | PodSeqManager 동작 원리 참조 |
| K-4 | emptyDir 용량 초과 | 에이전트 로컬 버퍼 누적 | 로그 로테이션 단축, 볼륨 분리 |
| K-5 | CrashLoopBackOff에서 에이전트 데이터 유실 | Pod 비정상 종료 시 미전송 데이터 손실 | graceful shutdown 설정 |
K-1: CNI 호환성 문제 (Calico, Cilium)
증상: FlowKat 대시보드에서 Container Host Agent가 "연결 끊김" 상태로 표시된다. 에이전트 로그에 Connection refused 또는 Connection timed out이 반복 출력된다.
원인: Calico, Cilium 등 CNI 플러그인의 NetworkPolicy가 기본적으로 Pod 간 TCP 통신을 차단한다. 에이전트가 Collect Server(TCP 6100)에 연결을 시도하지만 정책에 의해 드롭된다.
확인 방법:
# 에이전트 Pod 로그에서 연결 오류 확인
kubectl logs <agent-pod-name> -n <namespace> | grep -E "Connection|refused|timeout"
# NetworkPolicy 목록 확인
kubectl get networkpolicy -n <namespace>
# Pod에서 직접 연결 테스트
kubectl exec -it <agent-pod-name> -n <namespace> -- \
nc -zv <collect-server-service-ip> 6100
해결 방법: Collect Server로의 이그레스(egress)를 허용하는 NetworkPolicy를 추가한다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-flowkat-agent-egress
namespace: <namespace>
spec:
podSelector:
matchLabels:
app: flowkat-agent-container
policyTypes:
- Egress
egress:
- ports:
- protocol: TCP
port: 6100
관련 문서: 17.network-ports.md — 포트 목록 및 방화벽 설정
K-2: istio sidecar 환경에서 에이전트 연결 실패
증상: istio가 활성화된 네임스페이스에서 에이전트 Pod가 기동 직후 ECONNREFUSED 오류를 반복하다가 결국 정상 연결된다. 또는 초기화 중 완전히 연결 실패로 종료된다.
원인: 에이전트 JVM이 istio sidecar(istio-proxy) 컨테이너보다 먼저 기동되어 TCP 아웃바운드 연결을 시도한다. istio proxy가 준비되기 전에는 모든 이그레스 트래픽이 차단된다.
확인 방법:
# Pod 이벤트에서 컨테이너 기동 순서 확인
kubectl describe pod <agent-pod-name> -n <namespace>
# istio-proxy 준비 상태 확인
kubectl get pod <agent-pod-name> -n <namespace> \
-o jsonpath='{.status.containerStatuses[*].name} {.status.containerStatuses[*].ready}'
# istio sidecar 로그에서 초기화 타이밍 확인
kubectl logs <agent-pod-name> -n <namespace> -c istio-proxy | head -30
해결 방법: holdApplicationUntilProxyStarts 옵션을 활성화하여 istio proxy가 준비된 이후에 애플리케이션 컨테이너가 기동되도록 한다.
ConfigMap 전역 설정:
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
data:
mesh: |
defaultConfig:
holdApplicationUntilProxyStarts: true
Pod 단위 annotation 적용:
apiVersion: v1
kind: Pod
metadata:
annotations:
proxy.istio.io/config: |
holdApplicationUntilProxyStarts: true
K-3: Pod 재시작 시 에이전트 식별 변경 (PodSeqManager 동작 원리)
증상: FlowKat 대시보드에서 같은 Deployment의 Pod가 재시작될 때마다 새로운 오브젝트로 등록된다. myapp-pod_0, myapp-pod_rnd123456 형태가 혼재한다.
원인 — PodSeqManager 동작 원리: kube_pod_sequence_name_enabled=true(기본값) 상태에서 에이전트는 수집 서버로부터 순차 번호(seqNoForKube)를 받아 오브젝트 이름을 {podName}_{seq} 형태로 구성한다.
수집 서버로부터 순차 번호를 받기 전 초기화 구간에는 {podName}_rnd{randomNo} 임시 이름을 사용한다(설정 파일). 순차 번호 할당 흐름:
- 에이전트 기동 →
seqNoForKube = -1(미할당 상태, 설정 파일) - 에이전트가 수집 서버에 heartbeat 전송
- 수집 서버가
kube_pod_seq_heartbeat_ttl_ms(기본 120초) 내에 응답하면 순차 번호 반환 Configure.setSeqNoForKube(seq)호출 →obj_name이{podName}_{seq}로 확정 (설정 파일)counter_object_registry_path(/tmp/flowkat) 에{seq}.flowkatkubeseq파일 기록 (에이전트 하트비트 로직)
Pod 재시작 시 /tmp/flowkat(emptyDir)이 초기화되면 기존 seq 파일이 소실되고, 수집 서버가 TTL 만료 전까지 동일 번호를 재할당하지 않으면 새 번호가 부여된다.
확인 방법:
# 에이전트 내부 seq 파일 확인
kubectl exec -it <agent-pod-name> -n <namespace> -- \
ls -la /tmp/flowkat/
# 에이전트 로그에서 obj_name 확인
kubectl logs <agent-pod-name> -n <namespace> | grep -E "obj_name|seqNo|podName|_rnd"
해결 방법: 수집 서버의 TTL을 Pod 재시작 주기보다 길게 설정하거나, counter_object_registry_path를 emptyDir 대신 영속 볼륨으로 마운트한다.
# flowkat.conf — seq 파일을 영속 경로에 저장
counter_object_registry_path=/data/flowkat
# Pod spec — /data/flowkat를 PersistentVolumeClaim으로 마운트
volumes:
- name: flowkat-seq
persistentVolumeClaim:
claimName: flowkat-agent-seq-pvc
containers:
- name: flowkat-agent
volumeMounts:
- name: flowkat-seq
mountPath: /data/flowkat
관련 문서: 23.support-agent-connection.md — 에이전트-수집 서버 연결 상태 진단
K-4: emptyDir 용량 초과
증상: 에이전트 Pod가 반복 재시작되거나 OOMKilled 오류가 발생한다. kubectl describe pod에서 emptyDir size limit exceeded 이벤트가 확인된다.
원인: 에이전트 로그 디렉토리(logs/)가 emptyDir에 위치하고 log_keep_days=365(기본값)가 적용된 경우, 오래된 로그가 삭제되지 않고 누적된다. emptyDir에 sizeLimit이 지정된 경우 초과 시 Pod가 퇴출(Eviction)된다.
확인 방법:
# 에이전트 로그 디렉토리 사용량 확인
kubectl exec -it <agent-pod-name> -n <namespace> -- \
du -sh /opt/flowkat/agent.host.container/logs/
# Pod 이벤트 확인
kubectl describe pod <agent-pod-name> -n <namespace> | grep -A 5 "Events:"
# emptyDir 볼륨 정의 확인
kubectl get pod <agent-pod-name> -n <namespace> -o jsonpath='{.spec.volumes}'
해결 방법: 로그 보관 기간을 단축하고 에이전트 로그를 emptyDir 외부 볼륨으로 분리한다.
# flowkat.conf — 로그 보관 기간 단축
log_keep_days=7
log_dir=/opt/flowkat/agent.host.container/logs
emptyDir에 sizeLimit을 명시하여 초과 시 조기 감지한다:
volumes:
- name: agent-logs
emptyDir:
sizeLimit: 500Mi
containers:
- name: flowkat-agent
volumeMounts:
- name: agent-logs
mountPath: /opt/flowkat/agent.host.container/logs
K-5: CrashLoopBackOff에서 에이전트 데이터 유실
증상: Pod가 CrashLoopBackOff 상태에서 반복 재시작될 때 FlowKat 대시보드에서 해당 Pod의 메트릭 데이터에 빈 구간(gap)이 발생한다.
원인: 에이전트 JVM이 비정상 종료되면 메모리 버퍼에 있는 미전송 카운터/퍼포먼스 데이터가 소실된다. 수집 서버와의 TCP 세션이 즉시 끊기므로 수집 서버 측에서도 플러시가 발생하지 않는다.
확인 방법:
# Pod 재시작 횟수 및 종료 코드 확인
kubectl get pod <agent-pod-name> -n <namespace> \
-o jsonpath='{.status.containerStatuses[0].restartCount} {.status.containerStatuses[0].lastState.terminated.exitCode}'
# 이전 컨테이너 로그 확인
kubectl logs <agent-pod-name> -n <namespace> --previous | tail -50
# CrashLoop 원인 이벤트 확인
kubectl describe pod <agent-pod-name> -n <namespace> | grep -E "Reason|Exit Code|OOM"
해결 방법: Pod 종료 시 JVM에 SIGTERM이 전달되도록 terminationGracePeriodSeconds를 설정하여 에이전트가 진행 중인 전송을 완료할 시간을 확보한다.
spec:
terminationGracePeriodSeconds: 30
containers:
- name: flowkat-agent
lifecycle:
preStop:
exec:
# SIGTERM 전달 전 잠시 대기하여 진행 중인 전송 완료
command: ["/bin/sh", "-c", "sleep 5"]
TCP 세션 수를 늘려 전송 실패 시 재시도 가능성을 높인다:
# flowkat.conf — TCP 세션 증가로 전송 안정성 향상
net_collector_tcp_session_count=2
net_collector_tcp_so_timeout_ms=30000
관련 문서: 23.support-agent-connection.md — 연결 끊김 진단 및 재연결 패턴