중소기업 쿠버네티스 구축 – 09. 워크로드와 레거시 연동: 실전 트러블슈팅 (Headless Service·SNAT·503 디버깅)

2026.08.04

·

시리즈 안내
이 글은 “중소기업 쿠버네티스 구축” 시리즈의 마지막 9편입니다. 8편까지 인프라 레이어(클러스터·스토리지·노출·배포 자동화)를 모두 갖췄습니다. 이번 편에서는 그 위에 실제 애플리케이션 워크로드를 올리고, 클러스터 밖 레거시 시스템과 연동하면서 마주친 실전 문제들을 해결합니다. 시리즈의 하이라이트입니다.


들어가며

인프라를 아무리 잘 깔아도, 실제 서비스를 올리면 교과서에 없던 문제들이 튀어나옵니다. 이번 편은 그 현장의 기록입니다.

다룰 워크로드는 여러 마이크로서비스로 구성된 실제 서비스입니다.

Sponsored

  • 프론트엔드, API 게이트웨이
  • 인증(SSO), 회원, 결제 등 도메인별 서비스
  • 클러스터 밖에 있는 외부 API와 레거시 DB

이들을 클러스터에 올리고 서로, 그리고 바깥과 통신시키는 과정에서 부딪힌 세 가지 대표 문제 — 외부 시스템 연동, 비대칭 라우팅, 503 에러 디버깅 — 을 차례로 풀어봅니다.


1. 워크로드 배포의 기본

마이크로서비스들은 전용 네임스페이스(예: t4x-system)에 모아 배포합니다. 각 서비스는 Deployment(Pod를 관리)와 Service(Pod를 묶는 진입점)로 구성되고, 외부 노출이 필요한 것만 Ingress를 붙입니다.

배포 자체는 7·8편에서 한 것과 같은 패턴이라 반복하지 않겠습니다. 대신 마이그레이션할 때 놓치기 쉬운 것 하나만 짚습니다.

시크릿·컨피그맵 마이그레이션

dev에서 prd로 서비스를 옮길 때, 앱 코드보다 설정(Secret·ConfigMap)이 더 까다롭습니다. DB 접속 정보, 외부 API 키, 공통 환경 변수 등이 수십 개 키로 흩어져 있는데, 하나라도 빠지면 앱이 안 뜨거나 런타임에 죽습니다.

실제로 공통 설정에만 25개의 키가 있었고, 이를 하나하나 일치 검증하며 운영 네임스페이스로 옮겼습니다. 운영용은 dev와 분리된 별도 DB·시크릿을 새로 만들어 환경을 격리했습니다.

교훈: 마이그레이션의 실수는 대부분 코드가 아니라 설정 누락에서 납니다. 키 개수와 값을 양쪽에서 대조하는 체크리스트를 만들어두면 사고가 줄어듭니다.


2. 문제 ① 클러스터 밖 시스템을 서비스처럼 쓰기

상황

외부 API 하나가 클러스터 (예: 192.168.1.89:8000)에서 돌고 있었습니다. 클러스터 안의 앱들은 이걸 일반 쿠버네티스 서비스처럼 이름으로 호출하고 싶은데, 이 API는 Pod가 아니라서 일반적인 방법으로는 Service를 만들 수 없습니다.

쿠버네티스 Service는 보통 selector(라벨로 Pod를 고르는 규칙)로 대상 Pod를 찾습니다. 그런데 외부 API는 Pod가 아니니 고를 라벨이 없죠.

해결: selector 없는 Service + 수동 Endpoints

selector 없이 Service를 만들고, 그 Service가 가리킬 주소(외부 API의 IP·포트)를 Endpoints로 직접 지정하는 패턴을 씁니다.

apiVersion: v1
kind: Service
metadata:
  name: deeptax-api
  namespace: t4x-system
spec:
  ports:
    - port: 8000
      targetPort: 8000
---
apiVersion: v1
kind: Endpoints
metadata:
  name: deeptax-api          # Service와 같은 이름이어야 연결됨
  namespace: t4x-system
subsets:
  - addresses:
      - ip: 192.168.1.89      # 외부 API 주소
    ports:
      - port: 8000

이러면 클러스터 안의 앱들은 deeptax-api:8000이라는 내부 이름으로 외부 API를 호출할 수 있습니다. 외부 시스템이 마치 클러스터 안 서비스처럼 추상화되는 것이죠. 나중에 외부 API 주소가 바뀌어도 Endpoints만 고치면 되니, 앱 코드는 손대지 않아도 됩니다.

7편에서 예고한 “ArgoCD가 건드리면 안 되는 리소스”가 바로 이 수동 Endpoints입니다. ArgoCD가 이를 prune하지 않도록 Prune=false·IgnoreExtraneous annotation을 붙여 보호합니다.


