인그레스 운영, 왜 직접 부딪혀봐야 할까요?

쿠버네티스 클러스터를 운영하다 보면 서비스 개수가 늘어날수록 머리가 아파지는 순간이 찾아와요. 처음에는 간단하게 NodePort로 외부 노출을 시도하거나, 각 서비스마다 LoadBalancer를 붙여서 해결하곤 하죠. 하지만 서비스가 10개, 20개로 늘어나면 어떻게 될까요? 클라우드 비용은 기하급수적으로 올라가고, 각 서비스마다 할당된 포트 번호를 외우느라 정신이 없어질 거예요.
저 역시 비슷한 상황을 겪었어요. 매번 새로운 마이크로서비스를 배포할 때마다 새로운 로드밸런서를 생성해야 했고, 그로 인해 발생하는 비용 고지서를 보며 깜짝 놀라기도 했죠. 트래픽 관리 규칙이 복잡해지면서 네트워크 설정 실수로 서비스가 중단되는 아찔한 경험도 했어요. 이런 혼란을 잠재우기 위해 도입한 것이 바로 인그레스(Ingress)예요.
인그레스는 단순한 네트워크 도구가 아니에요. 클러스터 내부의 수많은 서비스를 단 하나의 진입점으로 묶어주고, 도메인과 경로에 따라 똑똑하게 트래픽을 배분해 주는 교통 정리원과 같아요. 이 글에서는 제가 실제 운영 환경에서 인그레스를 어떻게 도입했고, 어떤 과정에서 삽질을 하며 성장했는지 그 생생한 이야기를 들려드릴게요.
이 글을 끝까지 읽고 나면 다음과 같은 내용을 확실히 얻어갈 수 있어요.
- 서비스 구조에 맞는 최적의 인그레스 도입 시점 판단 기준
- Nginx Ingress Controller를 활용한 실무 설정 방법
- 실제 운영 중 마주친 트래픽 이슈와 해결 노하우
- 비용과 성능을 모두 잡는 인그레스 최적화 전략
성공적인 도입을 위한 사전 준비와 선택 기준
인그레스를 무턱대고 설치한다고 모든 문제가 해결되지는 않아요. 우리 서비스의 규모와 트래픽 특성을 먼저 이해해야 해요. 준비 없이 도입했다가는 오히려 설정의 복잡함 때문에 운영 난이도만 높아질 수 있거든요. 가장 먼저 결정해야 할 것은 인그레스 컨트롤러(Ingress Controller)를 무엇으로 쓸 것인가 하는 점이에요.
가장 대중적인 선택지는 Nginx Ingress Controller예요. 설정이 유연하고 레퍼런스가 압도적으로 많아서 실무에서 가장 선호하죠. 반면, 클라우드 환경(AWS, GCP 등)을 사용 중이라면 각 클라우드사가 제공하는 전용 인그레스 컨트롤러를 고려할 수도 있어요. 이들은 관리 부담이 적다는 강력한 장점이 있지만, 세밀한 설정을 커스텀하기에는 제약이 따를 수 있어요.
인그레스는 ‘규칙(Rule)’을 정의하는 리소스이고, 인그레스 컨트롤러는 그 규칙을 실제로 수행하는 ‘엔진(Engine)’이에요. 규칙만 만든다고 트래픽이 흐르지 않으니 반드시 컨트롤러를 함께 설치해야 해요.
도입 전, 현재 우리 시스템이 어떤 노출 방식을 쓰고 있는지 아래 표를 통해 냉정하게 비교해 보세요.
| 노출 방식 | 장점 | 단점 | 추천 상황 |
|---|---|---|---|
| NodePort | 설정이 매우 단순함 | 포트 관리 어려움, 보안 취약 | 테스트/개발 환경 |
| LoadBalancer | 클라우드 통합 관리 가능 | 서비스당 비용 발생 (매우 비쌈) | 단일 서비스 노출 시 |
| Ingress | 비용 절감, 경로 기반 라우팅 | 컨트롤러 관리 부담 존재 | 다수 서비스 운영 환경 |
준비가 되었다면 다음 체크리스트를 확인해 보세요. 이 항목들이 준비되지 않았다면 인그레스 도입은 잠시 미뤄두는 것이 좋아요.
- 사용할 도메인 네임이 준비되었나요?
- SSL/TLS 인증서를 관리할 Cert-manager 같은 도구가 고려되었나요?
- 클러스터 내부에 Ingress Controller를 설치할 충분한 리소스(CPU/Memory)가 있나요?
- 트래픽 패턴에 따라 타임아웃이나 바디 사이즈 제한을 조정할 준비가 되었나요?
주의: 인그레스를 도입하면 클러스터 외부에서 내부로 들어오는 통로가 단일화돼요. 즉, 인그레스 컨트롤러에 장애가 생기면 모든 서비스가 동시에 중단된다는 점을 반드시 명심해야 해요. 따라서 컨트롤러의 고가용성(HA) 확보가 최우선 과제예요.
실전! 인그레스 구축부터 최적화까지 단계별 실행
이제 이론은 접어두고 실제 환경에 적용하는 과정을 살펴볼게요. 저는 Helm을 사용하여 Nginx Ingress Controller를 설치하는 방식을 추천해요. 수동으로 매니페스트를 작성하는 것보다 훨씬 안전하고 업데이트가 쉽거든요.
STEP 1. 서비스 구조 설계와 트래픽 흐름 이해하기
설치에 들어가기 전, 우리가 만들 트래픽의 경로를 머릿속으로 그려봐야 해요. 사용자가 브라우저에 주소를 입력하면 어떤 단계를 거쳐 Pod까지 도달할까요? 보통 사용자 → DNS → Cloud LoadBalancer → Ingress Controller → Service → Pod 순으로 흐르게 돼요.
이 흐름을 이해해야 나중에 문제가 생겼을 때 어디를 고쳐야 할지 알 수 있어요. 예를 들어, 404 에러가 난다면 인그레스 규칙(Rule) 문제일 가능성이 높고, 502 에러가 난다면 컨트롤러와 백엔드 서비스 사이의 연결 문제일 확률이 높거든요. 설계 단계에서는 도메인을 어떻게 나눌지(예: api.example.com, web.example.com)와 경로(예: /v1, /v2)를 어떻게 구분할지를 먼저 결정하세요.
STEP 2. Nginx Ingress Controller 설치와 초기 설정
먼저 Helm을 이용해 컨트롤러를 설치할게요. 이때 중요한 점은 컨트롤러가 돌아갈 전용 네임스페이스를 만드는 거예요. 서비스들이 섞이지 않도록 ingress-nginx라는 별도의 공간을 확보하는 거죠.
설치 시에는 클라우드 환경의 LoadBalancer 서비스와 연동되도록 설정해야 해요. Helm 차트의 values.yaml 파일을 수정하여, 외부 트래픽을 받아올 수 있는 공인 IP를 확보하도록 명령을 내려야 하죠. 설치가 완료되면 `kubectl get svc -n ingress-nginx` 명령어를 통해 외부 IP가 정상적으로 할당되었는지 확인하세요. 이 IP가 바로 우리 서비스의 유일한 대문이 될 거예요.
STEP 3. 도메인 연결 및 TLS 인증서 자동화 적용
IP 주소만으로 서비스를 운영할 수는 없겠죠? 이제 도메인을 연결하고 보안(HTTPS)을 입혀야 해요. 저는 이 과정을 자동화하기 위해 Cert-manager를 함께 사용했어요. Let’s Encrypt 인증서를 사용하여 무료로 SSL을 적용할 수 있거든요.
인그레스 설정 파일(YAML)에 tls: 섹션을 추가하고, 우리가 사용할 시크릿(Secret) 이름을 명시하면 돼요. Cert-manager가 이 설정을 감지하면 자동으로 인증서를 발급받고, 갱신 주기까지 관리해 줘요. 이제 개발자는 인증서 만료 날짜를 체크하며 밤잠을 설칠 필요가 없어요. 보안은 인그레스가, 인증서는 Cert-manager가 알아서 해주니까요.
STEP 4. 경로 기반 및 호스트 기반 라우팅 구현
이제 가장 핵심인 라우팅 규칙을 만듭니다. 두 가지 방식이 있어요. 하나는 호스트 기반(Host-based) 방식이고, 다른 하나는 경로 기반(Path-based) 방식이에요.
호스트 기반은 `api.example.com`은 API 서버로, `dashboard.example.com`은 관리자 페이지로 보내는 식이에요. 경로 기반은 `example.com/api`는 API로, `example.com/static`은 정적 파일 서버로 보내는 방식이죠. 보통 이 두 가지를 혼합해서 사용해요. 예를 들어, 하나의 도메인 안에서 `/api` 경로를 가진 요청만 별도의 마이크로서비스로 보내는 식이죠. 이때 주의할 점은 경로 설정 시 pathType: ImplementationSpecific이나 Prefix를 정확히 구분해야 한다는 거예요. 잘못 설정하면 원치 않는 경로로 트래픽이 튀어버릴 수 있어요.
STEP 5. 트래픽 부하 분산 및 세부 최적화
기본 설정만으로 서비스가 돌아가긴 하겠지만, 실제 트래픽이 몰리면 문제가 생겨요. 특히 파일 업로드 기능이 있는 서비스라면 client_max_body_size 설정이 필수예요. Nginx의 기본값은 매우 작아서, 큰 파일을 올리려고 하면 바로 413 Request Entity Too Large 에러를 만나게 돼요.
또한, API 서버의 응답이 길어지는 경우가 있다면 proxy-read-timeout 값을 늘려줘야 해요. 기본 타임아웃을 넘기면 사용자는 연결이 끊겼다는 메시지를 보게 될 거예요. 이 외에도 커넥션 풀링 설정이나 버퍼 사이즈 조절을 통해 메모리 사용량을 최적화할 수 있어요. 이런 세세한 튜닝이 모여 서비스의 안정성을 결정한다는 사실을 잊지 마세요.
인그레스 설정은
Annotation(주석)을 통해 이루어지는 경우가 많아요. 예를 들어 `nginx.ingress.kubernetes.io/rewrite-target` 같은 주석은 경로 재작성 기능을 제공하므로, 백엔드 서비스의 경로 구조와 인그레스 경로가 다를 때 매우 유용해요.자주 하는 실수와 해결법
운영 현장에서 제가 직접 겪었던, 그리고 많은 동료가 반복하는 실수들을 정리했어요. 이 리스트만 알아도 삽질 시간을 절반으로 줄일 수 있어요.
- ❌ 경로(Path) 끝에 슬래시(/)를 빼먹음
→ 왜 발생하는가: 인그레스 규칙은 매우 엄격해요. `/api`와 `/api/`는 다르게 인식될 수 있어요.
✅ 해결법: 서비스의 엔드포인트 구조를 확인하고,rewrite-target주석을 사용해 경로를 정확히 맞춰주세요. - ❌ TLS Secret 이름을 잘못 기재함
→ 왜 발생하는가: 인증서는 발급되었지만 인그레스가 어디서 가져와야 할지 모르는 상태예요.
✅ 해결법:kubectl get secret으로 실제 이름과 YAML의 이름을 대조해 보세요. - ❌ Backend Service의 포트 불일치
→ 왜 발생하는가: 인그레스가 80포트로 보내는데, 실제 서비스는 8080에서 기다리고 있는 경우예요.
✅ 해결법: Ingress 리소스의service.port.number가 실제 Service 객체의port와 일치하는지 확인하세요. - ❌ Annotation 오타
→ 왜 발생하는가: Nginx 인그레스는 특정 접두사(`nginx.ingress.kubernetes.io/`)를 가진 주석을 읽어 동작해요.
✅ 해결법: 공식 문서를 옆에 띄워두고 복사해서 사용하세요. 직접 타이핑하는 건 위험해요. - ❌ Namespace 불일치
→ 왜 발생하는가: 인그레스 리소스와 대상 서비스가 서로 다른 네임스페이스에 있으면 찾을 수 없어요.
✅ 해결법: 하나의 인그레스는 반드시 동일한 네임스페이스 내의 서비스만 가리킬 수 있다는 원칙을 지키세요.
자주 묻는 질문
Q. 인그레스와 로드밸런서 서비스의 차이점이 정확히 무엇인가요?
로드밸런서 서비스는 클라우드에서 제공하는 물리적/가상 로드밸런서 하나를 통째로 빌려 쓰는 개념이에요. 서비스마다 하나씩 만들면 돈이 많이 들죠. 반면 인그레스는 하나의 로드밸런서(컨트롤러) 뒤에 수많은 규칙을 두어 트래픽을 나누는 방식이라 훨씬 경제적이고 유연해요.
Q. 인그레스 컨트롤러가 죽으면 어떻게 하나요?
모든 서비스로 가는 길이 막히게 돼요. 그래서 운영 환경에서는 컨트롤러를 최소 2개 이상의 노드에 분산 배치하고, 클라우드의 LoadBalancer 서비스를 통해 컨트롤러 자체를 고가용성으로 구성하는 것이 필수예요.
Q. SSL 인증서 갱신은 어떻게 관리하나요?
수동으로 하면 반드시 사고가 나요. Cert-manager를 설치하고 Let’s Encrypt와 연동해 두면, 인증서 만료 전 자동으로 갱신하고 Secret까지 업데이트해 주니 걱정 마세요.
Q. 특정 IP만 허용하고 싶은데 가능한가요?
네, 가능해요. Nginx 인그레스의 whitelist-source-range 주석을 사용하면 특정 IP 대역에서 오는 요청만 허용하도록 아주 쉽게 설정할 수 있어요.
Q. 경로 기반 라우팅 시 `/api`로 들어온 요청이 백엔드에 `/`로 전달되게 할 수 있나요?
네, nginx.ingress.kubernetes.io/rewrite-target 주석을 사용하면 돼요. 이 기능은 인그레스에서 경로를 필터링한 뒤, 실제 서비스로 전달할 때는 경로를 재작성해서 깔끔하게 넘겨줄 때 매우 유용해요.
인그레스 운영을 마치며: 다음 단계로 나아가기
인그레스 도입은 쿠버네티스 운영의 수준을 한 단계 높여주는 중요한 전환점이에요. 단순히 트래픽을 전달하는 것을 넘어, 보안을 강화하고 비용을 절감하며 복잡한 마이크로서비스 구조를 하나로 묶어주는 핵심 인프라가 되기 때문이죠. 하지만 처음부터 완벽할 수는 없어요. 제가 겪었던 시행착오를 여러분은 건너뛰고, 더 나은 최적화에 집중하시길 바라요.
- 서비스별 로드밸런서 대신 인그레스를 사용하여 비용을 절감하세요.
- Nginx Ingress Controller와 Helm을 조합해 안정적으로 설치하세요.
- Cert-manager를 활용해 SSL/TLS 인증서 관리를 자동화하세요.
- Annotation을 활용해 타임아웃, 파일 크기 등 세부 설정을 최적화하세요.
- 경로(Path)와 호스트(Host) 기반 라우팅 규칙을 명확히 설계하세요.
이제 막 인그레스를 공부하기 시작했다면, 다음 단계로 이것들을 실행해 보세요.
- 오늘 할 일: 현재 운영 중인 서비스 중 가장 단순한 서비스 하나를 골라 Ingress 규칙을 작성해 보세요.
- 이번 주 할 일: 개발 환경(Minikube 등)에 Nginx Ingress Controller를 직접 설치하고 도메인 연결을 테스트해 보세요.
- 실행 직전 할 일: 운영 환경 적용 전, 반드시
dry-run모드로 설정에 오류가 없는지 확인하는 습관을 들이세요.
인그레스 설정 중에 예상치 못한 에러 메시지를 마주한다면 당황하지 마세요. 로그를 꼼꼼히 살피면 반드시 답이 있어요. 만약 혼자 해결하기 어려운 부분이 있다면, 실습 환경에서 직접 적용해 보고, 막히는 부분은 댓글로 질문을 남겨 주세요. 함께 고민하면 더 빨리 해결할 수 있을 거예요.
함께 읽으면 좋은 글: 쿠버네티스 인그레스 기본 개념 글, 클러스터 구축 입문 글