쿠버네티스에서 Java Agent 배포의 진화: Operator 패턴으로 완성하는 APM 자동화
Kubernetes에서 Java Agent를 배포하는 다양한 방법들의 진화 과정을 살펴보고, 최종적으로 OPENMARU APM 을 활용한 혁신적인 해결책을 소개합니다.
단순하지만 한계가 명확한 초기 접근법들
1-1. Dockerfile에 Agent 직접 포함하기
처음에는 가장 직관적인 방법부터 시작했습니다.
FROM registry.cop.rnd01.local:8443/images/openjdk:11
# APM Agent 추가
COPY openmaru-agent-5.1.0.jar /opt/khan-agent/khan-agent-5.1.0.jar
# 애플리케이션 추가
COPY myapp.jar /opt/app/
# Agent와 함께 실행
ENTRYPOINT ["java", "-javaagent:/opt/khan-agent/khan-agent-5.1.0.jar", \ "-DOMAPM_HOST=192.168.80.190", \ "-DOMAPM_INSTANCE_ID=myapp", \ "-jar", "/opt/app/myapp.jar"]
현실에서 마주한 문제들
- Agent 5.1.1 패치 버전이 나오면 → 50개 애플리케이션 빌드시 에이전트 파일을 배포 후 이미지 재빌드
- 각 서비스마다 다른 Agent 설정이 필요할 때 → Dockerfile이 서비스별로 분화
- 개발/스테이징/운영 환경별로 다른 APM 서버 → 환경별 이미지 관리의 복잡성
1-2. Base Image 방식으로의 진화
경험을 통해 배운 것은 “중앙 집중식 관리의 필요성”이었습니다.
FROM openjdk:11
ADD khan-agent-5.1.0.jar /opt/khan-agent/khan-agent-5.1.0.jar
초기에는 좋아 보였지만,,,
- latest 태그 사용 → 의도하지 않은 Agent 버전 업그레이드로 인한 장애
- 서비스 A는 Agent 5.1.0, 서비스 B는 5.1.1를 사용해야 하는 상황 → Base Image 분화로 관리 부담
- Base Image 업데이트 시 여전히 모든 애플리케이션 이미지 재빌드 필요
1-3. S2I(Source To Image)로 관리하는 방법
S2I를 도입한 경우라면 좋은 방법이 될 수 있고 OpenShift의 경우 기본으로 제공되는 방식입니다.
project/
├── src/
│ ├── ...
└── data/
└── khan-agent-5.1.0.jar
OpenShift나 S2I가 강제되는 문제
- 개발자가 GIT에서 직접 관리해야 하는 부담
- 배포 시 모든 개발팀에 요청해야 하는 상황
- 소스가 아닌 바이너리를 GIT으로 관리해야 하는 비합리적인 방법
공유 볼륨 통한 유연성 확보
2-1. NFS, ConfigMap/Secret 등을 을 활용한 볼륨 마운트
“빌드 타임과 런타임을 분리하자”는 아이디어에서 시작된 접근법입니다.
# ConfigMap으로 Agent 관리 apiVersion: v1 kind: ConfigMap metadata: name: openmaru-agent binaryData: agent.jar: --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: template: spec: volumes: - name: agent-volume configMap: name: openmaru-agent containers: - name: myapp image: registry.cop.rnd01.local:8443/apps/myapp:latest # Agent 없는 순수 애플리케이션 이미지 volumeMounts: - name: agent-volume mountPath: /opt/agent env: - name: JAVA_TOOL_OPTIONS value: "-javaagent:/opt/khan-agent/khan-agent-5.1.0.jar -Dopenmaru.agent.service.name=myapp" - name: OMAPM_HOST value: 192.168.80.190 - name: OMAPM_APPLICATION_NAME value: 'myapp-${HOSTNAME:-:2}' - name: OMAPM_INSTANCE_ID value: myapp-${HOSTNAME:-:2}-${HOSTNAME:-:3}'
운영해보니 발견한 한계
- ConfigMap/Secret 크기 제한 (1MB) → 큰 Agent JAR 파일 저장 불가
- 바이너리 데이터를 base64로 인코딩 → 크기 1.3배 증가
- 모든 Deployment YAML에 볼륨 설정 추가 → 휴먼 에러 빈발
2-2. Init Container 패턴의 도입
“Agent 다운로드를 런타임에 하자”는 더 발전된 아이디어였습니다.
apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: template: spec: initContainers: - name: khan-agent-init image: registry.cop.rnd01.local:8443/images/khan-agent:5.1.0 command: - sh - -c - | cp /khan-agent-5.1.0.jar /khan-agent/khan-agent-5.1.0.jar volumeMounts: - name: khan-data mountPath: /khan-agent containers: - name: myapp image: registry.cop.rnd01.local:8443/apps/myapp:latest env: - name: JAVA_TOOL_OPTIONS value: "-javaagent:/khan-agent/khan-agent-5.1.0.jar - name: OMAPM_HOST value: 192.168.80.190 - name: OMAPM_APPLICATION_NAME value: 'myapp-${HOSTNAME:-:2}' - name: OMAPM_INSTANCE_ID value: myapp-${HOSTNAME:-:2}-${HOSTNAME:-:3}' volumeMounts: - name: khan-data mountPath: /khan-agent volumes: - name: khan-data emptyDir: {}
이 방식의 장점을 실감했지만
- 각 서비스마다 Init Container 설정 필요
- JAVA_OPTS 및 Agent 설정을 일일이 관리
- 설정 실수로 인한 배포 실패 빈발
- “또 YAML 수정해야 해요?” 라는 불만
자동화에 대한 갈망과 영감
OpenTelemetry Auto-instrumentation과의 만남
운영하면서 가장 큰 깨달음은 “반복되는 수동 작업은 반드시 자동화되어야 한다”는 것이었습니다.
그러던 중 OpenTelemetry Operator의 Auto-instrumentation 기능을 발견했습니다.
# OpenTelemetry 방식 apiVersion: apps/v1 kind: Deployment metadata: annotations: instrumentation.opentelemetry.io/inject-java: "true" spec: template: spec: containers: - name: myapp image: registry.cop.rnd01.local:8443/apps/myapp:latest
단순히 annotation 하나만 추가하면, Operator가 자동으로
- Init Container 추가
- 볼륨 설정
- 환경 변수 설정
- 공통 설정은 중앙에서
- OpenTelemetry Agent 주입
이를 보고 “바로 이거다!”라는 확신이 들었습니다.
OPENMARU Agent Operator의 탄생
설계 원칙
OpenTelemetry에서 영감을 받아 다음 원칙으로 설계했습니다.
- Zero Configuration: 기본 설정으로 즉시 사용 가능
- Convention over Configuration: 합리적인 기본값 제공
- Progressive Enhancement: 필요에 따라 점진적 설정 확장
핵심 동작 메커니즘
간단한 라벨 추가
apiVersion: apps/v1 kind: Deployment metadata: name: myapp labels: openmaru.io/was-agent: "true" # 이것만 추가! spec: template: spec: containers: - name: myapp image: registry.cop.rnd01.local:8443/apps/myapp:latest
Operator에 의한 Init Container 자동 추가
앞서 “Init Container”에서 수동으로 해야 했던 설정 작업들이 Pod가 생성 시 자동으로 주입됩니다.
상황별 상세 옵션 가능
metadata: labels: openmaru.io/was-agent: "true" openmaru.io/agent-version: "5.1.0" ## 특정 버전 지정 openmaru.io/container-names: 'myapp' ## 생략 가능 openmaru.io/was-agent-image-pull-policy: IfNotPresent ## 생략 가능, 기본값: IfNotPresent
Pod에 적용된 모습
실제 도입 성과와 변화
정량적 성과
도입 전 vs 도입 후 비교
항목 | 도입 전 | 도입 후 | 개선 효과 |
새 서비스 APM 적용 시간 | 30분-1시간 | 1분 | 95% 단축 |
Agent 업그레이드 시간 | 서비스당 15-30분 | 전체 일괄 5분 | 90% 단축 |
정성적 변화
개발팀의 반응
“이제 APM 때문에 인프라팀에 요청할 필요가 없어졌어요. 라벨 하나만 추가하면 끝이니까요.”
“애플리케이션 개발에만 집중할 수 있게 되었습니다.”
운영팀의 반응
“Agent 업그레이드가 이렇게 쉬울 줄 몰랐어요. 한 번에 모든 서비스를 업그레이드할 수 있어서 좋습니다.”
“설정 실수로 인한 장애가 거의 사라졌습니다.”
도구 활용의 철학과 지속적 진화
엔지니어링의 본질에 대한 성찰
이번 기회를 통해 깨달은 가장 중요한 점은 “도구는 문제를 해결하는 수단이지 목적이 아니다”라는 것입니다.
Kubernetes Operator를 만든 것 자체가 목적이 아니라, 개발팀과 운영팀이 겪고 있는 실제 고통을 해결하는 것이 진짜 목적이었습니다. 그 과정에서 OpenTelemetry의 접근 방식에서 영감을 받고, Kubernetes Operator 패턴을 활용한 것은 자연스러운 선택이었습니다.
도구 선택과 활용의 기준
1. 실용성 우선
- 멋있어 보이는 기술보다는 실제 문제를 해결하는 기술
- 역량과 상황에 맞는 현실적 선택
2. 점진적 개선
- 한 번에 완벽한 해결책을 만들려 하지 않기
- 작은 개선을 반복하며 점진적으로 발전
3. 사용자 중심 사고
- 개발자와 운영자의 실제 워크플로우 이해
- 기술적 우아함보다는 고객 사용자 경험 우선
맺음말(마무리)
OPENMARU APM은 단순히 서비스의 안정성을 보니터링하고 분석하는 제품이 아닙니다.
앞으로도 계속해서 도구들을 깊이 탐구하고, 실제 문제를 해결하는 더 나은 방법들을 찾아가겠습니다. 그리고 그 과정에서 얻은 경험과 고객과 공유하여, 모든 고객들이 더 좋은 환경에서 저희 제품을 사용할 수 있게 하겠습니다.
기술은 도구일 뿐입니다. 중요한 것은 그 도구로 무엇을 만들어내고, 얼마나 많은 사람들의 일상을 개선할 수 있느냐입니다.
References
- [자료 다운로드] 운영자가 알아야 하는 쿠버네티스 이전과 이후 비교
- [자료 다운로드] 컨테이너(Container) 와 쿠버네티스(Kubernetes)
- [자료 다운로드] 구글 이 오픈소스로 공개한 쿠버네티스 핵심
- [자료다운로드] 쿠버네티스 아키텍처 완벽 가이드 : 구조와 동작 원리 A to Z
- [자료 다운로드] 쿠버네티스 는 왜 어려운가?
- 쿠버네티스 Private 컨테이너 레지스트리 구축 방법
- Kubernetes (쿠버네티스) 도입을 가로막는 오해와 장벽 12가지
- 쿠버네티스 를 통한 운영 자동화, 이해해야 신뢰할 수 있어요.
- 쿠버네티스(Kubernetes)란 무엇인가요?
- 가상화 엔지니어가 Kubernetes 를 이해하지 못하는 이유는?
JBoss 고객이라면 반드시 알아야 하는 운영 노하우 공유
/카테고리: JBoss, Red Hat, Seminar/작성자: 오픈마루 마케팅0JBoss 실행 옵션을 cli 로 자동화하기
/카테고리: OpenShift, Red Hat, Seminar/작성자: 오픈마루 마케팅0Dogfooding – 사용자 입장에서 제품이나 서비스의 품질과 UX를 확인할 수 있습니다.
/카테고리: OpenShift, Red Hat, Seminar/작성자: 오픈마루 마케팅0