3. 문제 ② 레거시 대역과의 비대칭 라우팅

상황

클러스터(10.0.12.0/24)의 앱이 레거시 대역(192.168.1.0/24)의 DB를 호출하는데, 연결이 간헐적으로 실패했습니다. 핑은 되는데 실제 통신이 안 되는 묘한 증상이었죠.

원인은 비대칭 라우팅(asymmetric routing)이었습니다. 요청은 A 경로로 나갔는데 응답은 B 경로로 돌아오면서, 방화벽이 “이 응답은 내가 보낸 요청에 대한 게 아닌데?”라고 판단해 차단한 겁니다. 출발 경로와 도착 경로가 달라서 생기는 전형적인 문제입니다.

해결: OPNsense Outbound SNAT

방화벽(OPNsense)에서 Outbound SNAT 규칙을 추가했습니다. 클러스터 대역(10.0.12.0/24)에서 레거시 대역(192.168.1.0/24)으로 나가는 트래픽의 출발지 주소를, 레거시가 응답을 되돌려 보낼 수 있는 주소로 바꿔준 것입니다.

[규칙 개념]
출발: 10.0.12.0/24  →  목적지: 192.168.1.0/24
동작: 출발지를 OPNsense 인터페이스 주소로 SNAT

이렇게 하면 레거시 시스템이 보기에 트래픽이 방화벽에서 온 것처럼 보이고, 응답도 같은 경로로 돌아와 대칭이 맞춰집니다. 양방향 통신이 안정화됐습니다.

교훈: 핑은 되는데 통신이 안 되면 경로(라우팅)를 의심하세요. 특히 서로 다른 네트워크 대역을 방화벽 너머로 연결할 때 비대칭 라우팅은 흔한 함정입니다.


4. 문제 ③ 마이크로서비스 503 디버깅

상황

API 게이트웨이(Spring Cloud Gateway)를 통해 특정 서비스를 호출하면 503 Service Unavailable이 떴습니다. 게이트웨이는 살아 있는데 다운스트림 서비스를 못 찾는 상황이었죠.

체계적 진단 순서

503 같은 문제는 막연히 보면 답이 안 나옵니다. 경로를 따라 한 단계씩 좁혀갑니다.

  1. Pod 상태 확인 — 대상 서비스의 Pod가 Running인가?
kubectl get pods -n t4x-system
  1. Pod 로그 확인 — 떠 있어도 내부에서 죽고 있진 않은가?
kubectl logs -n t4x-system <pod-name>
  1. 서비스 디스커버리 확인 — 게이트웨이가 찾는 이름과 실제 Service 이름이 맞는가?
  2. 외부 의존성 확인 — 그 서비스가 의존하는 DB·외부 API가 정상인가?

진짜 원인: ConfigMap 키 누락

추적해보니 대상 서비스 Pod가 CreateContainerConfigError로 아예 못 뜨고 있었습니다. 원인은 ConfigMap에 특정 키가 없어서였습니다.

이 서비스는 원래 서비스 디스커버리(Eureka) 설정을 기대하는 코드였는데, 우리 환경은 Eureka를 안 씁니다. 그런데 코드가 해당 설정 키를 필수로 찾으니, 키가 없어 컨테이너 생성이 실패한 것이죠.

해결: 쓰지 않더라도 코드가 찾는 키를 더미 값으로 채워 넣었습니다.

# Eureka 미사용이지만 코드가 키를 요구 → 더미 값으로 충족
eureka.client.serviceUrl.defaultZone: "http://localhost:8761/eureka/"

Eureka 서버는 없지만, 키가 존재하니 컨테이너는 정상 생성되고, 실제 Eureka 호출은 일어나지 않으니 동작에도 문제가 없습니다. Pod가 뜨자 503도 사라졌습니다.

교훈: 503은 결과일 뿐 원인이 아닙니다. 게이트웨이 → 서비스 → Pod → 설정 → 의존성 순으로 경로를 따라가면 진짜 원인(여기서는 설정 키 누락)에 도달합니다.


5. 완성된 전체 그림

시리즈 전체를 통해 우리가 만든 것을 한 장으로 모으면 이렇습니다.

[외부 클라이언트]
   │ HTTPS (*.prd.dztechwill.com 와일드카드)
   ▼
[OPNsense + Caddy]  ── TLS 종단 + Unbound DNS
   │ HTTP
   ▼
