서버

k8s에서 스카우터 이름 고유하게 설정하기(helm)

백봉 2025. 9. 10. 17:43

Scouter Dynamic Pod Naming Solution

개요

Kubernetes 환경에서 Scouter APM을 사용할 때, 여러 Pod 인스턴스를 고유하게 식별하기 위한 동적 Pod명 설정 솔루션입니다.

문제점

기존 문제

  • 모든 Pod가 동일한 obj_name (예: "java1")으로 스카우터에 표시
  • Pod 구분이 어려워 개별 모니터링 불가능
  • 수동으로 Pod명을 설정하는 방법들의 한계:
    • 환경변수 치환이 스카우터 설정 파일에서 직접 작동하지 않음
    • EntryPoint 스크립트 방식의 복잡성
    • System Property 방식의 제한사항

해결 목표

  • 각 Pod가 고유한 Pod명으로 스카우터에 표시
  • 완전 자동화된 설정
  • 확장 가능한 솔루션

솔루션 아키텍처

핵심 아이디어

  • ${HOST_NAME} 환경변수에 Pod명이 포함되어 있음을 활용
  • InitContainer를 통한 동적 설정 파일 생성
  • Kubernetes Downward API를 활용한 Pod 메타데이터 주입

구조도

ConfigMap Template → InitContainer → Dynamic Config → Main Container → Scouter Agent
    (템플릿)       (치환 처리)      (실제 설정)     (애플리케이션)   (모니터링)

구현 상세

1. ConfigMap Template (templates/configmap.yaml)

{{- if .Values.scouter.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "ab-box.fullname" . }}-scouter-config
  labels:
    {{- include "ab-box.labels" . | nindent 4 }}
