티스토리 뷰

반응형

쿠버네티스 실습: Nginx Ingress Controller와 Nginx Proxy Manager로 외부 접근 구성하기

앞선 글에서는 Redis를 쿠버네티스에 배포하고 NestJS 애플리케이션에서 캐시 레이어로 활용하는 방법을 실습했습니다.
이번 글에서는 외부 사용자가 도메인으로 서비스에 접근할 수 있도록 Nginx Ingress Controller를 설치하고, Nginx Proxy Manager를 이용해 SSL(HTTPS)까지 적용하는 방법을 다룹니다.


1) 왜 Ingress인가?

쿠버네티스에서 **Service(NodePort, LoadBalancer)**만으로도 외부 노출이 가능합니다.
하지만:

  • NodePort는 포트 번호가 랜덤/불편합니다.
  • LoadBalancer는 클라우드 환경에서만 유효합니다.
  • 도메인 기반 라우팅, HTTPS 적용은 직접 관리해야 합니다.

Ingress는 이 문제를 해결합니다:

  • 하나의 LoadBalancer로 여러 도메인을 라우팅
  • 도메인별 라우팅 규칙 지정 가능
  • TLS/SSL 적용 지원

2) Ingress Controller 설치

Minikube에서는 ingress 애드온을 켜는 게 가장 쉽습니다.

minikube addons enable ingress
kubectl get pods -n kube-system

출력 예시:

NAME                                        READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-7c65d8d49d-abcde   1/1     Running   0          1m

이제 Ingress Controller가 준비되었습니다.


3) 예시 애플리케이션 배포 (NextJS/NestJS 서비스)

반응형

우리가 이미 배포한 NestJS와 NextJS 서비스가 있다고 가정합니다.
서비스 이름이 다음과 같다고 해봅시다:

  • nestjs-svc (port 3000)
  • nextjs-svc (port 3000)

4) Ingress 리소스 작성

app-ingress.yaml 작성:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: nest.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nestjs-svc
            port:
              number: 3000
  - host: next.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nextjs-svc
            port:
              number: 3000

적용:

kubectl apply -f app-ingress.yaml
kubectl get ingress

출력 예시:

NAME          CLASS   HOSTS                ADDRESS        PORTS   AGE
app-ingress   nginx   nest.local,next.local 192.168.49.2   80      30s

5) 로컬 도메인 매핑

맥북/맥미니의 /etc/hosts 파일에 다음을 추가:

192.168.49.2   nest.local next.local

192.168.49.2는 minikube ip로 확인하세요.

이제 브라우저에서:


6) Nginx Proxy Manager로 SSL 적용

Ingress만으로도 TLS는 적용 가능합니다. 하지만 UI 기반 관리를 원한다면 **Nginx Proxy Manager(NPM)**를 추가로 붙일 수 있습니다.

6-1. Nginx Proxy Manager 배포 (예시 Deployment)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: npm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: npm
  template:
    metadata:
      labels:
        app: npm
    spec:
      containers:
      - name: npm
        image: jc21/nginx-proxy-manager:2
        ports:
        - containerPort: 81   # 관리 UI
        - containerPort: 80   # HTTP
        - containerPort: 443  # HTTPS

Service:

apiVersion: v1
kind: Service
metadata:
  name: npm
spec:
  type: NodePort
  selector:
    app: npm
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30080
  - name: https
    port: 443
    targetPort: 443
    nodePort: 30443
  - name: admin
    port: 81
    targetPort: 81
    nodePort: 30081

적용:

kubectl apply -f npm-deployment.yaml
kubectl apply -f npm-service.yaml

6-2. 접속 확인

minikube service npm --url

브라우저에서 접속 → Nginx Proxy Manager UI를 통해 도메인 추가 + SSL(Let’s Encrypt) 설정 가능.


7) 정리

  • Minikube Ingress 애드온을 활성화하여 도메인 기반 라우팅 구현.
  • /etc/hosts 수정으로 로컬에서도 도메인 기반 접근 가능.
  • Nginx Proxy Manager를 추가하면 UI에서 SSL 발급과 프록시 설정을 관리할 수 있음.

다음 글에서는 CI/CD 파이프라인을 연결하여 코드 푸시 시 자동으로 NestJS/NextJS 이미지를 빌드하고, 쿠버네티스에 배포되는 워크플로우를 구성해보겠습니다.


 

쿠버네티스,Ingress,Nginx,프록시,NginxProxyManager,Minikube,도메인매핑,SSL,클라우드네이티브,K8s실습

 

 

