쿠버네티스 클러스터 내부 통신¶
한 줄 요약: 같은 클러스터 안의 파드끼리는 어느 노드에 있든 내부 주소로 서로 부를 수 있다. 하지만 이건 "길이 있다"는 뜻일 뿐이다. 토큰 검사, 막는 규칙, 브라우저용 공개 주소는 따로 챙겨야 한다.
📍 만난 상황¶
- 2026-11-09 16:04 — Next.js 기준 전체 아키텍처 페이지를 받은 직후였다. "Next.js 컨테이너 파드를 우리 쪽 노드에 띄우면 내부 통신에 문제없지?"라고 물었다. → 그날 일지
- hub-dev는 외부에서 열리지 않는다. 그래서 대시보드를 같은 곳에 두면 이 문제가 풀리는지 확인하고 싶었다.
- 답: 큰 방향은 맞다. 다만 정확한 말은 "노드"가 아니라 "같은 클러스터의 namespace"다. 확인할 점이 네 가지 남는다.
🧩 쉽게 말하면¶
큰 회사 사옥을 떠올리면 된다. 사옥 전체가 클러스터, 각 층이 노드, 직원이 파드, 부서가 namespace다.
같은 부서 직원도 여러 층에 흩어져 앉는다. 자리는 총무팀(쿠버네티스)이 빈자리를 보고 정한다. 그래도 사내 내선(내부 주소)으로 "기획팀 김 대리"를 부르면 어느 층이든 연결된다.
그래도 서버실에 들어가려면 출입증(토큰)이 있어야 한다. 보안팀이 특정 부서 간 통화를 막아 둘 수도 있다(NetworkPolicy). 외부 손님은 정문(공개 주소)으로만 들어온다.
이 구조가 없으면 앱마다 서버 IP를 외워 직접 연결해야 한다. 서버가 바뀔 때마다 설정을 고쳐야 한다.
📖 제대로 알기¶
구성 요소¶
| 용어 | 정체 | 누가 정하나 |
|---|---|---|
| 클러스터 | 쿠버네티스가 관리하는 서버 묶음 전체 | 플랫폼팀 |
| 노드 | 클러스터를 이루는 서버(기계) 한 대 | 플랫폼팀 |
| 파드 | 컨테이너를 실제로 돌리는 가장 작은 실행 단위 | 쿠버네티스가 노드에 배치 |
| namespace | 클러스터 안을 이름으로 나눈 구역(폴더 같은 것) | 우리가 고름 |
| Service | 파드 묶음에 붙는 고정 이름과 주소 | 우리가 만듦 |
- 파드는 자주 바뀐다. 재시작하면 새 파드가 생기고 IP도 바뀐다. 그래서 파드 IP를 직접 쓰지 않는다.
- Service(서비스: 바뀌는 파드들 앞에 놓인 고정 창구)가 이 문제를 푼다. 이름이 고정되고, 요청을 살아 있는 파드로 넘겨 준다.
내부 주소 (클러스터 DNS)¶
- 클러스터 안에는 DNS(이름 → 주소 변환기)가 있다. Service를 만들면 이름이 자동 등록된다.
- 모양:
서비스이름.namespace.svc.cluster.local - 같은 namespace 안이면
서비스이름만 써도 된다.
바깥과 이어지는 문¶
- Ingress / Gateway API(클러스터 정문: 바깥 요청을 안쪽 Service로 넘김). smartoffice가 쓰는 HTTPRoute는 Gateway API의 "이 주소는 이 서비스로" 규칙이다.
- 바깥(브라우저)은 내부 주소를 모른다. 공개 도메인과 정문 설정이 있어야 들어온다.
막는 장치¶
- NetworkPolicy(네트워크 정책: "이 namespace는 저 namespace로만 갈 수 있다" 같은 규칙).
- 서비스 메시(istio 등: 파드 사이 통신을 가로채 암호화·권한 검사를 하는 층).
- 둘 다 없으면 클러스터 안은 기본적으로 서로 다 통한다. 있으면 길을 열어 달라고 해야 한다.
⚙️ 어떻게 동작하나¶
- 배포: 우리가 "대시보드 namespace에 Next.js 파드 2개"를 요청한다.
- 배치: 쿠버네티스 스케줄러(배치 담당)가 남는 자원을 보고 노드를 고른다. 2개가 서로 다른 노드에 갈 수도 있다.
- 이름 부여: Service가 파드들 앞에 고정 이름을 붙이고 DNS에 등록한다.
- 찾기: Next.js 서버 코드가 매니저의 내부 주소를 부른다. DNS가 그 이름을 Service 주소로 바꾼다.
- 전달: 클러스터 네트워크가 노드 사이를 이어 준다. 다른 노드의 파드에도 그대로 닿는다.
- 규칙 검사: NetworkPolicy·서비스 메시가 있으면 여기서 통과 여부를 본다.
- 앱 검사: 매니저가 요청의 토큰을 보고 권한을 판정한다. 네트워크가 통해도 여기서 거절될 수 있다.
flowchart LR
B["이용자 브라우저"] -->|"① 공개 도메인"| G["정문<br/>(Gateway)"]
G --> N["Next.js 파드<br/>(대시보드 ns)"]
N -->|"② 내부 주소 + 토큰"| M["dhub2-manager<br/>(매니저 ns)"]
N -->|"② 내부 주소"| P[("PostgreSQL<br/>(대시보드 ns)")]
B -.->|"③ 로그인 화면<br/>공개 주소"| M
②만 내부 통신이다. ①과 ③은 브라우저가 직접 가는 길이라 공개 주소가 필요하다. 특히 ③(로그인)을 놓치기 쉽다.
🧪 예시¶
- 예시 1 · 일상에 빗대어: 사옥 10개 층에 직원 300명이 있다. 기획팀 5명은 3층에 2명, 7층에 3명 앉아 있다. 내선 "기획팀-대표번호"로 걸면 그중 받을 수 있는 사람에게 연결된다. 하지만 외부 손님은 내선을 걸 수 없다. 정문 안내 데스크(공개 주소)를 거쳐야 한다.
- 예시 2 · 실제로는: 대시보드 앱의 환경 설정이다(이름은 자리표시).
# ① 서버끼리: 클러스터 안 주소
MANAGER_INTERNAL_URL=http://<매니저서비스>.<매니저ns>.svc.cluster.local
# ② 같은 namespace의 DB는 서비스 이름만
DATABASE_HOST=<postgres서비스>
# ③ 로그인 발급처: 브라우저가 여는 공개 주소
OIDC_ISSUER=https://<매니저 공개 도메인>
# ④ 대시보드 자신의 공개 주소(로그인 후 돌아올 곳)
APP_PUBLIC_URL=https://<대시보드 공개 도메인>
issuer(발급처)는 공개 주소로 찍힌다. 검증할 때 이 값과 같아야 해서 내부 주소로 바꿔 쓰면 안 된다.
- ④ 로그인 후 브라우저가 돌아올 주소다. 브라우저 기준이라 역시 공개 주소다.
⚖️ 비교 · 흔한 오해¶
무엇을 나누는 단위인가¶
| 단위 | 나누는 것 | 우리가 고르나 |
|---|---|---|
| 클러스터 | 완전히 다른 쿠버네티스 묶음 | 예(어느 클러스터에 배포할지) |
| 노드 | 물리 기계 | 보통 아니요 |
| namespace | 이름·권한·설정의 구역 | 예 |
오해 1: "우리 쪽 노드에 띄운다"¶
- 실제: 노드는 고르지 않는다. 고르는 건 클러스터와 namespace다.
- 왜 그렇게 생각하기 쉬운가: 서버 한 대에 프로그램을 설치하던 경험 때문이다. "가까운 기계에 두면 통한다"는 물리적 그림이 남아 있다. 쿠버네티스에서는 같은 클러스터면 노드가 달라도 통한다.
오해 2: "내부망이면 다 통한다"¶
- 실제: 통하는 건 네트워크 층뿐이다. 권한은 앱이 따로 본다.
- 매니저는 내부 요청에도 토큰을 요구한다.
- NetworkPolicy·서비스 메시가 namespace 사이를 막아 둘 수 있다.
- 브라우저가 가는 길(화면, 로그인)은 내부망이 아니다.
- 왜 그렇게 생각하기 쉬운가: 예전 사내망은 "안에 들어오면 믿는다"는 방식이 많았다. 지금은 안에서도 매번 확인(제로 트러스트)하는 쪽이 기본이다.
🛠️ 실무에서는¶
- 쓰면 좋을 때: 앱이 플랫폼 API·DB를 서버끼리 부르고, 플랫폼이 외부에 열려 있지 않을 때.
- 배포 전 체크리스트
- 어느 클러스터, 어느 namespace에 배포하는지 플랫폼팀과 정했다.
- 대시보드 ns → 매니저 ns 통신이 NetworkPolicy·istio에서 허용되는지 물었다.
- 서버가 쓸 토큰(서비스 계정 또는 사용자 토큰 교환)을 준비했다.
- 대시보드 공개 도메인과 정문 규칙(HTTPRoute 등)을 신청했다.
- 매니저 로그인 화면이 이용자 브라우저에서 열리는지 확인했다.
- 안 될 때 먼저 볼 것
- 이름을 못 찾음 → 서비스 이름·namespace 오타, DNS 주소 형태.
- 연결 시간 초과 → NetworkPolicy·서비스 메시 차단.
- 401·403 → 네트워크는 통했다. 토큰·권한 문제다.
- 로그인만 실패 → issuer 불일치, 공개 주소 접근 불가.
❓ 자주 묻는 질문¶
- Q. 같은 노드에 두면 더 빠르지 않나? A. 약간 빠를 수 있지만 보통 신경 쓰지 않는다. 노드 고정은 장애에 약해져서 특별한 이유가 있을 때만 한다.
- Q. namespace가 다르면 서로 못 부르나? A. 기본은 부를 수 있다. 막는 규칙이 있을 때만 막힌다. 주소에 namespace를 넣어 부르면 된다.
- Q. 클러스터가 다르면? A. 내부 주소로는 안 된다. 그때는 공개 주소나 클러스터 사이 전용 연결이 필요하다.
- Q. 내부 통신이면 HTTPS가 필요 없나? A. 클러스터 정책에 따른다. 서비스 메시가 자동으로 암호화하기도 한다. 플랫폼팀 규칙을 따른다.
🔭 더 깊이 보기¶
- Service의 종류(ClusterIP, NodePort, LoadBalancer)는 어떻게 다른가? — 내부 전용과 외부 공개가 어떻게 갈리는지 알 수 있다.
- NetworkPolicy는 어떻게 쓰나? — "우리 ns에서 매니저로 가는 길을 열어 주세요"를 정확히 요청할 수 있다.
- 제로 트러스트란? — 내부망에서도 토큰을 요구하는 이유의 배경이다.
- 관련 주제: OIDC 로그인 흐름 · 프론트엔드와 백엔드 서버 구조 · Docker Compose 로컬 개발환경
📚 참고 자료¶
- 서비스 (Kubernetes 한국어 문서) — 파드 앞에 고정 이름을 붙이는 Service 개념 · 링크
- 서비스 및 파드용 DNS (Kubernetes 한국어 문서) —
svc.cluster.local주소가 만들어지는 규칙 · 링크 - 네트워크 정책 (Kubernetes 한국어 문서) — namespace 사이 통신을 막고 여는 규칙 · 링크
🗓️ 이력¶
- 2026-11-09: Next.js 파드를 "우리 쪽 노드"에 띄우면 내부 통신이 되는지 물음. 노드 대신 클러스터·namespace, 토큰·공개 주소가 여전히 필요함을 정리 → 일지
🕸️ 연결된 주제¶
바로 이어진 주제 6개전체 지도에서 보기 →