이번 강의는 “Ingress를 왜 쓰는가?”를 서비스(Service)부터 역순으로 쌓아 올리며 설명합니다. 결론부터 말하면:
- Service는 “클러스터 내부에서 Pod 집합을 안정적으로 노출(가상 VIP + L4 로드밸런싱)”하는 기본 단위이고
- Ingress는 “HTTP(S) 트래픽을 URL/Host 기반으로 여러 Service로 라우팅하고, TLS(SSL)까지 한 곳에서 처리”하는 L7 진입점입니다.
1) 서비스부터 다시: Pod를 외부에 노출하려면?
회사에 온라인 스토어 my-online-store.com를 운영한다고 해봅시다.
1.1 내부 의존성: DB는 ClusterIP로
앱은 MySQL이 필요합니다.
- MySQL Pod(Deployment/StatefulSet 등)
- MySQL Service(ClusterIP) → 클러스터 내부에서만 접근
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
type: ClusterIP
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
앱 Pod는 mysql-service라는 이름(DNS)으로 DB에 붙습니다.
1.2 외부 노출: NodePort로 시작하면?
웹앱을 외부에 열기 위해 Service를 NodePort로 만들면:
- 노드의 고정 포트 범위(보통 30000~32767) 중 하나(예: 30080)가 열립니다.
- 사용자는
http://<노드IP>:30080로 접속합니다.
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080
이 구성은 동작은 합니다. 트래픽이 늘면 Deployment replica를 늘리고, Service가 Pod로 분산합니다.
2) 운영을 생각하면 NodePort/LoadBalancer만으로는 “관리 포인트”가 폭증한다
2.1 “IP를 치게 할 순 없으니” DNS를 붙임
사용자가 IP 대신 my-online-store.com으로 들어오게 DNS를 구성합니다.
하지만 여전히 포트가 남습니다:
my-online-store.com:30080
2.2 “포트도 숨기자” → 앞단 프록시/로드밸런서가 필요
NodePort는 일반적으로 80/443 같은 “표준 포트”를 직접 쓰기 어렵습니다(고포트만 할당).
그래서 보통:
- 외부 80 → 내부 노드의 30080으로 프록시하는 별도 프록시/로드밸런서가 필요해집니다.
- 온프레미스라면 HAProxy/Nginx/하드웨어 LB 같은 걸 앞단에 둡니다.
2.3 클라우드라면? Service type=LoadBalancer
GCP 같은 환경에서는 type: LoadBalancer를 쓰면:
- Kubernetes가 기본적으로 NodePort와 비슷한 구성(노드 포트 오픈)을 하고
- 클라우드에 외부 LB 프로비저닝 요청을 보내서
- 외부 IP를 가진 로드밸런서를 자동으로 만들어 줍니다.
그러면 사용자는:
my-online-store.com→ LB 외부 IP → Service → Pod
여기까지는 “단일 웹앱”이면 괜찮습니다.
3) 문제가 커지는 지점: 서비스가 늘어날수록 외부 LB/프록시가 계속 늘어난다
회사가 성장해서 /watch 같은 영상 서비스가 추가됐다고 해봅시다.
- web 앱(기존)
- video 앱(신규)
각각을 type: LoadBalancer로 노출하면:
- LB가 2개가 되고
- 서비스가 늘수록 LB가 계속 늘고(=비용 증가)
- “URL 경로에 따라 다른 백엔드로 보내기” 같은 라우팅은 LB를 매번 재설정해야 합니다.
여기에 TLS(HTTPS)까지 붙이면 더 복잡해집니다.
- 앱마다 TLS를 구현하게 하면 팀별 방식이 달라지고 유지보수 지옥
- LB/프록시 레벨에서 TLS termination을 하려면 설정이 계속 커짐
“이런 L7 라우팅/SSL/규칙 관리를 쿠버네티스 안에서, YAML로, 일관되게 관리할 수 없을까?”
그게 Ingress의 출발점입니다.
4) Ingress의 정체: “클러스터 내부에 두는 L7 진입점” + 규칙 리소스
Ingress는 크게 2개로 나뉩니다.
4.1 Ingress Controller (구현체)
Ingress는 “개념/규격”이고, 실제 트래픽을 처리하는 제품이 필요합니다.
- NGINX Ingress, GCE Ingress, HAProxy, Traefik, Contour, Istio Gateway 등
중요 포인트:
- 쿠버네티스는 Ingress Controller를 기본으로 설치해주지 않습니다.
- Ingress 리소스(YAML)만 만들어서는 아무 일도 안 일어납니다.
- 먼저 “컨트롤러”를 클러스터에 배포해야 합니다.
4.2 Ingress Resource (규칙)
Ingress 리소스는 “이 Host/Path로 들어오면 어떤 Service로 보낼지”를 정의하는 규칙 모음입니다.
5) NGINX Ingress Controller를 예로: 뭐가 필요하나?
강의 흐름(최소 구성)은 아래 4종 세트입니다.
- Deployment: nginx ingress controller Pod
- Service: 외부에서 ingress controller로 들어올 진입점(NodePort 또는 LoadBalancer)
- ConfigMap: nginx 동작 옵션(빈 ConfigMap이라도 미리 만들어두면 확장 쉬움)
- ServiceAccount + RBAC(Role/ClusterRole, Binding): Ingress 리소스/Service/Endpoint 등을 watch할 권한
실무에서는 Helm으로 설치하는 경우가 많지만, 개념상 위 구성요소가 핵심입니다.
컨트롤러가 하는 일은 단순 “nginx 띄우기”가 아닙니다.
- Kubernetes API를 watch
- Ingress 리소스가 추가/변경되면 nginx 설정을 자동으로 생성/리로드
- TLS 시크릿, 서비스 엔드포인트 변화를 반영
6) Ingress Resource 기본 형태 (networking.k8s.io/v1)
6.1 단일 백엔드(모든 트래픽 → 한 서비스)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-web
spec:
ingressClassName: nginx
defaultBackend:
service:
name: web-service
port:
number: 80
- rules 없이 defaultBackend만 있으면 “모든 요청이 web-service로” 갑니다.
6.2 경로 기반 라우팅: /는 web, /watch는 video
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-store
spec:
ingressClassName: nginx
rules:
- host: my-online-store.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /watch
pathType: Prefix
backend:
service:
name: video-service
port:
number: 80
- rules(Host) → 그 아래 paths(Path)
즉, Host 단위로 큰 갈래를 나누고 그 안에서 Path로 세부 분기합니다.
6.3 호스트 기반 라우팅: wear. vs watch.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-host-split
spec:
ingressClassName: nginx
rules:
- host: wear.my-online-store.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wear-service
port:
number: 80
- host: watch.my-online-store.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: video-service
port:
number: 80
- DNS는 여러 레코드를 같은 Ingress 진입점(LB IP)으로 가리키게 만들 수 있습니다.
- Ingress는
Host헤더로 어떤 rule을 적용할지 결정합니다.
7) “Default Backend(404)”는 왜 보이나?
kubectl describe ingress를 보면 종종 default backend 이야기가 나옵니다.
- Ingress rules/path에 매칭이 안 되면 어디로 보낼지 필요합니다.
- 보통은 “404 페이지 서비스”를 하나 두고 그쪽으로 보내도록 구성합니다.
컨트롤러 설치 시 기본 404 백엔드가 함께 배포되는 경우도 있고, 직접 만들기도 합니다.
8) Kubernetes 버전 변화 포인트: kubectl로 Ingress를 imperative하게 만들 수 있다(1.20+)
강의에 나온 형식처럼, (환경에 따라) 아래처럼 만들 수 있습니다.
kubectl create ingress ingress-test \
--class=nginx \
--rule="wear.my-online-store.com/wear*=wear-service:80"
핵심은:
- “Ingress도 결국 Kubernetes 리소스라서”
- kubectl로 선언적(YAML) / 명령형(Imperative) 모두 가능하다는 점입니다.
9) NGINX Ingress에서 자주 만나는 함정: rewrite-target
문제 상황:
- 사용자가 Ingress로
http://<ingress>/watch로 접속 - Ingress가 backend인
watch-service로 보냄
그런데 rewrite를 안 하면 보통 요청 URI가 그대로 전달됩니다.
/watch→ 백엔드에도/watch로 전달됨
(즉http://watch-service/watch)
하지만 watch 앱은 루트(/)만 제공하고 /watch 라우트가 없다면:
- 404 Not Found
9.1 해결: nginx.ingress.kubernetes.io/rewrite-target
Ingress에서 /watch로 들어온 요청을 백엔드에 /로 바꿔서 보내고 싶다면:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: my-online-store.com
http:
paths:
- path: /watch
pathType: Prefix
backend:
service:
name: watch-service
port:
number: 80
- path: /wear
pathType: Prefix
backend:
service:
name: wear-service
port:
number: 80
이렇게 하면 의도는:
http://<ingress>/watch→http://watch-service/http://<ingress>/wear→http://wear-service/
즉, “Ingress에서 라우팅에만 쓰는 prefix(/watch, /wear)를 백엔드로 전달하지 않도록” 하는 옵션입니다.
9.2 정규식 기반 예시(개념)
강의 후반의 replace("/something(/|$)(.*)", "/$2") 같은 형태는 “캡처 그룹으로 뒤쪽 경로를 살려서 전달”하려는 패턴입니다.
예:
/something/abc→/abc
컨트롤러/버전에 따라 “정규식 path 지원 여부”나 “annotation 옵션”이 달라질 수 있으니, 실습에서는 해당 컨트롤러 문서 기준으로 확인하는 습관이 좋습니다.
10) Ingress를 써도 “외부로 노출”은 한 번은 해야 한다
Ingress를 쓰면 모든 것이 해결되는 것처럼 보이지만, 외부 트래픽이 Ingress Controller까지 들어와야 합니다.
그래서 보통:
- Ingress Controller Service를 NodePort 또는 LoadBalancer로 1회 노출
- 그 이후 “새 서비스 추가/라우팅 변경/TLS 추가”는 Ingress 리소스(YAML)만 바꿔서 해결
즉, 핵심 가치는:
- 외부 LB/프록시를 서비스마다 늘리는 대신
- Ingress Controller 하나에 규칙을 모아 관리하는 것입니다.
11) 정리: Service vs Ingress, 언제 뭘 쓰나?
Service
- Pod 집합을 안정적으로 노출(ClusterIP/NodePort/LoadBalancer)
- L4 중심(TCP/UDP) 관점
- “클러스터 내부/외부”를 연결하는 기본 빌딩 블록
Ingress
- HTTP(S) 트래픽을 Host/Path 기반으로 여러 Service로 라우팅
- TLS(HTTPS) termination을 중앙집중식으로 처리 가능
- 규칙이 Kubernetes 리소스로 관리되므로 배포/형상관리(YAML) 친화적
- 단, Ingress Controller 설치가 선행되어야 함
실습에서 바로 보는 커맨드
# ingress 리소스 보기
kubectl get ingress -A
kubectl describe ingress <name>
# ingress controller(예: nginx) 배포 여부 확인(환경마다 라벨/이름 다름)
kubectl -n ingress-nginx get all
kubectl -n kube-system get pods | grep -i ingress
# rewrite나 라우팅 문제 확인용
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller
Practice Test URL: https://uklabs.kodekloud.com/topic/practice-test-cka-ingress-networking-1-2/
Practice Test URL: https://uklabs.kodekloud.com/topic/practice-test-cka-ingress-networking-2-2/
'CKA' 카테고리의 다른 글
| Network - 정리(2) (0) | 2026.01.05 |
|---|---|
| Network - Gateway API (0) | 2026.01.05 |
| Network - Service Networking (0) | 2026.01.05 |
| Network - IPAM(IP Address Management) (0) | 2026.01.05 |
| Network - Pod Networking & CNI (1) | 2026.01.05 |