1. 개요: GKE와 AWS MSK 간의 안전한 Kafka 데이터 동기화
- ✨ 이 문서의 목표: Google Kubernetes Engine (GKE) 환경에서 Strimzi MirrorMaker2를 사용하여 AWS MSK (Managed Streaming for Kafka)의 데이터를 온프레미스 또는 다른 클라우드의 OSS Kafka로 안전하게 단방향 동기화하는 방법을 안내합니다.
- 🔑 핵심 과제 해결: GKE의 서비스 계정(GCP SA)이 AWS IAM 역할을 통해 MSK에 직접 인증하도록 Workload Identity Federation을 구성하여, AWS 액세스 키를 직접 관리하는 위험 없이 보안을 강화합니다.
- 📚 주요 학습 내용:
- Workload Identity Federation 설정 이해 및 구성
- AWS MSK IAM 인증을 위한 커스텀 Strimzi MirrorMaker2 이미지 빌드
- Strimzi MirrorMaker2를 사용하여 MSK와 OSS Kafka 간의 데이터 미러링 설정
2. 시작하기 전에: 구성 환경 및 사전 지식
- 🛠️ 구성 환경:
- GKE (Google Kubernetes Engine)
- GCP SA - AWS IAM Workload Identity Federation
- Strimzi:
0.39.0 - Kafka:
3.5.1(소스: AWS MSK, 타겟: OSS Kafka) - AWS MSK IAM Auth Plugin:
aws-msk-iam-auth-2.2.0.jar - 필수 도구:
aws-cli,kubectl,docker
- 🧠 필요한 사전 지식:
- Kubernetes 및 GKE 기본 운영
- Apache Kafka 및 Strimzi 기본 개념
- AWS IAM 역할 및 정책
- GCP 서비스 계정 및 Workload Identity Federation 개념
3. 동기화 아키텍처 및 흐름 🌬️
- 🎯 동기화 목표: AWS MSK에서 GKE 클러스터 내 OSS Kafka로 단방향 데이터 동기화.
- 🔐 인증 흐름:
- GKE Pod (MirrorMaker2)가 GCP 서비스 계정(SA)으로 실행됩니다.
- GCP SA는 Workload Identity Federation을 통해 AWS IAM 역할을 수임(AssumeRole)합니다.
- 수임된 AWS IAM 역할의 임시 자격 증명을 사용하여 AWS MSK에 IAM 방식으로 인증 및 접근합니다.
- MirrorMaker2는 MSK에서 데이터를 읽어 OSS Kafka로 전송합니다.
4. 1단계: AWS 및 GCP 환경 사전 설정 ⚙️
- 목표: GKE 워크로드가 AWS IAM 역할을 수임할 수 있도록 Workload Identity Federation을 설정합니다.
- 4.1. AWS IAM 역할 구성
- MSK 접근 권한을 가진 IAM 정책 생성
- GCP SA가 수임할 수 있는 신뢰 관계를 가진 IAM 역할 생성
- 4.2. GCP 서비스 계정(SA) 생성 및 권한 부여
- GKE에서 사용할 GCP SA 생성
- 생성된 GCP SA에
iam.workloadIdentityUser역할 부여 (특정 네임스페이스의 Kubernetes SA와 바인딩)
- 4.3. GKE Workload Identity 설정
- GKE 클러스터에서 Workload Identity 활성화
- GCP SA와 Kubernetes SA(KSA) 간의 IAM 정책 바인딩 설정
5. 2단계: AWS IAM 인증을 위한 커스텀 Strimzi 이미지 빌드 🐳
- 목표: Strimzi MirrorMaker2가 AWS MSK에 IAM 방식으로 인증하는 데 필요한 AWS CLI 및 Kafka IAM Auth 플러그인을 포함하는 커스텀 이미지를 생성합니다.
- 5.1. Dockerfile 구성
## Stage 1: Install AWS CLI
FROM public.ecr.aws/amazonlinux/amazonlinux:2 AS installer
ARG EXE_FILENAME=awscli-exe-linux-x86_64.zip
## Docker 빌드 컨텍스트 내 ./awscli/ 디렉토리에 AWS CLI zip 파일이 있다고 가정
COPY ./awscli/$EXE_FILENAME .
RUN yum update -y \
&& yum install -y unzip \
&& unzip $EXE_FILENAME \
&& ./aws/install --bin-dir /aws-cli-bin/
## Stage 2: Build custom Strimzi Kafka image
FROM quay.io/strimzi/kafka:0.39.0-kafka-3.5.1
USER root:root
## Install necessary packages and create directories
RUN microdnf update -y \
&& microdnf --setopt=install_weak_deps=0 --setopt=tsflags=nodocs install -y jq less groff-base procps \
&& microdnf clean all -y \
&& mkdir -p /home/kafka/.aws
## Copy AWS CLI from installer stage
COPY --from=installer /usr/local/aws-cli/ /usr/local/aws-cli/
COPY --from=installer /aws-cli-bin/ /usr/local/bin/
## Copy Kafka IAM Auth plugin and AWS config/credentials setup scripts
# Docker 빌드 컨텍스트 내 ./libs/ 에 IAM auth plugin jar 파일(aws-msk-iam-auth-2.2.0.jar)이 있다고 가정
COPY ./libs/aws-msk-iam-auth-2.2.0.jar /opt/kafka/libs/
## Docker 빌드 컨텍스트 내 ./aws/ 에 AWS 설정 파일 (예: config)이 있다고 가정 (선택 사항)
COPY --chown=1001:0 ./aws/ /home/kafka/.aws/
## Docker 빌드 컨텍스트 내 ./scripts/ 에 관련 스크립트가 있다고 가정 (선택 사항)
# COPY --chown=1001:0 --chmod=755 ./scripts/ /home/kafka/
USER 1001
6. 3단계: Strimzi MirrorMaker2 배포 및 설정 🚀
- 목표: 커스텀 이미지를 사용하여 Strimzi MirrorMaker2를 GKE에 배포하고, MSK와 OSS Kafka 간의 미러링을 구성합니다.
- 6.1. MirrorMaker2 Kubernetes Manifest (YAML)
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaMirrorMaker2
metadata:
name: msk-to-oss-kafka-mm2
namespace: kafka-mm2 # 이 네임스페이스에 KSA가 Workload Identity로 GCP SA와 연결되어 있어야 함
spec:
version: 3.5.1 # Kafka 버전
image: registry.my.repo/strimzi/custom-mirrormaker2:dev # 5단계에서 빌드한 이미지
replicas: 1
connectCluster: gcp-oss-kafka # 타겟 Kafka 클러스터 alias (아래 clusters 정의와 일치)
clusters:
- alias: aws-msk # 소스 MSK 클러스터
bootstrapServers: YOUR_MSK_BOOTSTRAP_SERVERS:9098 # 예: b-1.xxxx.xxxx.kafka.ap-northeast-2.amazonaws.com:9098
config:
group.id: msk-oss-kafka-mm2
config.storage.topic: mm2-configs # MirrorMaker2 내부용 설정 토픽
offset.storage.topic: mm2-offsets # MirrorMaker2 내부용 오프셋 토픽
status.storage.topic: mm2-status # MirrorMaker2 내부용 상태 토픽
# AWS MSK IAM 인증 설정
security.protocol: SASL_SSL
sasl.mechanism: AWS_MSK_IAM
sasl.jaas.config: "software.amazon.msk.auth.iam.IAMLoginModule required awsProfileName=\"default\" awsDebugCreds=true;"
sasl.client.callback.handler.class: software.amazon.msk.auth.iam.IAMClientCallbackHandler
# plugin.path는 Strimzi가 /opt/kafka/libs 아래의 JAR를 자동으로 로드하므로 일반적으로 불필요
- alias: gcp-oss-kafka # 타겟 OSS Kafka 클러스터
bootstrapServers: gcp-oss-kafka.your-namespace.svc.cluster.local:9092 # 예시: GKE 내부 Kafka 서비스 주소
config:
group.id: msk-oss-kafka-mm2
config.storage.topic: mm2-configs
offset.storage.topic: mm2-offsets
status.storage.topic: mm2-status
config.storage.replication.factor: 1 # 환경에 맞게 조정
offset.storage.replication.factor: 1 # 환경에 맞게 조정
status.storage.replication.factor: 1 # 환경에 맞게 조정
# 타겟 클러스터가 인증을 사용한다면 관련 security.protocol, sasl.* 설정 추가
mirrors:
- sourceCluster: aws-msk
targetCluster: gcp-oss-kafka
topicsPattern: "copy-target-topic" # 동기화할 토픽 패턴 (정규식 가능)
# groupsPattern: ".*" # 소비자 그룹 오프셋 동기화 시 (필요시 주석 해제)
sourceConnector: # Source -> Target 데이터 복제 설정
# tasksMax: 1 # 병렬 작업 수 (기본값 사용 또는 필요시 조정)
config:
replication.factor: -1 # 타겟 클러스터의 브로커 기본값 사용
refresh.topics.interval.seconds: 60
sync.topic.acls.enabled: "false" # ACL 동기화 비활성화
# checkpointConnector: # Target -> Source 오프셋 동기화 (단방향에서는 보통 불필요)
# config:
# sync.group.offsets.enabled: "false"
template:
pod:
imagePullSecrets:
- name: my-repo-secret # 커스텀 이미지 레지스트리 접근 시크릿
serviceAccountName: ksa-for-mirrormaker # 4.3에서 설정한 Kubernetes 서비스 계정
connectContainer:
env:
- name: AWS_ROLE_ARN
value: arn:aws:iam::{YOUR_AWS_ACCOUNT_ID}:role/your-msk-access-role # 4.1에서 생성한 IAM 역할 ARN
- name: AWS_WEB_IDENTITY_TOKEN_FILE # Workload Identity가 주입하는 토큰 경로
value: /var/run/secrets/sts.amazonaws.com/serviceaccount/token
# - name: AWS_STS_REGIONAL_ENDPOINTS # 리전 엔드포인트 사용 시 (예: regional)
# value: "regional"
# metricsConfig: # JMX Prometheus Exporter 설정 (선택 사항)
# type: jmxPrometheusExporter
# valueFrom:
# configMapKeyRef:
# key: metrics-config.yml
# name: mirror-maker-2-metrics
# rack: # GKE Zone 인식을 위한 설정 (선택 사항)
# topologyKey: topology.gke.io/zone
- 6.2. YAML 파일 배포
kubectl apply -f mirrormaker2.yaml -n kafka-mm2
- 6.3. 배포 확인 및 트러블슈팅
- Pod 로그 확인:
kubectl logs -f <mm2-pod-name> -n kafka-mm2 -c kafka - IAM 인증 오류, Kafka 연결 오류 등 확인
- Pod 로그 확인:
7. 추가 고려 사항 및 FAQ 🤔
- 🔒 보안:
- IAM 역할 권한 최소화 원칙 준수
- GCP SA 및 KSA 권한 범위 제한
- ⚡ 성능:
replicas,tasksMax등 파라미터 튜닝- 네트워크 대역폭 및 지연 시간 고려
❓ FAQ:
- Q:
awsProfileName="default"설정은 어떻게 동작하나요?- A: Docker 이미지 내
/home/kafka/.aws/config파일에[profile default]섹션이 정의된 경우 이를 참조할 수 있습니다. Workload Identity Federation 사용 시에는AWS_ROLE_ARN과AWS_WEB_IDENTITY_TOKEN_FILE환경 변수를 통해 AWS SDK가 자동으로 자격 증명을 얻으므로, 복잡한 프로필 설정이 필수는 아닙니다.awsDebugCreds=true옵션은 인증 과정을 디버깅하는 데 도움이 됩니다.
- A: Docker 이미지 내
- Q:
GCP_OAUTH_AUD환경 변수 설정이 필요한가요?- A:
AWS_WEB_IDENTITY_TOKEN_FILE환경 변수를 사용하면 일반적으로 AWS SDK가 토큰의 audience를 자동으로 인식하여GCP_OAUTH_AUD를 명시적으로 설정할 필요가 없습니다. 만약 문제가 발생하거나 특정 audience를 지정해야 한다면, GCP Workload Identity Pool Provider 설정에서 확인된 audience 값을 사용해야 합니다. 대부분의 경우, 이 변수 없이 정상 동작합니다.
- A:
- Q:
plugin.path설정이KafkaMirrorMaker2YAML에 필요 없는 이유는 무엇인가요?- A: Strimzi Kafka 이미지는 기본적으로
/opt/kafka/libs디렉토리를 플러그인 경로로 인식합니다. Dockerfile에서aws-msk-iam-auth-2.2.0.jar파일을 해당 위치에 복사했으므로 MirrorMaker2가 자동으로 플러그인을 로드합니다. 따라서 명시적인plugin.path설정은 생략 가능합니다.
- A: Strimzi Kafka 이미지는 기본적으로
