학습 예시 안내: 본문의 상황과 출력은 개념 설명을 위한 예시로 정리했습니다. 당시 실행 여부는 확인되지 않았으며, 현재 환경에서의 클러스터 실습도 별도 검증이 필요합니다.
🎯 학습 목표
2026-09-29 보완: 이 글은 2025년에 작성한 Ingress 학습 기록입니다. 여기서 사용한 Kubernetes 커뮤니티의 ingress-nginx는 2026-03-24 유지보수가 종료되어 새 보안 수정이 제공되지 않습니다. 아래 설치 버전은 당시 예시로 보존하며 현재 신규 설치를 권하지 않습니다. 새 구성은 지원 중인 Ingress Controller 또는 Gateway API 구현체를 검토해야 합니다. Ingress API 자체가 제거됐다는 의미는 아닙니다. 유지보수 종료 안내
이 글을 통해 다음을 학습할 수 있습니다:
- Ingress의 개념과 Service와의 차이점 이해
- Ingress Controller 설치와 설정 방법
- 경로 기반, 호스트 기반 라우팅 구성
- SSL/TLS 인증서 관리와 HTTPS 설정
- 고급 트래픽 관리 (로드밸런싱, 헬스체크, Rate Limiting)
- 실제 운영 환경에서의 Ingress 패턴과 모범 사례
- CKA 준비 과정에서 연습할 Ingress 관련 문제 해결
📝 앞선 개념과 이번 예제
지난 글에서는 네임스페이스를 이용한 팀별·환경별 구성 예제를 다뤘습니다. 이번에는 외부 HTTP/HTTPS 요청을 여러 서비스로 전달하는 상황을 가정합니다.
예제에서 가정한 환경
# 네임스페이스별 서비스들 확인
kubectl get services --all-namespaces
# 기존 네임스페이스 구성 확인
kubectl get namespaces --show-labels
가정한 문제 상황
여러 애플리케이션을 외부에 노출할 때 포트, 도메인과 인증서를 각각 관리해야 하는 상황을 가정해 봅니다.
# 현재 서비스들을 외부에 노출하는 방법들
kubectl get services -o wide
# NodePort 방식의 문제점 확인
kubectl expose deployment web-app --type=NodePort --port=80 -n frontend-team
# web-app NodePort 10.96.1.100 <none> 80:32547/TCP 1m
# LoadBalancer 방식의 문제점
kubectl expose deployment api-server --type=LoadBalancer --port=8080 -n backend-team
# 각 서비스마다 별도의 로드밸런서 IP가 필요
가정한 상황의 문제점:
- 포트 관리의 복잡성: NodePort 사용 시 30000-32767 포트 범위의 임의 포트 사용
- 비용 문제: 각 서비스마다 LoadBalancer가 필요 (클라우드에서는 비용 증가)
- SSL/TLS 관리: 각 서비스별로 인증서 관리가 복잡
- 도메인 관리: 여러 서비스에 대한 통일된 도메인 정책 부재
- 라우팅 로직: 경로나 호스트 기반의 세밀한 라우팅 불가능
이런 요구를 다루는 Ingress의 라우팅 구성 방법을 살펴보겠습니다.
🚪 Ingress의 개념과 작동 원리
Ingress란?
Ingress는 클러스터 외부에서 내부 서비스로 HTTP/HTTPS 라우팅을 제공하는 API 객체입니다. L7 계층에서 작동하며, 클러스터의 ‘교통 관제사’ 역할을 합니다.
외부 클라이언트 요청 (HTTP/HTTPS)
↓
Load Balancer (단일 진입점)
↓
Ingress Controller (e.g., NGINX) ← Ingress Rules 참조
↙ ↘
Service A Service B
↓ ↓
Pod A Pod B
| 구분 | Service (LoadBalancer) | Ingress |
|---|---|---|
| 레이어 | L4 (전송 계층) | L7 (응용 계층) |
| 프로토콜 | TCP, UDP | HTTP, HTTPS |
| 라우팅 | 포트 기반 | 경로, 호스트 기반 |
| SSL 지원 | 제한적 | 완전 지원 (TLS Termination) |
| 비용 | 서비스당 비용 발생 | 단일 진입점으로 비용 효율적 |
첫 번째 Ingress Controller 설치
아래는 당시 사용한 커뮤니티 ingress-nginx 설치 명령입니다. 현재 실습 환경에 그대로 적용하지 않고 버전과 컨트롤러 선택부터 다시 검토해야 합니다.
# 1. NGINX Ingress Controller 설치 (클라우드 환경 기준)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
# 2. Ingress Controller가 준비될 때까지 대기
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=120s
# 3. 외부 IP 확인 (클라우드 환경에서 EXTERNAL-IP가 할당됨)
kubectl get services -n ingress-nginx
기본 Ingress 생성과 테스트
# 테스트용 서비스 생성
kubectl create deployment web-app --image=nginx -n frontend-team
kubectl expose deployment web-app --port=80 -n frontend-team
# basic-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
namespace: frontend-team
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app
port:
number: 80
# Ingress 적용 및 테스트
kubectl apply -f basic-ingress.yaml
EXTERNAL_IP=$(kubectl get services -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -H "Host: myapp.example.com" http://$EXTERNAL_IP
🛣️ 고급 라우팅 패턴
1. 경로 기반 라우팅 (Path-based Routing)
하나의 도메인에서 경로에 따라 다른 서비스로 라우팅합니다.
정규식 경로는 ingress-nginx의 use-regex 설정과 ImplementationSpecific을 사용합니다. 표준 Prefix 경로와는 구분해야 합니다. 기존 컨트롤러의 rewrite 예제
# path-based-routing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
rules:
- host: mycompany.com
http:
paths:
- path: /app(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: frontend-service
port: { number: 80 }
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port: { number: 8080 }
2. 호스트 기반 라우팅 (Host-based Routing)
서브도메인별로 다른 서비스로 라우팅합니다.
# host-based-routing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-based-ingress
namespace: production
spec:
ingressClassName: nginx
rules:
- host: www.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: main-website
port: { number: 80 }
- host: api.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port: { number: 8080 }
🔐 SSL/TLS 인증서 관리
1. 기본 TLS 설정
openssl로 자체 서명 인증서를 생성하고, 이를 Secret으로 만들어 Ingress에 적용합니다.
# 1. 자체 서명 인증서 생성
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=secure.mycompany.com" \
-addext "subjectAltName=DNS:secure.mycompany.com"
# 2. 쿠버네티스 Secret 생성
kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n production
# 3. TLS Ingress 생성
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.mycompany.com
secretName: tls-secret
rules:
- host: secure.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-app-service
port: { number: 80 }
EOF
2. Cert-Manager를 통한 자동 인증서 관리 (Let’s Encrypt)
Cert-Manager를 설치하면 Let’s Encrypt로부터 무료 TLS 인증서를 자동으로 발급받고 갱신할 수 있습니다.
아래 v1.13.0은 기존 기록의 버전입니다. 새 설치에는 cert-manager 공식 설치 안내에서 지원 버전과 Kubernetes 호환성을 확인해야 합니다. 실제 발급에는 소유한 도메인, DNS, 외부에서 접근 가능한 검증 경로가 필요합니다.
# 1. Cert-Manager 설치
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# 2. ClusterIssuer 생성 (Let's Encrypt 발급자)
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx
EOF
# 3. Ingress에 어노테이션 추가
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-tls-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- www.mycompany.com
secretName: mycompany-tls # 이 Secret은 Cert-Manager가 자동으로 생성/관리
rules:
- host: www.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: main-service
port: { number: 80 }
EOF
⚙️ 고급 Ingress 기능
1. Rate Limiting과 보안 설정
어노테이션을 통해 특정 경로의 요청 수를 제한하거나 IP 기반 접근 제어를 할 수 있습니다.
# security-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: security-ingress
namespace: production
annotations:
# 컨트롤러 복제본별·클라이언트 IP별 초당 100개 요청 (별도 burst 허용)
nginx.ingress.kubernetes.io/limit-rps: "100"
# 같은 기준의 동시 연결 10개 제한
nginx.ingress.kubernetes.io/limit-connections: "10"
# IP 화이트리스트: 특정 IP 대역만 접근 허용
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,192.168.0.0/16"
# 기본 인증(Basic Auth)
nginx.ingress.kubernetes.io/auth-type: "basic"
nginx.ingress.kubernetes.io/auth-secret: "basic-auth-secret"
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
ingressClassName: nginx
rules:
- host: admin.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port: { number: 3000 }
2. 백엔드 준비 상태와 재시도
백엔드의 준비 상태는 Pod의 Readiness Probe로 관리하고, 아래는 요청 실패 시 재시도 조건을 지정하는 예제입니다. 기존에 적었던 upstream-health-check*, upstream-max-fails, upstream-fail-timeout은 커뮤니티 ingress-nginx의 지원 어노테이션으로 확인되지 않아 제거했습니다. 이 설정만으로 능동 헬스체크나 서킷 브레이커가 생기지는 않습니다. 지원 어노테이션
# health-check-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: health-check-ingress
namespace: production
annotations:
# 재시도 정책
nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_502 http_503"
nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3"
spec:
ingressClassName: nginx
rules:
- host: resilient-app.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: resilient-service
port: { number: 80 }
🏗️ 실전 시나리오: 마이크로서비스 아키텍처 Ingress
복잡한 마이크로서비스 환경에서 Ingress를 API Gateway처럼 활용하는 예시입니다.
# microservices-gateway.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: microservices-gateway
namespace: production
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.mycompany.com
- app.mycompany.com
secretName: microservices-tls
rules:
# 메인 웹 애플리케이션 (React, Vue 등)
- host: app.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port: { number: 80 }
# API Gateway 역할
- host: api.mycompany.com
http:
paths:
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port: { number: 8080 }
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port: { number: 8081 }
# 결제 API는 별도 보안 Ingress로 분리 관리 가능
- path: /payments
pathType: Prefix
backend:
service:
name: payment-service
port: { number: 8082 }
🔧 Ingress 트러블슈팅
502/503 Error:kubectl get endpointslices -l kubernetes.io/service-name=<service-name> -o yaml로 백엔드 주소와 Ready 상태를 확인. Ingress와 같은 네임스페이스를 지정하고 Controller 로그도 확인.404 Not Found:pathType,rewrite-target어노테이션, 서비스 이름/포트 번호가 정확한지 확인.- 인증서 오류:
kubectl describe certificate <cert-name>으로 Cert-Manager 발급 상태 확인. DNS 전파 문제일 수 있음. - Controller 미작동:
kubectl get pods -n ingress-nginx로 컨트롤러 상태 확인.describe명령으로 이벤트 로그 분석.
🎯 CKA 대비 연습 패턴
시험에서는 YAML을 직접 작성하기보다 명령형 커맨드로 빠르게 기본 구조를 만드는 것이 중요합니다.
- 기본 Ingress 생성:
kubectl create ingress my-ingress --class=nginx --rule="host.com/path*=service:port" - TLS 설정:
--rule="host.com/*=service:port,tls=my-secret"옵션을 추가. - YAML 수정:
--dry-run=client -o yaml > ingress.yaml명령으로 YAML 파일을 생성한 뒤vi로 세부 사항(어노테이션 등)을 수정.
🚀 고급 Ingress 패턴
- Blue-Green 배포: Ingress의
backend.service.name을 새 버전의 서비스 이름으로 변경하여 트래픽을 한번에 전환. - A/B 테스트 (Canary):
nginx.ingress.kubernetes.io/canary: "true"와canary-weight어노테이션을 사용하여 일부 트래픽만 새 버전으로 분기.
🎓 다음 학습 계획
이 글은 Ingress의 경로·호스트 기반 라우팅과 인증서 설정 예제를 정리했습니다. 다음 학습 주제는 애플리케이션 데이터를 영구적으로 보관하는 스토리지입니다.
다음 주제들
- 스토리지와 PersistentVolume 관리 - 애플리케이션 데이터의 영구 보관소 만들기
- RBAC과 보안 설정 - 사용자별로 세밀한 권한 부여하기
- 모니터링과 로깅 시스템 구축 - 클러스터와 애플리케이션의 건강 상태 관찰하기
다음 글에서는 Pod가 사라져도 데이터는 안전하게 지킬 수 있는 방법, 쿠버네티스 스토리지에 대해 깊이 있게 다뤄보겠습니다!
🔗 참고 자료
yellow.log · 2025.08.28에 작성 · 2026.09.29에 수정
CKA 준비 전체 8편
- 1.Pod 생성과 관리 - 쿠버네티스의 기본 단위 이해하기
- 2.ReplicaSet과 Deployment로 Pod 관리하기 - 확장성과 가용성 확보
- 3.Service를 통한 Pod 네트워킹 - 안정적인 접근 경로 만들기
- 4.ConfigMap과 Secret으로 설정 관리하기 - 환경별 설정 분리
- 5.Pod 리소스 제한과 요청 설정 - 안정적인 클러스터 운영을 위한 리소스 관리
- 6.Liveness와 Readiness Probe 구성 - 헬스체크와 자동 복구
- 7.네임스페이스를 통한 리소스 격리와 다중 테넌시 - 팀별, 환경별 격리
- 8.Ingress를 통한 외부 트래픽 관리와 라우팅 - 클러스터의 똑똑한 관문 구축읽는 중