1. 문제 배경
클러스터를 생성한 이후 바로 서비스를 배포하려 했지만, Kubernetes는 단순히 컨테이너를 실행하는 구조가 아니라 이미지, 설정, 권한, 저장소가 분리된 상태에서 동작한다.
이 상태에서 바로 배포를 진행할 경우 다음과 같은 문제가 발생할 수 있다.
- 클러스터에서 이미지를 인식하지 못하는 문제
- 환경 변수와 설정이 코드에 종속되는 구조
- Pod가 외부 리소스에 접근하지 못하는 문제
- Pod 재시작 시 데이터가 유실되는 문제
따라서 실제 서비스 배포 이전에 공통적으로 필요한 구성 요소를 먼저 정리했다.
2. 목표
- Kubernetes 실행에 필요한 공통 리소스 구성
- 환경 설정과 코드 분리
- 서비스 간 연결 정보 외부화
- 데이터 유지가 가능한 구조 확보
3. 이미지 준비 방식
Kubernetes는 컨테이너 이미지를 기반으로 Pod를 생성하기 때문에 클러스터에서 접근 가능한 위치에 이미지를 준비해야 한다.
이미지를 사용하는 방식은 크게 두 가지가 있다.
- 로컬 이미지를 클러스터 내부로 직접 주입하는 방식 (kind load)
- 외부 레지스트리를 통해 이미지를 공유하는 방식 (push / pull)
로컬 개발 환경에서는 kind load 방식이 빠르지만, 다른 서버나 클러스터에서도 동일한 이미지를 사용해야 하는 경우에는 레지스트리를 통한 방식이 더 적합하다.
이번 구성에서는 이후 배포 환경 확장을 고려해 레지스트리를 기준으로 이미지를 관리했다.
docker tag navisafe-producer:latest <dockerhub-username>/navisafe-producer:latest
docker push <dockerhub-username>/navisafe-producer:latest
※ 실제 계정 정보는 보안상 제외하고 구조만 정리했다.
4. Helm 및 Spark Operator 설치
Spark 작업을 Kubernetes에서 실행하기 위해 Operator를 사용했다.
- 위 zip 파일을 다운로드 한 후에, 실행 파일을 아래와 같은 경로에 위치

2. 실행 파일을 위와 같이 위치한 후 환경변수를 설정

- Spark Application을 리소스로 정의 가능
- Pod를 직접 관리하지 않고 선언형으로 실행
helm repo add spark-operator https://kubeflow.github.io/spark-operator
helm install spark-operator spark-operator/spark-operator \
--namespace spark-operator \
--create-namespace

5. Namespace 구성
리소스를 역할별로 분리하기 위해 namespace를 구성했다.
kubectl create namespace spark-operator
kubectl create namespace airflow

namespace를 기준으로 리소스를 분리하면 서비스 간 충돌을 방지하고 관리 단위를 나눌 수 있다.
6. Secret 생성
외부 서비스 연결 정보는 코드에 포함하지 않고
Kubernetes Secret으로 분리했다.
kubectl create secret generic navisafe-producer-secret \
--from-literal=KAFKA_BOOTSTRAP=<kafka-bootstrap-server> \
--from-literal=REDIS_HOST=<redis-host> \
--from-literal=MYSQL_HOST=<mysql-host> \
--from-literal=MYSQL_USER=<username> \
--from-literal=MYSQL_PASSWORD=<password>
※ 실제 값은 보안상 제외하고 구조만 정리했다.
7. ServiceAccount 생성
Pod가 Kubernetes 리소스에 접근할 수 있도록 ServiceAccount를 생성했다.
kubectl create serviceaccount spark
8. ConfigMap 구성
설정 파일과 초기 SQL 스크립트를 이미지와 분리하기 위해 ConfigMap을 사용했다.
kubectl create configmap mysql-init-script --from-file=init.sql
또한 Airflow에서 사용할 Pod 템플릿도 ConfigMap으로 관리했다.
kubectl create configmap airflow-pod-template \
--from-file=airflow-pod-template.yaml -n airflow
이 방식은 설정 변경 시 이미지를 다시 빌드하지 않아도 된다는 점에서
운영 관점에서 유리하다.
9. 스토리지 구성 (PVC)
Pod 재시작 시 데이터가 유지될 수 있도록 Persistent Volume을 구성했다.
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
이를 통해 데이터와 로그를 지속적으로 유지할 수 있는 환경을 구성했다.
10. 정리
이번 단계에서는 서비스를 바로 배포하기보다, Kubernetes에서 실행에 필요한 요소를 먼저 분리해서 준비했다.
- 클러스터에서 접근 가능한 이미지 관리 방식 구성
- Spark Operator 설치
- Secret, ConfigMap을 통한 설정 분리
- ServiceAccount를 통한 권한 관리
- PVC를 통한 데이터 유지
특히 이미지 관리 방식은 단순한 선택이 아니라 배포 범위(로컬 vs 서버)에 따라 달라지는 구조적인 선택이라는 점을 확인할 수 있었다.
Kubernetes 환경 구성 (3) - NaviSafe 서비스 배포와 Kafka Topic 초기화
1. 문제 배경사전 준비 단계에서 이미지, 설정, 권한, 저장소를 분리했지만 실제 서비스는 아직 실행되지 않은 상태였다.Kubernetes에서는 서비스를 단순히 실행하는 것이 아니라, 각 서비스의 역할
jjaehyeok.tistory.com
'Navisafe > Infrastructure' 카테고리의 다른 글
| AWS S3 및 IAM 설정 - 클라우드 데이터 접근 환경 구성 (0) | 2026.04.29 |
|---|---|
| Kubernetes 환경 구성 (5) - PostgreSQL + PostGIS + pgRouting 구성 (0) | 2026.04.29 |
| Kubernetes 환경 구성 (4) - 데이터 파이프라인 동작 검증 (0) | 2026.04.20 |
| Kubernetes 환경 구성 (3) - NaviSafe 서비스 배포와 Kafka Topic 초기화 (0) | 2026.04.20 |
| Kubernetes 환경 구성 (1) - Windows에서 kind로 NaviSafe 클러스터 생성 (0) | 2026.04.20 |