바로 고칠 것 (핵심 4가지)

  1. 컨트롤러 확인 네임스페이스
    minikube addons enable ingress 이후 컨트롤러 파드는 ingress-nginx 네임스페이스에 뜹니다.
# 기존: kubectl get pods -n kube-system  (X)
kubectl get pods -n ingress-nginx        # 이것이 정답

(쿠버네티스 공식 튜토리얼이 -n ingress-nginx로 안내합니다.) (Kubernetes)


  1. Ingress에 ingressClassName 지정
    요즘은 주로 spec.ingressClassName: nginx를 씁니다(예전 annotation 방식은 점차 폐기).
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: nginx    # 추가
  rules:
    ...

(ingress-nginx는 kubernetes.io/ingress.class: "nginx" 또는 ingressClassName: nginx를 인식합니다.) (kubernetes.github.io)


  1. rewrite-target 주석은 불필요(오히려 혼동)
    현재 경로가 둘 다 / 인 단순 라우팅이라면 nginx.ingress.kubernetes.io/rewrite-target: / 없애세요. 이 주석은 보통 /app(/|$)(.*)처럼 캡처 그룹을 써서 하위 경로를 /로 재작성할 때 필요합니다. 불필요한 rewrite는 디버깅을 어렵게 만듭니다. (공식 예제 확인) (kubernetes.github.io)

  1. 로컬 도메인: /etc/hosts 외에 대안도 소개
    /etc/hosts는 맞는 방법이지만, Minikube에는 ingress-dns 애드온이 있어 /etc/hosts 편집 없이도 로컬 DNS로 Ingress 호스트를 해석하게 할 수 있습니다(원리: 질의 시 Ingress 목록을 조회). 선택지로 한 줄 소개해 두면 좋아요. (minikube)

Nginx Proxy Manager(NPM) 관련 현실 체크 (2가지)

  1. 로컬 Minikube에서 Let’s Encrypt 발급 한계
    NPM UI에서 Let’s Encrypt HTTP-01로 발급하려면 공인 DNS가 실제로 외부에서 접근 가능한 IP로 향하고, 방화벽/포트80이 열려 있어야 합니다. 로컬 Minikube(NodePort 30080/30443 등)로는 일반적으로 검증이 통과하지 않습니다. 이런 경우는

실습 난이도를 낮추려면: cert-manager로 self-signed(또는 staging) 발급 → Ingress에 TLS Secret 연결 방식을 권장합니다. 설치 한 줄:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml (cert-manager)

Ingress에 수동으로 자체 서명 키/인증서를 넣을 때는 다음처럼 만듭니다:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key -out tls.crt -subj "/CN=nest.local/O=nest.local" \
  -addext "subjectAltName = DNS:nest.local,DNS:next.local"

kubectl create secret tls app-tls --cert=tls.crt --key=tls.key

(이후 Ingress spec.tls에 secretName: app-tls 추가) (kubernetes.github.io, Kubernetes)


  1. NPM 배포 시 영속 볼륨 필수
    jc21/nginx-proxy-manager는 /data(설정/DB)와 /etc/letsencrypt(인증서) 볼륨이 필요합니다. 질문의 Deployment에는 볼륨이 없어 재시작 시 설정이 유실됩니다. PVC 또는 hostPath를 마운트하세요(프로젝트 가이드/풀 셋업 문서 참고). (nginxproxymanager.com)

예) (요지)

volumeMounts:
  - name: data
    mountPath: /data
  - name: letsencrypt
    mountPath: /etc/letsencrypt
volumes:
  - name: data
    persistentVolumeClaim:
      claimName: npm-data
  - name: letsencrypt
    persistentVolumeClaim:
      claimName: npm-le

보너스 팁

  • TLS를 Ingress에서 바로 종료: 운영/표준 패턴은 보통 ingress-nginx + cert-manager 조합입니다. NPM을 추가 프록시로 두면 레이어가 겹쳐 관리 복잡도가 증가합니다(반드시 UI가 필요할 때만 채택). (NGINX 문서, cert-manager)
  • Ingress 동작 확인 포인트: 컨트롤러는 80/443을 리슨하며 호스트 헤더 일치가 중요합니다. 접근 실패 시 kubectl logs -n ingress-nginx deploy/ingress-nginx-controller로 규칙 매칭을 먼저 확인하세요. (minikube)

최소 수정본 요약

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함
반응형