data:
  scouter.conf: |
    ### scouter java agent configuration
    obj_host_name=k8s
    obj_name=${HOST_NAME}  # 플레이스홀더: InitContainer에서 치환됨
    net_collector_ip={{ .Values.scouter.collectorIp }}
    net_collector_udp_port={{ .Values.scouter.collectorUdpPort }}
    net_collector_tcp_port={{ .Values.scouter.collectorTcpPort }}

    # Health Check 및 Actuator 엔드포인트 모니터링 제외
    xlog_fully_discard_service_patterns=/actuator/*,/health*
    xlog_discard_service_show_error=true

    # 서비스 후킹 패턴
    hook_exception_class_patterns=java.lang.Throwable
{{- end }}

2. InitContainer 설정 (templates/deployment.yaml)

InitContainer 추가

initContainers:
  - name: scouter-config-init
    image: busybox:1.35
    command: ['sh', '-c']
    args:
      - |
        echo "Generating scouter config with HOST_NAME: $HOST_NAME"
        sed "s/\${HOST_NAME}/$HOST_NAME/g" /config-template/scouter.conf > /config-output/scouter.conf
        echo "Generated config:"
        cat /config-output/scouter.conf | head -10
    env:
      - name: HOST_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name  # Pod명 자동 주입
    volumeMounts:
      - name: scouter-config-template
        mountPath: /config-template
      - name: scouter-config-generated
        mountPath: /config-output

메인 컨테이너 Volume 수정

volumeMounts:
  - name: scouter-config-generated  # 템플릿이 아닌 생성된 설정 사용
    mountPath: /opt/agent.java/conf
    readOnly: true

Volume 정의

volumes:
  - name: scouter-config-template      # ConfigMap 템플릿
    configMap:
      name: {{ include "ab-box.fullname" . }}-scouter-config
  - name: scouter-config-generated     # 동적 생성된 설정
    emptyDir: {}

실행 과정

1. Pod 생성 단계

  1. Kubernetes Scheduler: Pod 생성 및 고유명 할당
    • 예: ab-box-prod-6fd597cd94-7zrj9

2. InitContainer 실행 단계

  1. 환경변수 주입: Downward API를 통해 Pod명이 HOST_NAME에 설정
  2. 템플릿 로드: ConfigMap에서 scouter.conf 템플릿 읽기
  3. 치환 처리: sed 명령어로 ${HOST_NAME} → 실제 Pod명 치환
  4. 설정 생성: 동적 생성된 설정 파일을 emptyDir 볼륨에 저장

3. 메인 컨테이너 실행 단계

  1. 설정 마운트: 동적 생성된 설정 파일 사용
  2. 스카우터 에이전트 시작: 고유한 Pod명으로 모니터링 시작

결과 예시

생성되는 설정 파일

### scouter java agent configuration
obj_host_name=k8s
obj_name=ab-box-prod-6fd597cd94-7zrj9  # 실제 Pod명
net_collector_ip=192.168.10.105
net_collector_udp_port=6100
net_collector_tcp_port=6100

스카우터 모니터링 화면

  • 이전: 모든 Pod가 "java1"로 표시
  • 이후: 각각 고유한 Pod명으로 표시
    • ab-box-prod-6fd597cd94-7zrj9
    • ab-box-prod-6fd597cd94-k8m2x
    • ab-box-prod-6fd597cd94-p9t4l

장점

✅ 완전 자동화

  • 수동 설정 불필요
  • Pod 재시작 시 자동으로 새로운 이름 적용

✅ 고유성 보장

  • Kubernetes가 보장하는 Pod명의 고유성 활용
  • 이름 충돌 가능성 제거

✅ 확장성

  • 다른 마이크로서비스에 동일 패턴 적용 가능
  • Values 파일을 통한 환경별 설정 지원

✅ 안정성

  • Kubernetes 네이티브 기능 활용
  • InitContainer 패턴을 통한 안전한 설정 생성

✅ 디버깅 용이성

  • InitContainer 로그를 통한 설정 생성 과정 추적 가능
  • 생성된 설정 파일 내용 확인 가능

다른 프로젝트 적용 방법

1. ConfigMap 수정

obj_name=${HOST_NAME}  # 이 라인 추가

2. Deployment에 InitContainer 추가

위의 InitContainer 설정을 그대로 복사하여 적용

3. Volume 설정 수정

템플릿과 생성된 설정을 위한 두 개의 볼륨 설정

4. Values 파일 확인

scouter:
  enabled: true
  collectorIp: "192.168.10.105"
  collectorUdpPort: 6100
  collectorTcpPort: 6100

모니터링 및 문제 해결

InitContainer 로그 확인

kubectl logs <pod-name> -c scouter-config-init -n <namespace>

생성된 설정 파일 확인

kubectl exec <pod-name> -n <namespace> -- cat /opt/agent.java/conf/scouter.conf

스카우터 에이전트 로그 확인

kubectl logs <pod-name> -n <namespace> | grep -i scouter

성능 영향

InitContainer 오버헤드

  • 시작 시간: 약 1-2초 추가 (busybox 이미지 풀 및 sed 처리)
  • 리소스 사용: 최소한의 CPU/메모리 사용 (busybox)
  • 디스크 사용: 설정 파일 크기만큼 emptyDir 사용 (일반적으로 1KB 미만)

런타임 영향

  • 없음: InitContainer는 메인 컨테이너 시작 전에 완료되므로 런타임 성능에 영향 없음

향후 개선 방안

1. 설정 파일 템플릿 확장

  • 더 많은 환경변수 지원
  • 조건부 설정 생성

2. 다중 환경 지원

  • 개발/스테이징/프로덕션별 다른 템플릿 지원

3. 모니터링 개선

  • InitContainer 실행 상태 모니터링
  • 설정 생성 실패 시 알림

결론

이 솔루션은 Kubernetes 환경에서 Scouter APM의 Pod 식별 문제를 완전히 해결하며, 확장 가능하고 유지보수가 용이한 방식으로 구현되었습니다. InitContainer 패턴을 활용하여 복잡한 환경변수 치환 문제를 우아하게 해결했으며, 다른 마이크로서비스에도 쉽게 적용할 수 있는 범용적인 솔루션입니다.