
갑작스러운 서비스 중단, 인그레스가 범인일 때
평온한 오후, 갑자기 슬랙(Slack) 알람이 울려요. “팀장님, 웹사이트 접속이 안 돼요!”라는 메시지와 함께 502 Bad Gateway 에러 화면이 올라와요. 당황스러운 마음에 급히 대시보드를 열어보지만, 포드(Pod)들은 모두 Running 상태이고 서비스도 멀쩡해 보여요. 이럴 때 가장 먼저 의심해야 할 곳은 바로 클러스터의 관문, 인그레스(Ingress)예요.
소규모 스타트업에서 혼자 서버를 담당하다 보면 이런 상황이 정말 자주 발생해요. 앱 코드를 수정한 적도 없고, 노드(Node)에 문제가 생긴 것도 아닌데 갑자기 트래픽이 끊겨버리니까요. 인그레스는 단순한 설정 파일 같아 보이지만, 내부적으로는 L7 로드밸런싱, TLS 인증서 처리, 경로 기반 라우팅 등 아주 복잡한 로직을 수행하고 있어요. 설정 하나만 어긋나도 서비스 전체가 먹통이 될 수 있는 아주 예민한 구성 요소예요.
인그레스 트러블슈팅이 어려운 이유는 에러 메시지만 봐서는 어디가 고장 났는지 바로 알기 어렵기 때문이에요. 클라이언트가 보낸 요청이 인그레스 컨트롤러에 도달하지 못한 것인지, 컨트롤러는 받았지만 서비스로 못 보낸 것인지, 아니면 서비스는 받았지만 포드로 전달하지 못한 것인지 그 경로를 하나씩 역추적해야 하거든요. 이 과정을 제대로 모르면 똑같은 장애를 두고 몇 시간 동안 엉뚱한 곳만 헤매게 돼요.
이 글에서는 당황하지 않고 문제를 해결할 수 있도록 장애 증상별 원인 분석법과 로그를 통해 범인을 검거하는 방법, 그리고 상황별 복구 시나리오를 실전 중심으로 정리했어요. 이 글을 끝까지 읽고 나면, 어떤 에러 코드가 떠도 침착하게 다음 단계로 넘어갈 수 있는 능력을 갖추게 될 거예요.
이 글에서 다루는 핵심 내용
- 대표적인 인그레스 에러 코드(404, 502, 503, 504)의 의미와 원인
- 인그레스 컨트롤러 로그와 쿠버네티스 이벤트를 활용한 진단법
- 서비스, 엔드포인트, 포드를 잇는 연결 고리 점검 순서
- 설정 실수와 인증서 문제를 해결하는 실전 복구 가이드
장애 진단 전 반드시 체크해야 할 기본 구조
문제를 해결하기 위해 무작정 명령어를 입력하기 전에, 우리가 점검해야 할 전체적인 데이터 흐름을 머릿속에 그려야 해요. 인그레스 트러블슈팅은 결국 연결 고리(Chain)를 찾는 과정이에요. 외부 요청이 들어와서 실제 애플리케이션 포드에 도달하기까지는 크게 네 가지 단계를 거쳐요.
첫 번째는 클라이언트의 요청이 외부 로드밸런서를 거쳐 인그레스 컨트롤러(Ingress Controller)에 도달하는 단계예요. 두 번째는 컨트롤러가 인그레스 규칙(Rule)을 읽고 적절한 서비스(Service)를 찾아내는 단계죠. 세 번째는 서비스가 해당 서비스에 연결된 엔드포인트(Endpoint), 즉 포드의 IP를 확인하는 단계예요. 마지막 네 번째는 포드가 요청을 받아 처리하고 응답을 돌려주는 단계예요. 이 중 단 한 곳이라도 끊겨 있다면 사용자는 에러 화면을 보게 돼요.
인그레스 트러블슈팅을 시작하기 전, 반드시
kubectl 권한이 충분한지 확인하세요. 특히 Ingress 네임스페이스의 로그를 볼 수 있는 권한이 있어야 효과적인 진단이 가능해요.효율적인 진단을 위해 각 구성 요소가 담당하는 역할을 비교해 볼게요. 어떤 레이어에서 문제가 발생했는지 판단하는 기준이 될 거예요.
| 구성 요소 | 주요 역할 | 장애 시 나타나는 특징 |
|---|---|---|
| Ingress | 라우팅 규칙 정의 (Host, Path) | 404 Not Found, 설정 미반영 |
| Ingress Controller | 실제 트래픽 처리 및 로드밸런싱 | 502/503/504 에러, 로그 에러 |
| Service | 포드 집합에 대한 추상화된 IP 제공 | 엔드포인트 없음, 연결 실패 |
| Pod | 애플리케이션 실제 실행 | CrashLoopBackOff, Readiness 실패 |
진단을 시작하기 전에 여러분의 환경이 아래 체크리스트를 만족하는지 먼저 확인해 보세요. 의외로 아주 사소한 부분에서 문제가 시작되는 경우가 많거든요.
진단 전 필수 체크리스트
- 인그레스 컨트롤러 상태: 컨트롤러 포드가 정상적으로 동작 중인가요?
- 인그레스 클래스(Ingress Class): 사용 중인 컨트롤러에 맞는 클래스가 지정되어 있나요?
- 네트워크 정책(Network Policy): 컨트롤러에서 서비스로 가는 트래픽이 허용되어 있나요?
- TLS 인증서: Secret에 정의된 인증서가 유효하고 존재하나요?
문제를 해결하겠다고 설정을 무작정 바꾸는 것은 금물이에요. 현재 설정값과 실제 동작 상태를 먼저
kubectl get 명령어로 백업하거나 기록해 두는 습관을 가지세요.실전! 단계별 장애 원인 분석과 복구 절차
이제 본격적으로 문제를 해결해 볼 시간이에요. 인그레스 장애는 보통 에러 코드로 그 정체를 드러내요. 에러 코드를 확인했다면, 그 코드가 의미하는 바를 따라 범위를 좁혀나가면 돼요. 무작정 모든 걸 뒤지는 게 아니라, 에러 코드 → 컨트롤러 로그 → 서비스/엔드포인트 → 포드 순으로 내려가는 전략이 가장 빨라요.
STEP 1. 에러 코드로 범인 좁히기
브라우저나 API 클라이언트에서 어떤 응답을 주는지 확인하는 게 첫걸음이에요. 응답 코드는 현재 트래픽이 어디서 막혔는지를 알려주는 아주 결정적인 단서예요.
- 404 Not Found: 인그레스 규칙(Rule) 설정이 잘못되었을 가능성이 커요. 요청한 호스트 이름(Host)이나 경로(Path)가 인그레스 설정과 정확히 일치하는지 확인해야 해요. 특히 마지막 슬래시(/) 유무에 따라 404가 발생하기도 하니 주의하세요.
- 502 Bad Gateway: 인그레스 컨트롤러가 요청을 받았지만, 뒤에 있는 서비스나 포드로 연결을 시도했을 때 거절당한 상태예요. 포드가 죽었거나, 서비스의 포트 설정이 틀렸거나, 혹은 앱이 요청을 받을 준비가 안 된 상태일 때 주로 발생해요.
- 503 Service Unavailable: 컨트롤러가 요청을 보낼 대상(엔드포인트)을 전혀 찾지 못했을 때 나타나요. 서비스와 포드의 라벨(Label)이 일치하지 않아 연결 고리가 끊어진 경우가 대부분이에요.
- 504 Gateway Timeout: 요청은 전달되었지만, 포드가 응답을 너무 늦게 주고 있는 상황이에요. 애플리케이션의 처리 속도가 느리거나, 데이터베이스 쿼리 지연, 혹은 네트워크 타임아웃 설정이 너무 짧을 때 발생해요.
STEP 2. 인그레스 컨트롤러 로그와 이벤트 분석
에러 코드를 확인했다면 이제 컨트롤러의 속마음을 들어볼 차례예요. 인그레스 컨트롤러의 로그는 가장 강력한 진단 도구예요. Nginx Ingress Controller를 사용 중이라면 해당 네임스페이스의 로그를 확인해 보세요.
kubectl logs -n ingress-nginx <[컨트롤러-포드-이름]> 명령어를 통해 실시간 로그를 관찰할 수 있어요. 로그에 “upstream connect error”나 “no endpoints available” 같은 메시지가 보인다면, 문제는 인그레스 규칙 자체가 아니라 그 뒤에 있는 서비스나 포드 쪽에 있다는 것을 확실히 알 수 있어요.
또한, kubectl describe ingress <[인그레스-이름]> 명령어를 꼭 사용하세요. 이 명령어는 인그레스 객체가 생성될 때 발생한 이벤트(Event)를 보여줘요. 만약 인증서(Secret)를 찾지 못했다면 여기서 “Secret not found”라는 명확한 에러 메시지를 확인할 수 있어요. 설정 파일에 오타가 있어 인그레스가 제대로 생성되지 않았을 때도 이곳에 기록이 남아요.
STEP 3. 서비스와 엔드포인트 연결 고리 점검
컨트롤러 로그에서 서비스 쪽 문제라는 신호가 왔다면, 이제 서비스를 타고 내려가야 해요. 많은 개발자가 인그레스는 잘 만들었지만, 정작 서비스와 포드를 이어주는 연결 고리를 놓쳐서 고생하곤 해요.
가장 먼저 확인해야 할 것은 엔드포인트(Endpoints)의 존재 여부예요. 서비스를 생성했다고 해서 바로 트래픽이 흐르는 게 아니에요. 서비스의 셀렉터(Selector)가 포드의 라벨과 완벽하게 일치해야만 쿠버네티스가 자동으로 엔드포인트를 생성해 줘요. 아래 명령어로 확인해 보세요.
kubectl get endpoints <[서비스-이름]>
만약 결과값의 ENDPOINTS 항목이 <<none>으로 나온다면, 100% 확률로 서비스의 셀렉터와 포드의 라벨이 서로 다른 거예요. 예를 들어, 서비스는 app: my-web을 찾고 있는데, 실제 포드는 app: web-app이라는 라벨을 달고 있다면 연결은 영원히 이어지지 않아요. 이럴 땐 포드의 라벨을 수정하거나 서비스의 셀렉터를 수정해서 둘을 맞춰줘야 해요.
STEP 4. 경로(Path) 및 호스트(Host) 규칙 검증
모든 연결이 정상인데 404 에러가 지속된다면, 인그레스의 경로 설정 규칙을 의심해야 해요. 최근 쿠버네티스 버전에서는 인그레스 경로 작성 방식이 조금 더 엄격해졌거든요. 특히 ImplementationSpecific이나 Prefix 같은 경로 타입 설정이 중요해요.
사용자가 /api/v1/users로 요청을 보냈는데, 인그레스 규칙에는 /api로만 되어 있다면, 컨트롤러가 이를 어떻게 처리할지 설정에 따라 달라져요. 만약 경로 재작성(Rewrite Target) 기능이 필요하다면, 인그레스 어노테이션(Annotation)에 nginx.ingress.kubernetes.io/rewrite-target 설정을 정확히 넣어줬는지 확인해야 해요. 이 설정 하나로 경로가 꼬여서 404가 발생하는 사례는 정말 셀 수 없이 많아요.
경로 규칙을 테스트할 때는
curl -v 명령어를 활용하세요. 헤더 정보를 포함해서 요청을 보내면, 어떤 호스트로 요청이 가는지, 응답 헤러는 무엇인지 더 상세히 알 수 있어요.STEP 5. TLS 인증서와 Secret 상태 확인
HTTPS를 사용하는 서비스라면 마지막으로 인증서 문제를 확인해야 해요. 웹사이트에 접속했을 때 “연결이 비공개로 설정되어 있지 않습니다”라는 경고가 뜬다면 인그레스의 TLS 설정 문제입니다.
먼저, 인그레스 설정 파일의 tls: 섹션에 적힌 secretName이 실제 존재하는 Secret인지 확인하세요. kubectl get secret 명령어로 해당 이름의 Secret이 있는지, 그리고 그 안에 tls.crt와 tls.key 파일이 잘 들어있는지 체크해야 해요. 만약 인증서가 만료되었다면, 새 인증서를 Secret으로 업데이트하는 것만으로도 문제는 즉시 해결돼요.
자주 하는 실수와 해결법
실무에서 인그레스 장애를 일으키는 가장 흔한 실수들을 정리했어요. 비슷한 상황에 처해 있다면 이 부분을 먼저 살펴보세요.
- ❌ 실수: 인그레스 클래스(Ingress Class)를 지정하지 않음
→ 왜 발생하는가: 여러 개의 컨트롤러가 있는 클러스터에서 어떤 컨트롤러를 사용할지 몰라 요청이 방치됨
→ ✅ 해결법: 인그레스 설정에ingressClassName: nginx와 같이 사용할 클래스를 명시하세요. - ❌ 실수: 서비스 포트와 타겟 포트(TargetPort) 불일치
→ 왜 발생하는가: 서비스가 80번 포트로 요청을 받는데, 실제 포드는 8080번에서 대기 중인 경우
→ ✅ 해결법: 서비스 정의서의targetPort값이 포드의containerPort와 정확히 일치하는지 확인하세요. - ❌ 실수: 경로 규칙(Path Type) 설정 오류
→ 왜 발생하는가: Prefix와 Exact 타입의 차이를 혼동하여 의도치 않은 경로로 요청이 들어감
→ ✅ 해결법: 하위 경로까지 모두 허용하려면Prefix타입을 사용하고, 정확한 일치를 원하면Exact를 사용하세요. - ❌ 실수: TLS Secret 이름 오타
→ 왜 발생하는가: 인그레스 파일에 적은 Secret 이름과 실제 생성된 이름이 미세하게 다름
→ ✅ 해결법:kubectl get secret결과와 인그레스 YAML 파일을 눈으로 직접 대조하세요. - ❌ 실수: Readiness Probe 실패로 인한 엔드포인트 누락
→ 왜 발생하는가: 포드는 떠 있지만, 앱이 아직 준비되지 않아 쿠버네티스가 트래픽을 보내지 않음
→ ✅ 해결법: 포드의 상태를 확인하고,kubectl describe pod을 통해 프로브(Probe) 실패 로그를 확인하세요.
자주 묻는 질문
Q. 인그레스에서 404 에러가 나는데 서비스는 정상이에요. 어떻게 하죠?
먼저 인그레스의 host 설정과 요청하는 도메인이 일치하는지 보세요. 그다음 path 설정이 /로 시작하는지, 그리고 경로 타입이 제대로 설정되었는지 확인해야 해요.
Q. 502 Bad Gateway 에러가 너무 자주 발생해요.
애플리케이션 포드가 요청을 처리하는 시간이 너무 길거나, 포드가 순간적으로 재시작(Restart)되고 있을 가능성이 커요. 포드의 restartCount를 확인하고, 앱의 로그를 통해 연결 거부(Connection Refused)가 발생하는지 보세요.
Q. 인그레스 컨트롤러 로그를 볼 수 있는 방법이 궁금해요.
보통 인그레스 컨트롤러는 별도의 네임스페이스(예: ingress-nginx)에 설치되어 있어요. kubectl get pods -A로 컨트롤러 포드를 찾은 뒤, 해당 네임스페이스를 지정해 로그를 확인하면 돼요.
Q. SSL 인증서를 적용했는데 브라우저에서 경고가 떠요.
Secret에 인증서와 키가 제대로 들어있는지, 그리고 인그레스 설정에서 tls: 섹션의 hosts 리스트에 현재 사용하는 도메인이 포함되어 있는지 확인하세요.
Q. 엔드포인트가 <<none>으로 나와요.
서비스의 selector가 포드의 labels와 일치하는지 확인하는 게 가장 빠릅니다. 라벨 이름 하나, 오타 하나만 있어도 연결되지 않아요.
장애 대응을 끝내며: 안정적인 운영을 위한 다음 단계
인그레스 장애를 해결하는 과정은 마치 복잡한 미로를 헤쳐 나가는 것과 같아요. 하지만 당황하지 않고 에러 코드를 통해 범위를 좁히고, 로그와 엔드포인트를 차례로 점검한다면 어떤 문제든 반드시 해결할 수 있어요. 오늘 다룬 내용을 바탕으로 다음의 체크리스트를 꼭 기억해 두세요.
- 에러 코드는 문제의 위치를 알려주는 나침반이에요 (404는 설정, 502/503은 연결 문제).
- 인그레스 컨트롤러 로그는 가장 강력한 진단 도구예요.
- 서비스와 포드의 라벨(Label)이 일치하는지 반드시 확인하세요.
- 엔드포인트(Endpoints)가 존재해야 트래픽이 흐를 수 있어요.
- TLS 인증서는 Secret의 존재 유무와 도메인 일치 여부가 핵심이에요.
- 설정을 변경하기 전에는 반드시 현재 상태를 기록해 두세요.
장애를 해결했다면, 이제는 똑같은 문제가 재발하지 않도록 대비할 차례예요. 단순히 불을 끄는 것을 넘어, 시스템을 더 단단하게 만드는 과정이 필요하거든요.
운영 안정성을 위한 제안
- 모니터링 강화: 인그레스 컨트롤러의 메트릭을 Prometheus로 수집하고, 에러율이 급증할 때 알람이 오도록 설정하세요.
- GitOps 도입: 인그레스 설정을 수동으로 바꾸지 말고, Git에 저장된 YAML 파일을 통해 관리하여 설정 변경 이력을 남기세요.
- 정기적 인증서 점검: 인증서 만료 전에 자동으로 갱신되는 Let’s Encrypt와 Cert-Manager를 도입하는 것을 추천해요.
오늘 정리해 드린 가이드가 여러분의 평온한 밤을 지켜주는 데 도움이 되었으면 좋겠어요. 실습 환경에서 직접 적용해 보시다가 막히는 부분이나, 이해가 잘 안 되는 상황이 있다면 댓글로 질문을 남겨 주세요. 함께 고민하면 해결책을 찾을 수 있을 거예요.
함께 읽으면 좋은 글:
– 쿠버네티스 인그레스 기본 개념 정리
– 클러스터 구축 및 네트워크 기초 입문