k8s - Ingress

HelloPong·2025년 10월 26일

공부

목록 보기
38/39

Kubernetes Ingress란 무엇인가?

쿠버네티스 환경에서 외부 트래픽을 관리하는 Ingress의 개념과 동작 원리를 실습과 함께 알아봅니다.

📌 목차

  1. 시작하며: 헷갈리는 Nginx와 Ingress
  2. Ingress가 필요한 이유
  3. Ingress의 정체: 자동화된 Nginx
  4. Ingress 동작 원리
  5. 실습: Ingress vs 일반 Nginx 비교
  6. 결론

1. 시작하며: 헷갈리는 Nginx와 Ingress

쿠버네티스를 공부하다 보면 이런 의문이 생깁니다.

"URL 기반 라우팅은 Nginx로 할 수 있는 건데, Ingress는 왜 필요한 거지?"

결론부터 말하면: Ingress는 Nginx를 쿠버네티스 방식으로 자동 관리하는 도구입니다.

1.1 일반적인 Nginx 설정

전통적인 서버 환경에서는 Nginx를 다음과 같이 설정합니다:

# /etc/nginx/nginx.conf

server {
    listen 80;
    server_name myapp.com;

    location / {
        proxy_pass http://192.168.1.10:3000;  # Frontend 서버
    }

    location /api {
        proxy_pass http://192.168.1.11:8080;  # Backend 서버
    }
}

특징:

  • Nginx를 서버에 직접 설치
  • IP 주소를 직접 설정 파일에 기록
  • 서버 재시작 시에도 IP 주소 유지

2. Ingress가 필요한 이유

2.1 쿠버네티스의 동적 환경

쿠버네티스에서는 상황이 다릅니다:

# 오늘의 Pod IP
$ kubectl get pods -o wide
NAME              IP
frontend-aaa      10.244.1.5
backend-bbb       10.244.2.8

# Pod 재시작 후
$ kubectl get pods -o wide
NAME              IP
frontend-ccc      10.244.1.9  ← IP 변경!
backend-ddd       10.244.2.3  ← IP 변경!

문제점:

  • Pod IP는 재시작할 때마다 변경됨
  • 오토스케일링으로 Pod 개수가 증가/감소
  • 수동으로 Nginx 설정을 계속 업데이트해야 함 (불가능!)

2.2 NodePort의 한계

현재 일반적으로 사용하는 NodePort 방식:

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30080  # 30000-32767 범위

접속:

http://xxx.xxx.xxx.xxx:30080  # Frontend
http://xxx.xxx.xxx.xxx:30081  # Backend

문제점:

  • ❌ 포트 번호를 외워야 함 (30080, 30081...)
  • ❌ 서비스마다 다른 포트
  • ❌ 도메인 사용 어려움
  • ❌ SSL/HTTPS 설정이 복잡함

3. Ingress의 정체: 자동화된 Nginx

3.1 Ingress의 두 가지 컴포넌트

1. Ingress Resource (규칙)

# YAML로 작성하는 라우팅 규칙
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
spec:
  rules:
  - host: myapp.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: frontend-service  # ← Service 이름만!
            port:
              number: 80
      - path: /api
        backend:
          service:
            name: backend-service
            port:
              number: 8080

2. Ingress Controller (구현체)

  • 실제 트래픽을 처리하는 Pod
  • 내부에 Nginx (또는 Traefik, HAProxy 등) 포함
  • Ingress 규칙을 읽고 자동으로 Nginx 설정 생성

3.2 동작 방식 비교

전통적인 방식 (수동):

1. nginx.conf 파일 직접 편집
2. IP 주소 하드코딩
3. 변경 사항 있으면 수동으로 수정
4. nginx -s reload 실행

Ingress 방식 (자동):

1. Ingress YAML 작성 (Service 이름만 명시)
2. kubectl apply
3. Ingress Controller가 자동으로:
   - Service의 Pod IP 추적
   - Nginx 설정 생성
   - 변경 사항 자동 반영

4. Ingress 동작 원리

4.1 내부 구조

