← 모든 글

Ingress를 통한 외부 트래픽 관리와 라우팅 - 클러스터의 똑똑한 관문 구축

Ingress의 HTTP/HTTPS 라우팅과 인증서 설정을 학습용 예제로 정리합니다. 기존 ingress-nginx 구성은 유지보수 종료 전 예시로 보존합니다.

CKA 준비 · 8 / 8편

이 글의 목차

학습 예시 안내: 본문의 상황과 출력은 개념 설명을 위한 예시로 정리했습니다. 당시 실행 여부는 확인되지 않았으며, 현재 환경에서의 클러스터 실습도 별도 검증이 필요합니다.

🎯 학습 목표

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가 필요

가정한 상황의 문제점:

  1. 포트 관리의 복잡성: NodePort 사용 시 30000-32767 포트 범위의 임의 포트 사용
  2. 비용 문제: 각 서비스마다 LoadBalancer가 필요 (클라우드에서는 비용 증가)
  3. SSL/TLS 관리: 각 서비스별로 인증서 관리가 복잡
  4. 도메인 관리: 여러 서비스에 대한 통일된 도메인 정책 부재
  5. 라우팅 로직: 경로나 호스트 기반의 세밀한 라우팅 불가능

이런 요구를 다루는 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. 1.Pod 생성과 관리 - 쿠버네티스의 기본 단위 이해하기
  2. 2.ReplicaSet과 Deployment로 Pod 관리하기 - 확장성과 가용성 확보
  3. 3.Service를 통한 Pod 네트워킹 - 안정적인 접근 경로 만들기
  4. 4.ConfigMap과 Secret으로 설정 관리하기 - 환경별 설정 분리
  5. 5.Pod 리소스 제한과 요청 설정 - 안정적인 클러스터 운영을 위한 리소스 관리
  6. 6.Liveness와 Readiness Probe 구성 - 헬스체크와 자동 복구
  7. 7.네임스페이스를 통한 리소스 격리와 다중 테넌시 - 팀별, 환경별 격리
  8. 8.Ingress를 통한 외부 트래픽 관리와 라우팅 - 클러스터의 똑똑한 관문 구축읽는 중