Docker를 사용하면 애플리케이션을 컨테이너로 패키징할 수 있지만, 여러 대의 서버와 수많은 컨테이너를 관리하기에는 한계가 있습니다. 이때 등장하는 것이 Kubernetes (쿠버네티스)입니다.
Kubernetes란?
Kubernetes는 Google이 개발하고 CNCF가 관리하는 컨테이너 오케스트레이션 플랫폼입니다. 수십~수백 개의 Docker 컨테이너를 자동으로 배포, 스케일링, 복구하고, 서비스 간 트래픽을 효율적으로 분산시킵니다.
- Pod: Kubernetes의 최소 실행 단위 (1개 이상의 컨테이너 포함)
- Deployment: Pod의 배포, 업데이트, 롤백을 관리
- Service: Pod 간 통신과 외부 노출(Load Balancer) 담당
- Ingress: 외부 트래픽을 도메인 기반으로 라우팅
1. 준비 단계 — Docker 이미지 빌드
먼저 Spring Boot 애플리케이션을 Docker 이미지로 빌드합니다.
./gradlew bootJar
docker build -t springboot-k8s:latest .
이후 Kubernetes 클러스터에서 접근 가능한 Docker Registry(예: Docker Hub, AWS ECR, GCR 등)에 이미지를 푸시합니다.
docker tag springboot-k8s your-dockerhub-id/springboot-k8s:latest
docker push your-dockerhub-id/springboot-k8s:latest
2. Deployment 구성
Kubernetes에서 애플리케이션을 실행하기 위해 deployment.yaml 파일을 작성합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-app
labels:
app: springboot-app
spec:
replicas: 2
selector:
matchLabels:
app: springboot-app
template:
metadata:
labels:
app: springboot-app
spec:
containers:
- name: springboot-container
image: your-dockerhub-id/springboot-k8s:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
위 설정은 Spring Boot 컨테이너를 2개(Pod 2개) 실행하고, 자원 제한을 명시하여 안정적인 클러스터 운영을 보장합니다.
3. Service 구성
Pod는 동적으로 IP가 변경될 수 있기 때문에, Service를 통해 고정된 접근점을 제공합니다.
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
Service 타입을 LoadBalancer로 지정하면 클라우드 환경(AWS, GCP 등)에서 자동으로 외부 접근이 가능한 IP 또는 도메인이 생성됩니다.
4. Ingress로 도메인 라우팅 (선택 사항)
외부 도메인 이름을 이용해 트래픽을 라우팅하려면 Ingress를 구성합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: springboot-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: springboot-service
port:
number: 80
Ingress Controller(Nginx Ingress Controller 등)를 통해, demo.example.com 도메인으로 들어오는 요청을 Spring Boot 서비스로 전달할 수 있습니다.
5. 리소스 배포 및 확인
모든 YAML 파일이 준비되면, kubectl 명령으로 Kubernetes에 리소스를 배포합니다.
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
배포 상태는 아래 명령으로 확인할 수 있습니다.
kubectl get pods
kubectl get svc
kubectl get ingress
Service의 EXTERNAL-IP가 생성되면 해당 주소를 통해 애플리케이션에 접근할 수 있습니다.
6. 롤링 업데이트 및 복구
Kubernetes는 Deployment를 이용해 애플리케이션을 무중단으로 업데이트할 수 있습니다.
kubectl set image deployment/springboot-app springboot-container=your-dockerhub-id/springboot-k8s:v2
문제가 발생할 경우, 즉시 이전 버전으로 롤백할 수 있습니다.
kubectl rollout undo deployment/springboot-app
이렇게 Kubernetes는 안정적인 배포와 롤백, 스케일링을 모두 자동으로 처리합니다.
7. 오토스케일링 (HPA)
트래픽이 급증할 경우, Horizontal Pod Autoscaler(HPA)를 통해 자동으로 Pod 개수를 늘릴 수 있습니다.
kubectl autoscale deployment springboot-app --cpu-percent=70 --min=2 --max=5
CPU 사용률이 70%를 초과하면 최대 5개까지 Pod를 자동으로 확장합니다.
8. ConfigMap과 Secret으로 환경 분리
환경별 설정 값을 외부에서 주입하려면 ConfigMap과 Secret을 활용합니다.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
SPRING_PROFILES_ACTIVE: prod
API_URL: https://api.example.com
---
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
DB_USER: admin
DB_PASSWORD: securepass
Pod에서는 아래처럼 환경 변수로 주입할 수 있습니다.
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secret
주의할 점
- 클러스터 시간 동기화(NTP) 불일치 시 로그 및 트레이싱 분석 어려움
- 리소스 요청(requests)과 제한(limits)을 명확히 설정해야 안정적인 스케줄링 가능
- 이미지 태그 latest 사용은 피하고, 버전 명시(v1, v2 등)로 추적성 확보
- ConfigMap/Secret은 Git에 직접 커밋하지 않도록 주의
- Ingress 사용 시 HTTPS 인증서 자동 갱신(Let’s Encrypt + cert-manager) 구성 권장
Spring Boot 애플리케이션을 Kubernetes에 배포하면, 확장성, 가용성, 복구력을 모두 확보할 수 있습니다. Docker만으로는 어려운 스케일링과 자동 복구를 Kubernetes가 대신 처리하므로, 대규모 트래픽을 다루는 서비스에 필수적인 기술입니다.
'개발 > JAVA' 카테고리의 다른 글
| Spring Boot와 AWS RDS 연동하기 - 안정적인 클라우드 데이터베이스 환경 구축 (0) | 2025.11.12 |
|---|---|
| Spring Boot와 Jenkins CI/CD 파이프라인 구축 - 자동화된 배포 환경 만들기 (0) | 2025.11.11 |
| Spring Boot + Docker로 배포하기 - 손쉬운 컨테이너 기반 애플리케이션 배포 (0) | 2025.11.09 |
| Sleuth와 Zipkin으로 분산 트레이싱 - 마이크로서비스의 요청 흐름 가시화 (0) | 2025.11.08 |
| Hystrix/Resilience4j로 장애 대응하기 — 마이크로서비스의 회복탄력성 설계 (0) | 2025.11.07 |