┌─────────────────────────────────────────┐
│  Ingress Controller Pod                 │
│                                         │
│  ┌───────────────────────────────────┐ │
│  │  Nginx (실제 프록시 서버)         │ │
│  │  - 요청 받기                      │ │
│  │  - 라우팅                         │ │
│  └───────────────────────────────────┘ │
│              ↑                          │
│  ┌───────────────────────────────────┐ │
│  │  Controller (자동화 로직)         │ │
│  │  - Ingress 규칙 watch             │ │
│  │  - Service Endpoints 추적         │ │
│  │  - Nginx 설정 자동 생성/업데이트  │ │
│  └───────────────────────────────────┘ │
└─────────────────────────────────────────┘

4.2 실제 동작 시나리오

Scenario: Backend Pod 재시작

# 1. 초기 상태
$ kubectl get pods -o wide
NAME           IP
backend-aaa    10.244.1.5
backend-bbb    10.244.2.8

# Ingress Controller 내부 Nginx 설정 (자동 생성됨)
upstream backend-service {
    server 10.244.1.5:8080;
    server 10.244.2.8:8080;
}
# 2. Backend Pod 하나 재시작
$ kubectl delete pod backend-aaa

# 3. 새 Pod 생성 (IP 변경!)
$ kubectl get pods -o wide
NAME           IP
backend-ccc    10.244.1.12  ← 새 IP!
backend-bbb    10.244.2.8

Ingress Controller가 자동으로:
1. Service의 Endpoints 변경 감지
2. Nginx 설정 자동 업데이트

upstream backend-service {
    server 10.244.1.12:8080;  # ← 자동 업데이트!
    server 10.244.2.8:8080;
}
  1. Nginx reload 자동 실행

→ 우리는 아무것도 안 해도 됨!


5. 실습: Ingress vs 일반 Nginx 비교

5.1 Before: NodePort 방식 (현재)

아키텍처:

사용자
  ↓
http://xxx.xxx.xxx.xxx:30080  (Frontend)
http://xxx.xxx.xxx.xxx:30081  (Backend)
  ↓
NodePort Service
  ↓
Pod (IP 계속 변경)

문제:

  • 포트 번호 필요
  • 서비스별로 다른 URL

5.2 After: Ingress 방식

설치:

# Ingress Controller 설치 (Nginx 기반)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml

# 설치 확인
kubectl get pods -n ingress-nginx
# NAME                                   READY
# ingress-nginx-controller-xxxxx-xxxxx   1/1

Ingress 규칙 작성:

# ingress-rules.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: myapp.local  # 또는 실제 도메인
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 8080

적용:

kubectl apply -f ingress-rules.yaml

# 확인
kubectl get ingress
# NAME            HOSTS         ADDRESS         PORTS
# myapp-ingress   myapp.local   xxx.xxx.xxx.xxx 80

최종 아키텍처:

사용자
  ↓
http://myapp.local/       (Frontend)
http://myapp.local/api    (Backend)
  ↓
Ingress Controller (Nginx Pod)
  ├─ / → Frontend Service
  └─ /api → Backend Service
        ↓
    Frontend/Backend Pods

5.3 결과 비교

항목NodePortIngress
URLhttp://IP:30080http://myapp.com/
포트여러 개 필요80/443만
도메인어려움쉬움
SSL서비스별 설정한 곳에서 설정
라우팅Service마다 포트경로로 구분

6. Ingress Controller 내부 들여다보기

6.1 실제 Nginx 설정 확인

# Ingress Controller Pod 찾기
INGRESS_POD=$(kubectl get pods -n ingress-nginx -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].metadata.name}')

# Nginx 설정 파일 확인
kubectl exec -n ingress-nginx $INGRESS_POD -- cat /etc/nginx/nginx.conf

출력 예시 (일부):

# 자동 생성된 설정!
upstream default-backend-service-8080 {
    # Service Endpoints 자동 추적
    server 10.244.1.12:8080 max_fails=0 fail_timeout=0;
    server 10.244.2.8:8080 max_fails=0 fail_timeout=0;
}

server {
    listen 80;
    server_name myapp.local;

    location /api {
        proxy_pass http://default-backend-service-8080;
        # ... 기타 설정
    }
}

→ 결국 Nginx 설정이지만, 자동으로 생성/관리됨!

6.2 변경 사항 자동 감지

# Backend를 3개로 스케일업
kubectl scale deployment backend --replicas=3

