네, 알겠습니다. 두 번째 글인 ‘PVC 기반 워크플로우’를 워드프레스에 바로 게시할 수 있는 전문가용 기술 문서 형식으로 작성해 드리겠습니다.
Kafka Connect와 커스텀 SMT의 GitOps 통합 관리 (2): PVC를 활용한 영속적 플러그인 관리
이전 문서에서 다룬 ConfigMap 기반의 SMT 배포 전략은 경량의 JAR 파일을 관리하는 데 효과적이지만, Kubernetes ConfigMap의 크기 제한(기본 1MB)이라는 명확한 한계가 있습니다. 대용량 플러그인을 다루거나 플러그인의 생명주기를 애플리케이션의 배포 주기와 분리하고자 할 때, Persistent Volume Claim(PVC)을 활용한 전략이 강력한 대안이 될 수 있습니다.
이 방식은 공유 스토리지를 중앙 플러그인 저장소로 사용하여 Kafka Connect Pod들이 이를 마운트하는 구조입니다.
PVC 기반 아키텍처
PVC 기반 플러그인 관리 아키텍처는 다음 네 가지 핵심 요소로 구성됩니다.
- 공유 스토리지 (Shared Storage):
ReadWriteMany
(RWX) 접근 모드를 지원하는 스토리지 클래스(예: NFS, CephFS, AWS EFS)를 기반으로 Persistent Volume(PV)을 프로비저닝합니다. RWX 모드는 여러 Kafka Connect Pod가 동시에 동일한 볼륨에 접근하여 플러그인을 읽을 수 있도록 하는 데 필수적입니다. - Persistent Volume Claim (PVC): CI/CD 파이프라인과 Kafka Connect 클러스터가 공유할 중앙 플러그인 저장소 역할을 하는 PVC를 생성합니다. 이 PVC는 프로비저닝된 PV에 바인딩됩니다.
- CI/CD 파이프라인: 커스텀 SMT 코드가 변경되면, 파이프라인은 JAR 파일을 빌드한 후 이 PVC에 마운트된 공유 볼륨의 특정 경로에 업로드합니다.
- Kafka Connect Pod: Kafka Connect의 Deployment 또는 StatefulSet은 이 PVC를 볼륨으로 마운트하고, 해당 경로를
plugin.path
에 추가하여 플러그인을 로드합니다.
이 구조는 플러그인이라는 ‘상태(State)’를 외부 영속 스토리지로 분리하여 관리하는 모델입니다.
GitOps 통합 워크플로우
PVC 기반 전략의 전체적인 워크플로우는 다음과 같이 진행됩니다.
- SMT 코드 변경 및 푸시: 개발자가 SMT 코드를 수정하고 Git 저장소에 푸시합니다.
- CI 파이프라인 트리거: Git 푸시를 감지한 CI 파이프라인(예: GitLab CI, GitHub Actions)이 실행되어 Gradle이나 Maven을 통해 JAR 파일을 빌드합니다.
- 플러그인 배포 (핵심 단계): CI 파이프라인은 빌드된 JAR 파일을 PVC에 직접 복사합니다. 이 단계는 구현 방식에 따라 몇 가지 옵션이 있습니다.
- 임시 Pod 활용: CI 스크립트가
kubectl
을 사용하여 PVC를 마운트하는 임시 Pod를 실행하고,kubectl cp
명령으로 JAR 파일을 해당 Pod의 마운트 경로에 복사합니다. - 스토리지 클라이언트 활용: CI 실행기(runner)에 NFS 클라이언트나 AWS CLI와 같은 스토리지 전용 도구를 설치하고, 이를 통해 직접 PVC에 파일을 업로드합니다.
- 임시 Pod 활용: CI 스크립트가
- Kafka Connect 재시작: 새로운 플러그인을 클러스터에 인식시키기 위해 Kafka Connect Deployment의 롤링 재시작을 트리거합니다. 이 신호는 CI 파이프라인의 마지막 단계에서
kubectl rollout restart deployment/kafka-connect -n <namespace>
명령으로 전달됩니다. - 플러그인 로드: 롤링 업데이트를 통해 새로 시작된 Kafka Connect Pod들은 마운트된 PVC 경로에서 최신 플러그인 JAR 파일을 찾아 로드합니다.
Helm을 통한 PVC 마운트 설정
Kafka Connect Helm 차트의 values.yaml
파일에서 PVC를 마운트하도록 아래와 같이 설정합니다.
# 기존 plugin.path에 PVC 마운트 경로를 추가합니다.
pluginPaths: "/opt/kafka/plugins,/opt/kafka/custom-smt-pvc"
# PVC를 볼륨으로 마운트하기 위한 설정입니다.
extraVolumeMounts:
- name: custom-smt-pvc-volume
mountPath: /opt/kafka/custom-smt-pvc
extraVolumes:
- name: custom-smt-pvc-volume
persistentVolumeClaim:
# 미리 생성해 둔 PVC의 이름을 지정합니다.
claimName: kafka-connect-plugins-pvc
기술적 고려사항
이 전략을 채택하기 전에 장단점을 명확히 이해해야 합니다.
장점
- 대용량 파일 지원: JAR 파일 크기에 사실상 제한이 없습니다.
- 플러그인과 애플리케이션 생명주기 분리: Pod를 재배포하지 않고 플러그인만 업데이트할 수 있는 유연성을 제공합니다 (단, 플러그인 로드를 위한 재시작은 필요).
- 중앙 관리: 모든 플러그인이 단일 공유 스토리지에서 관리되므로, 여러 Connect 클러스터가 동일한 플러그인을 공유하는 시나리오에서 일관성을 유지하기 용이합니다.
단점
ReadWriteMany
(RWX) 의존성: 분산 모드로 운영되는 Kafka Connect 클러스터는 모든 Pod가 동시에 볼륨에 접근할 수 있어야 하므로, RWX를 지원하는 스토리지 솔루션(예: NFS)에 대한 강한 의존성이 생깁니다. 이는 클라우드 환경에서 구성 복잡성을 증가시킬 수 있습니다.- 상태 관리의 복잡성: PVC는 상태를 가지는(stateful) 리소스이므로, 백업, 복구, 마이그레이션, 접근 권한 등 추가적인 운영 부담이 발생합니다.
- 상태 불일치 위험: CI/CD 프로세스가 비정상적으로 종료되거나 관리자가 수동으로 파일을 조작할 경우, Git에 정의된 상태와 실제 스토리지의 파일 상태가 불일치할 위험이 내재되어 있습니다.
이 전략은 사내에 NFS와 같은 공유 파일 시스템 인프라가 이미 안정적으로 구축되어 있거나, 매우 큰 용량의 플러그인을 다루어야 하는 환경에 특히 적합합니다.