
인그레스 운영 사례를 통해 배우는 효율적인 트래픽 관리
새로운 마이크로서비스를 하나 배포할 때마다 클라우드 콘솔에 접속해 새로운 로드밸런서를 생성하던 기억이 나요. 처음에는 서비스가 두세 개뿐이라 괜찮았지만, 서비스 규모가 커지면서 매달 청구되는 로드밸런서 비용이 감당하기 어려울 정도로 불어나기 시작했어요. 게다가 각 서비스마다 개별적인 IP와 DNS를 관리하는 것도 운영 팀에게는 커다란 짐이었지요.
단순히 서비스를 외부로 노출하는 것을 넘어, 하나의 진입점을 통해 수십 개의 서비스를 경로(Path)나 호스트(Host)에 따라 깔끔하게 분기하고 싶다는 갈증이 생겼어요. 이것이 바로 저희 팀이 인그레스 운영 사례를 깊이 파고들게 된 결정적인 계기였어요.
많은 개발자가 쿠버네티스를 배우면서 서비스(Service)와 인그레스(Ingress)의 차이점은 알지만, 실제 운영 환경에서 어떤 변수들을 마주하게 되는지는 알기 어려워요. 설정 하나 잘못해서 전체 서비스의 접속이 끊기거나, SSL 인증서 적용 과정에서 예상치 못한 오류로 밤을 지새우는 일이 비일비재하거든요.
이 글에서는 저희 팀이 실제 운영 환경에서 인그레스를 도입하며 겪었던 시행착오와 그 과정에서 얻은 값진 교훈들을 가감 없이 나누려고 해요. 이론적인 설명보다는 실무에서 바로 써먹을 수 있는 생생한 경험담을 중심으로 구성했어요.
이 글을 읽고 나면 다음과 같은 내용을 확실히 이해할 수 있어요.
- 로드밸런서 비용을 절감하며 다수의 서비스를 운영하는 방법
- 인그레스 컨트롤러의 역할과 올바른 구성 방식
- 실무에서 자주 발생하는 설정 오류와 해결 시나리오
- SSL/TLS 인증서를 효율적으로 관리하는 노하우
인그레스 도입 전 반드시 체크해야 할 준비 사항
인그레스를 도입하기로 마음먹었다면 무작정 YAML 파일을 작성하기 전에 우리 클러스터의 현재 상태를 먼저 점검해야 해요. 인그레스는 스스로 트래픽을 처리하는 엔진이 아니라, 트래픽을 전달해 주는 규칙(Rule)일 뿐이기 때문이에요. 즉, 이 규칙을 실제로 실행해 줄 인그레스 컨트롤러(Ingress Controller)가 클러스터 내에 반드시 설치되어 있어야 해요.
가장 먼저 고려해야 할 것은 어떤 컨트롤러를 사용할 것인가예요. 가장 대중적인 선택지는 NGINX Ingress Controller이지만, 클라우드 환경에 따라 AWS의 ALB Ingress Controller나 Google Cloud의 GCE Ingress를 사용하는 것이 더 유리할 수도 있어요. 각 컨트롤러마다 지원하는 기능과 설정 방식(Annotation)이 다르기 때문에 우리 서비스의 요구사항을 먼저 정의하는 것이 순서예요.
또한, 현재 사용 중인 서비스(Service)들의 타입이 무엇인지도 확인해야 해요. 인그레스는 보통 ClusterIP 타입의 서비스를 대상으로 동작해요. 만약 모든 서비스가 이미 LoadBalancer 타입으로 외부에 노출되어 있다면, 인그레스를 도입했을 때 트래픽 흐름이 어떻게 변할지, 기존 설정과 충돌하지는 않을지 면밀히 검토해야 해요.
아래 표는 인그레스 도입 여부를 결정할 때 참고할 수 있는 서비스 노출 방식별 비교표예요. 우리 팀의 상황이 어디에 해당하는지 확인해 보세요.
| 주요 특징 | 장점 | 단점 | |
|---|---|---|---|
| NodePort | 모든 노드의 특정 포트를 개방 | 구현이 매우 간단함 | 포트 관리의 어려움, 보안 취약 |
| LoadBalancer | 클라우드 제공 로드밸런서 사용 | 높은 가용성과 관리 편의성 | 서비스마다 비용 발생 (매우 비쌈) |
| Ingress | L7 계층 기반 라우팅 수행 | 비용 절감, 도메인/경로 기반 제어 | 설정 복잡도 증가, 컨트롤러 관리 필요 |
⚠️ 주의
인그레스를 도입한다고 해서 모든 비용이 즉시 사라지는 것은 아니에요. 인그레스 컨트롤러 자체를 구동하기 위한 리소스와, 컨트롤러를 외부에 노출하기 위한 최소 하나의 LoadBalancer 비용은 여전히 발생한다는 점을 기억해야 해요. 핵심은 ‘서비스 개수당 1개’의 비용을 ‘전체 서비스 통합 1개’로 줄이는 데 있어요.
인그레스 구축 및 실전 운영 단계별 가이드
본격적으로 인그레스를 구축하는 과정은 단순히 YAML 파일을 하나 만드는 것으로 끝나지 않아요. 아키텍처 설계부터 트래픽 제어, 보안 설정까지 체계적인 단계가 필요해요. 저희 팀이 실제로 수행했던 6가지 핵심 단계를 바탕으로 설명해 드릴게요.
STEP 1. 기존 서비스 구조 분석과 도메인 설계
인그레스를 적용하기 전 가장 먼저 해야 할 일은 현재 운영 중인 서비스들의 도메인과 경로 체계를 정리하는 것이에요. 무턱대고 인그레스를 설치했다가는 기존에 사용하던 도메인 충돌이나 경로 중첩 문제로 서비스 장애가 발생할 수 있어요.
저희는 서비스를 두 가지 방식으로 분류했어요. 첫 번째는 호스트 기반(Host-based) 방식이에요. 예를 들어 `api.example.com`은 API 서버로, `web.example.com`은 프론트엔드 서버로 보내는 식이죠. 두 번째는 경로 기반(Path-based) 방식이에요. 하나의 도메인 아래에서 `example.com/user`는 사용자 서비스로, `example.com/order`는 주문 서비스로 나누는 것이죠. 이 두 방식을 적절히 혼합하는 것이 운영 효율성을 극대화하는 비결이에요.
STEP 2. 인그레스 컨트롤러(NGINX) 설치 및 검증
저희 팀은 가장 레퍼런스가 많고 커뮤니티가 활발한 NGINX Ingress Controller를 선택했어요. 설치는 주로 Helm을 통해 진행했어요. Helm을 사용하면 컨트롤러의 설정값을 명령줄에서 손쉽게 변경할 수 있고, 나중에 버전 업데이트를 할 때도 매우 편리하기 때문이에요.
설치 후에는 반드시 컨트롤러가 클러스터 내의 서비스들을 제대로 인식하는지 확인해야 해요. 컨트롤러의 파드(Pod)가 정상적으로 `Running` 상태인지, 그리고 컨트롤러가 생성한 LoadBalancer 서비스가 외부 IP를 정상적으로 할당받았는지 확인하는 것이 첫 번째 검증 단계예요. 이때 컨트롤러의 로그를 실시간으로 모니터링하며 트래픽이 들어올 때 어떤 동작을 하는지 관찰하는 과정이 꼭 필요해요.
STEP 3. 인그레스 리소스(Ingress Resource) 작성 및 배포
이제 실제 규칙을 담은 YAML 파일을 작성할 차례예요. 인그레스 리소스는 어떤 호스트로 들어온 요청을 어떤 서비스의 어떤 포트로 보낼지를 정의하는 일종의 ‘이정표’ 역할을 해요. 작성할 때는 반드시 서비스의 이름과 포트 번호가 일치하는지 재차 확인해야 해요.
예를 들어, 특정 경로(`/api`)로 들어오는 요청을 `user-service`라는 이름의 서비스로 보내고 싶다면 아래와 같은 논리적 구조를 갖게 돼요. 하지만 여기서 주의할 점은 경로 설정 시 슬래시(/) 처리예요. `/api`와 `/api/`는 다르게 동작할 수 있으므로, 서비스의 실제 엔드포인트 구조와 일치하도록 세심하게 설계해야 해요.
STEP 4. SSL/TLS 인증서 적용을 통한 보안 강화
실무 환경에서 HTTPS 적용은 선택이 아닌 필수예요. 인그레스의 가장 큰 장점 중 하나는 각 서비스마다 인증서를 설정할 필요 없이, 인그레스 계층에서 SSL Termination을 한 번에 처리할 수 있다는 점이에요. 즉, 외부에서 인그레스까지는 암호화된 통신을 하고, 클러스터 내부의 서비스들끼리는 가벼운 HTTP 통신을 하게 하여 네트워크 부하를 줄일 수 있어요.
저희는 `cert-manager`를 함께 사용하여 Let’s Encrypt 인증서를 자동으로 발급받고 갱신하도록 구성했어요. 인증서가 만료되어 서비스 접속이 차단되는 끔찍한 사고를 방지하기 위해서죠. 인그레스 설정 파일에 `tls` 섹션을 추가하고, 미리 생성된 Secret 이름을 지정해 주는 것만으로도 보안 설정이 완료돼요.
STEP 5. Annotation을 활용한 고급 트래픽 제어
인그레스는 단순한 전달자를 넘어 매우 강력한 기능을 제공해요. 바로 Annotation(주석) 기능을 통해서예요. NGINX 인그레스 컨트롤러는 수많은 주석을 통해 동작을 미세하게 조정할 수 있게 해 줘요.
예를 들어, 특정 서비스에만 더 큰 업로드 용량을 허용하고 싶다면 `nginx.ingress.kubernetes.io/proxy-body-size` 주석을 사용하면 돼요. 또한, 특정 경로에 대해 속도 제한(Rate Limiting)을 걸어 디도스(DDoS) 공격이나 특정 클라이언트의 과도한 요청으로부터 서비스를 보호할 수도 있어요. 이러한 세세한 설정들이 모여 안정적인 서비스 운영을 가능하게 만들어요.
STEP 6. 모니터링 및 성능 최적화
마지막 단계는 인그레스가 정상적으로 작동하는지 지속적으로 관찰하는 것이에요. 트래픽이 갑자기 몰릴 때 인그레스 컨트롤러의 CPU나 메모리 사용량이 급증하지 않는지, 응답 시간이 길어지지는 않는지 체크해야 해요.
저희는 Prometheus와 Grafana를 연결하여 인그레스의 요청 수, 에러율(4xx, 5xx), 응답 시간을 시각화했어요. 이를 통해 특정 서비스에서 에러가 발생하면 즉시 인그레스 계층에서 문제를 인지할 수 있었고, 트래픽 패턴을 분석하여 인그레스 컨트롤러의 리소스 할당량(Resource Quota)을 적절히 조절할 수 있었어요.
인그레스 설정 시 자주 사용하는 핵심 Annotation 예시입니다.
proxy-body-size: 파일 업로드 용량 제한 설정rewrite-target: 요청 경로를 재작성하여 서비스에 전달canary: 카나리 배포를 위한 트래픽 분할 설정ssl-redirect: HTTP 요청을 자동으로 HTTPS로 전환
자주 하는 실수와 해결법 및 FAQ
인그레스를 처음 운영하다 보면 정말 별거 아닌 설정 하나 때문에 몇 시간을 허비하게 되는 경우가 많아요. 저희 팀이 겪었던 실제 사례들을 바탕으로 실수를 정리해 드릴게요.
자주 하는 실수와 해결법
❌ 실수: 인그레스 리소스를 생성했는데 접속이 안 돼요.
왜 발생하는가: 인그레스 컨트롤러가 설치되어 있지 않거나, 컨트롤러가 해당 인그레스 리소스를 인식하지 못하는 경우예요. 인그레스는 규칙일 뿐, 실행 주체가 없으면 아무 일도 일어나지 않아요.
✅ 해결법: 먼저 `kubectl get pods -n <컨트롤러-네임스페이스>` 명령어로 컨트롤러가 떠 있는지 확인하세요. 또한 인그레스 리소스의 `ingressClassName`이 컨트롤러의 설정과 일치하는지 반드시 확인해야 해요.
❌ 실수: 특정 경로로 접속하면 404 에러가 발생해요.
왜 발생하는가: 경로 매칭(Path Matching) 규칙이 잘못되었거나, 서비스의 엔드포인트와 경로가 맞지 않기 때문이에요. 특히 `/api`로 들어온 요청을 서비스에 전달할 때 서비스 내부에서도 `/api` 경로를 기다리고 있는지 확인해야 해요.
✅ 해결법: `rewrite-target` annotation을 사용하여 인그레스가 경로를 수정해서 전달하도록 설정하거나, 서비스 애플리케이션의 경로 설정을 인그레스 규칙과 일치시키세요.
❌ 실수: SSL 인증서를 적용했는데 브라우저에서 경고가 떠요.
왜 발생하는가: 인증서가 포함된 Secret이 존재하지 않거나, 인그레스 설정에서 해당 Secret 이름을 잘못 적었을 가능성이 커요.
✅ 해결법: `kubectl get secret`으로 인증서가 정상적으로 존재하는지 확인하고, 인그레스 YAML의 `tls.secretName` 필드와 이름이 완벽히 일치하는지 체크하세요.
❌ 실수: 서비스가 동작하는데 인그레스에서만 503 Service Unavailable이 떠요.
왜 발생하는가: 인그레스 컨트롤러가 목적지 서비스(Service)를 찾지 못하거나, 서비스가 연결된 파드(Pod)들이 준비 상태(Ready)가 아니기 때문이에요.
✅ 해결법: 서비스의 `selector`가 파드의 라벨과 정확히 일치하는지, 그리고 파드가 `Running` 상태이면서 `Readiness Probe`를 통과했는지 확인하세요.
❌ 실수: 업로드 중에 요청이 중간에 끊겨요.
왜 발생하는가: 인그레스 컨트롤러의 기본 파일 업로드 제한 용량(보통 1MB)을 초과했기 때문이에요.
✅ 해결법: `nginx.ingress.kubernetes.io/proxy-body-size` annotation을 사용하여 허용 용량을 충분히 늘려주세요.
자주 묻는 질문
Q. 인그레스와 서비스(LoadBalancer 타입)의 가장 큰 차이점은 무엇인가요?
서비스(LoadBalancer)는 각각의 서비스마다 독립적인 외부 로드밸런서를 생성하지만, 인그레스는 하나의 로드밸런서를 공유하면서 내부의 규칙에 따라 트래픽을 분배해요. 즉, 비용 효율성과 관리 편의성 면에서 인그레스가 훨씬 유리해요.
Q. 하나의 클러스터에 여러 개의 인그레스 컨트롤러를 설치할 수 있나요?
네, 가능해요. 예를 들어, 일반적인 웹 트래픽용 NGINX 컨트롤러와 보안이 매우 중요한 관리용 컨트롤러를 별도의 `ingressClassName`으로 나누어 운영할 수 있어요. 이를 통해 트래픽 성격에 따라 리소스를 분리하여 관리할 수 있답니다.
Q. 인그레스에서 세션 유지가 필요한데 어떻게 해야 하나요?
사용자의 접속을 특정 파드에 계속 유지해야 하는 경우(Sticky Session), NGINX 인그레스의 경우 특정 annotation을 사용하여 쿠키 기반의 세션 유지를 설정할 수 있어요. 이를 통해 로그인 상태 유지 등의 문제를 해결할 수 있어요.
Q. AWS 환경이라면 인그레스 대신 ALB를 직접 쓰는 게 더 좋지 않을까요?
상황에 따라 달라요. 단순한 구조라면 ALB Ingress Controller가 편리하지만, 매우 정교한 경로 제어, 속도 제한, 커스텀 헤더 조작 등이 필요하다면 NGINX 컨트롤러가 훨씬 강력한 기능을 제공해요. 우리 서비스의 복잡도를 고려해서 결정하는 것이 좋아요.
Q. 인그레스 설정 변경 시 서비스 중단이 발생하나요?
아니요, 인그레스 리소스를 업데이트하는 것은 컨트롤러가 설정을 다시 로드(Reload)하는 과정이기 때문에 이론적으로는 무중단으로 이루어져요. 하지만 설정 실수로 잘못된 규칙이 적용되면 접속 장애가 발생할 수 있으니, 반드시 스테이징 환경에서 먼저 검증해야 해요.
안정적인 인그레스 운영을 위한 마지막 점검
지금까지 인그레스 운영 사례를 통해 실제 현장에서 부딪히는 문제들과 해결책들을 살펴보았어요. 인그레스는 단순히 트래픽을 넘겨주는 도구를 넘어, 서비스의 관문이자 보안의 핵심 방어선이라는 사실을 꼭 기억해 주세요. 처음에는 설정이 복잡하게 느껴질 수 있지만, 한 번 제대로 구축해 두면 운영의 편의성과 비용 절감 측면에서 엄청난 이득을 얻을 수 있어요.
- 인그레스 도입 전 컨트롤러 설치 여부를 반드시 확인하세요.
- 서비스별 로드밸런서 비용을 인그레스 하나로 통합하여 절감하세요.
- 도메인과 경로 설계를 미리 체계적으로 수립하세요.
- SSL/TLS 인증서는 cert-manager를 통해 자동화하는 것을 추천해요.
- Annotation을 적극 활용하여 상세한 트래픽 제어를 수행하세요.
- 설정 변경 전에는 반드시 테스트 환경에서 검증 과정을 거치세요.
인그레스 운영이 처음이라 막막하시다면, 지금 바로 작은 테스트 클러스터에서 NGINX 컨트롤러를 설치하는 것부터 시작해 보세요. 이론으로 보는 것과 직접 YAML 파일을 적용하며 에러 로그를 확인하는 것은 하늘과 땅 차이예요.
오늘 바로 할 일: 현재 운영 중인 서비스 중 로드밸런서 비용이 과다하게 발생하는 것이 있는지 체크해 보세요.
이번 주 할 일: 테스트 환경에 Helm으로 NGINX Ingress Controller를 설치하고 간단한 HTTP 서비스를 연결해 보세요.
실행 직전 할 일: 서비스의 경로(Path) 체계와 도메인 리스트를 엑셀이나 문서로 정리해 보세요.
실습 환경에서 직접 적용해 보시다가 막히는 부분이 있거나, 예상치 못한 에러 로그가 발생한다면 주저하지 말고 댓글로 질문을 남겨 주세요. 함께 고민하며 해결해 나갔으면 좋겠어요!
이 글과 함께 읽으면 좋은 글:
• 쿠버네티스 인그레스 기본 개념 완벽 정리
• 클러스터 구축부터 운영까지 입문 가이드