# 잠시 후 Nginx 설정 다시 확인
kubectl exec -n ingress-nginx $INGRESS_POD -- cat /etc/nginx/nginx.conf | grep "server 10.244"

출력:

server 10.244.1.12:8080;  # 기존
server 10.244.2.8:8080;   # 기존
server 10.244.1.15:8080;  # ← 자동으로 추가됨!

7. Ingress vs Frontend Nginx 헷갈림 해소

많은 사람들이 헷갈려하는 부분:

7.1 Frontend Pod 안의 Nginx

# frontend deployment
containers:
- name: nginx
  image: nginx:alpine
  # HTML 파일 서빙
  # /api 요청을 Backend로 프록시

역할:

  • HTML/CSS/JS 파일 서빙
  • 정적 자산 제공
  • 클라이언트 사이드 라우팅
  • 범위: 이 Pod 내부만

7.2 Ingress Controller의 Nginx

kubectl get pods -n ingress-nginx
# ingress-nginx-controller-xxxxx

역할:

  • 클러스터 전체 진입점
  • 도메인 기반 라우팅
  • 여러 Service 통합
  • 범위: 클러스터 전체

7.3 계층 구조

인터넷
  ↓
Ingress Controller (Nginx #1)
  ├─ myapp.com/ → Frontend Service
  │                    ↓
  │               Frontend Pod
  │                    ↓
  │               Nginx #2 (HTML 서빙)
  │
  └─ myapp.com/api → Backend Service
                          ↓
                     Backend Pod

비유:

Ingress Controller = 공항 입구 안내 데스크
  "어느 게이트로 가실까요?"

Frontend Pod Nginx = 탑승구 직원
  "탑승권 확인하고 좌석 안내해드릴게요"

8. Ingress의 장단점

8.1 장점

자동화

  • Pod IP 변경 자동 추적
  • 설정 자동 생성/업데이트

통합 관리

  • 하나의 진입점으로 여러 Service 관리
  • 일관된 URL 체계

쿠버네티스 네이티브

  • YAML로 선언적 관리
  • kubectl로 제어 가능

고급 기능

  • SSL/TLS 자동 관리
  • 경로 기반 라우팅
  • 호스트 기반 라우팅
  • 로드 밸런싱

8.2 단점

초기 복잡도

  • 새로운 개념 학습 필요
  • 설치/설정 단계 추가

디버깅

  • 추상화 레이어가 많음
  • 문제 발생 시 원인 파악 어려움

리소스

  • Ingress Controller Pod 추가 필요
  • 메모리/CPU 사용

9. 실전 팁

9.1 hosts 파일로 로컬 테스트

도메인이 없어도 테스트 가능:

# /etc/hosts (Linux/Mac) 또는 C:\Windows\System32\drivers\etc\hosts (Windows)
xxx.xxx.xxx.xxx myapp.local

이제 브라우저에서:

http://myapp.local/
http://myapp.local/api

9.2 Ingress 디버깅

# Ingress 상태 확인
kubectl describe ingress myapp-ingress

# Ingress Controller 로그
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

# Endpoints 확인 (Service가 올바른 Pod를 가리키는지)
kubectl get endpoints

9.3 SSL/HTTPS 추가

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - myapp.com
    secretName: myapp-tls
  rules:
  - host: myapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

10. 결론

핵심 정리

  1. Ingress는 Nginx를 쿠버네티스 방식으로 관리하는 도구

    • Nginx 자체가 아니라 Nginx를 자동화하는 레이어
  2. 왜 필요한가?

    • 쿠버네티스의 동적 환경 (Pod IP 변경, 오토스케일링)
    • 수동 관리 불가능
  3. 어떻게 동작하나?

    • Ingress Resource (YAML 규칙) 작성
    • Ingress Controller가 자동으로 Nginx 설정 생성
    • Service 이름 → Pod IP 자동 변환
  4. 언제 사용하나?

    • 프로덕션 환경
    • 여러 Service를 하나의 도메인으로 통합
    • SSL/HTTPS 필요
    • 경로 기반 라우팅

최종 비교

관점수동 NginxIngress
설정nginx.conf 직접 편집YAML 선언
IP 관리수동자동
업데이트수동 reload자동
환경정적 서버동적 쿠버네티스
러닝 커브낮음중간
운영 효율낮음높음

0개의 댓글