[MetalLB VIP .200] → [Ingress-NGINX]  ── Host 헤더 라우팅
   │
   ├─ argocd.prd...    → ArgoCD (배포 자동화)
   ├─ dash.prd...      → Headlamp (대시보드)
   ├─ s3.prd...        → MinIO (오브젝트 스토리지)
   └─ (실서비스 도메인) → 마이크로서비스 (t4x-system)
                            │
                            ├─ 내부 서비스끼리 통신
                            ├─ deeptax-api → 외부 API (수동 Endpoints)
                            └─ DB 호출 → [OPNsense SNAT] → 레거시(192.168.1.x)
  • 배포: Git push → ArgoCD가 클러스터에 자동 동기화
  • 저장: 영속 데이터는 NFS(MinIO), 일반 PV는 local-path
  • 노출: 도메인 하나 추가로 새 서비스 공개
  • 연동: 클러스터 밖 외부 API·레거시 DB까지 매끄럽게 연결

흩어진 조각들이 하나의 살아 있는 시스템이 됐습니다.


6. 시리즈를 마치며

0편에서 “쿠버네티스가 무엇이고 우리 회사에 필요한가”를 물었고, 9편에 걸쳐 그 답을 직접 만든 클러스터로 증명했습니다. 되짚어보면:

  • 00. 개념과 판단 — 쿠버네티스란 무엇이고, 왜 중소기업에 K3s인가
  • 01. 아키텍처 설계 — 4노드 구성과 IP 정책
  • 02. OS 준비 — swap·시간·커널·sysctl 토대
  • 03. K3s 부트스트랩 — 마스터·워커·역할 분리
  • 04. 스토리지·로드밸런서 — local-path·MetalLB
  • 05. Ingress·TLS — 외부 노출 경로 완성
  • 06. 대시보드 — Headlamp로 시각화
  • 07. GitOps — ArgoCD 도입과 판단
  • 08. 오브젝트 스토리지 — MinIO·NFS
  • 09. 워크로드·트러블슈팅 — 실전 문제 해결

이 시리즈가 전하고 싶었던 것

기술 단계를 나열하는 것보다 중요한 건 판단의 근거였습니다. 왜 K3s인지, 왜 단일 마스터인지, 왜 TLS를 Caddy에서 끝내는지, ArgoCD가 정말 필요한지 — 각 선택에는 중소기업이라는 규모와 제약이 깔려 있었습니다. 그대로 따라 하기보다, 자기 환경의 규모·인력·서비스 수에 비춰 취사선택하는 데 이 기록이 도움이 되길 바랍니다.

쿠버네티스는 거대 기업만의 것이 아닙니다. K3s 같은 경량 도구와 명확한 설계 원칙이 있으면, 적은 인력의 중소기업도 충분히 운영할 수 있는 인프라입니다. 이 시리즈가 그 첫걸음에 보탬이 됐기를 바랍니다.

더 나아간다면

이 시리즈는 인프라 구축에 집중했습니다. 운영을 더 단단히 하고 싶다면 다음 주제로 확장할 수 있습니다.

  • 모니터링: Prometheus + Grafana + Loki로 메트릭·로그 관측
  • DB 고가용성: PostgreSQL Patroni 클러스터, Valkey(Redis) Sentinel
  • 백업: 3-2-1 원칙에 따른 자동 백업 체계
  • 마스터 HA: 단일 마스터를 3노드 컨트롤 플레인으로 확장

이전 글: 중소기업 쿠버네티스 구축 – 08. 오브젝트 스토리지: S3 호환 구축
— 시리즈 완결 —


MORE POSTS

다른 글 보기

guniq 인사이트 썸네일 — 이론으로 읽는 PSTA – 03. P-S-T-A 4계층은 WBS인가, 에픽-스토리인가
프로젝트 관리

이론으로 읽는 PSTA – 03. P-S-T-A 4계층은 WBS인가, 에픽-스토리인가

2026.08.06
guniq 인사이트 썸네일 — 이론으로 읽는 PSTA – 02. 애자일이라는 렌즈 — 선언문·스크럼·칸반이 말하는 “덜어내야 할 것들”
프로젝트 관리

이론으로 읽는 PSTA – 02. 애자일이라는 렌즈 — 선언문·스크럼·칸반이 말하는 “덜어내야 할 것들”

2026.08.05
guniq 인사이트 썸네일 — 중소기업 쿠버네티스 구축 – 09. 워크로드와 레거시 연동: 실전 트러블슈팅 (Headless Service·SNAT·503 디버깅)
테크 랩

중소기업 쿠버네티스 구축 – 09. 워크로드와 레거시 연동: 실전 트러블슈팅 (Headless Service·SNAT·503 디버깅)

2026.08.04

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.

무료 3분 자가진단

우리 회사, 자체 클라우드가 답일까?

AWS vs 자체 인프라 · 11개 항목 3분 체크