1. 라이브러리
  2. 포트
  3. 포트 설정

업데이트됨 1개월 전

모니터링 대시보드에는 모든 포트가 열려 있다고 표시됩니다. 모든 시스템 정상. 모든 지표가 초록불입니다.

그런데 사용자들이 로그인을 할 수 없습니다. 애플리케이션이 응답 시간을 초과합니다. 뭔가 분명히 망가졌습니다.

다시 확인해 봅니다. 포트 443: 열림. 포트 5432: 열림. 아무것도 작동하지 않는데 어떻게 전부 "정상"일 수 있을까요?

이것이 바로 포트 상태와 서비스 상태의 차이입니다. 이 차이를 이해하면 모니터링을 바라보는 시각이 달라집니다.

"포트 열림"이 실제로 의미하는 것

스캐너가 포트를 "열림"으로 보고할 때, 이는 단 한 가지만 확인하는 것입니다: 해당 주소의 무언가가 TCP 핸드셰이크를 수락했다는 것. 전송 계층이 응답했다는 것.

이것은 다음에 대해 아무것도 알려주지 않습니다:

  • 실제로 무엇이 수신 대기 중인지
  • 기대하는 서비스가 맞는지
  • 그 서비스가 실제로 제 역할을 할 수 있는지

웹 서버는 그 뒤의 애플리케이션이 충돌한 상태에서도 포트 80이 열려 있을 수 있습니다. 운영체제의 TCP 스택은 계속 연결을 수락하지만—그 연결들은 아무 데도 이어지지 않습니다.

당신을 괴롭히는 시나리오들

서비스는 충돌했지만 포트는 열려 있는 경우

가장 흔한 경우입니다. 데이터베이스 서버가 시작되어 포트 5432에 바인딩된 후, 메모리 오류로 충돌합니다. 충돌 방식에 따라 운영체제가 그 수신 소켓을 잠시 유지하거나, 다른 프로세스가 이를 상속받을 수 있습니다. 포트 스캐너는 "열림"을 봅니다. 연결 시도는 중단되거나 끊어집니다.

모니터링은 정상이라고 합니다. 애플리케이션은 데이터베이스에 접근하지 못합니다.

서비스가 뜨기 전에 포트가 먼저 열려 있는 경우

소켓 활성화(systemd 등)를 사용하는 시스템에서는 더 이상한 일이 생깁니다. init 시스템이 포트에서 대기하다가 연결이 도착할 때만 실제 서비스를 시작합니다. 그 사이—또는 시작이 실패하면—포트는 열려 있지만, 아직 실행되지 않은 서비스를 향해 연결을 받아들이고 있습니다.1

운영체제가 지키지 못할 약속을 받아들이고 있는 셈입니다.

엉뚱한 서비스가 수신 대기 중인 경우

포트 충돌은 또 다른 종류의 함정을 만듭니다. 포트 8080에서 내 애플리케이션이 응답하길 기대합니다. 그런데 개발자가 그 포트에 테스트 서버를 켜놓은 채로 뒀습니다. 포트는 열려 있습니다. 연결도 됩니다. 그런데 모든 요청에서 엉뚱한 응답이 돌아옵니다. 완전히 잘못된 서비스이기 때문입니다.

개발 환경에서, 그리고 마이그레이션이 불완전하게 끝난 후에 이런 일이 끊임없이 발생합니다.

서비스는 실행 중이지만 제 기능을 못 하는 경우

가장 파악하기 어려운 장애 유형입니다. 프로세스는 실행 중이고, 포트는 열려 있고, 서비스는 연결을 수락하지만—실제로는 아무것도 할 수 없습니다. 데이터베이스 연결이 실패했습니다. 설정 파일에 오류가 있습니다. 필요한 디렉터리가 존재하지 않습니다.

서비스는 살아 있지만 무용지물입니다.

포트 스캔 vs. 서비스 프로브

포트 스캔은 전송 계층에서 작동합니다. SYN을 보내고, SYN-ACK를 받으면 포트가 열린 것입니다. 수 밀리초 만에 끝나고, 네트워크 연결 상태를 알려줍니다.

서비스 프로브는 애플리케이션 계층에서 작동합니다. 실제 HTTP 요청을 보내고, 데이터베이스에 인증을 시도하고, 서비스에게 실제 작업을 요청한 뒤 처리 가능한지 확인합니다.

포트 스캔이 묻는 것: 누군가 수신 대기 중인가?

서비스 프로브가 묻는 것: 실제로 도움이 되는가?

포트 스캔은 빠르고 비용이 적습니다. 호스트 다운, 방화벽 차단, 아무것도 수신 대기하지 않는 상황 같은 완전한 장애를 잡아냅니다. 하지만 무언가가 수신 대기 중이면서도 고장난 경우는 모두 놓칩니다.

서비스 프로브는 더 느리고 프로토콜 지식이 필요합니다. 하지만 정작 중요한 질문에 답합니다: 이 서비스가 요청을 처리할 수 있는가?

문제가 생겼을 때: 진실 찾기

먼저 확인할 것: 실제로 무엇이 수신 대기 중인가?

ss -tlnp | grep :PORT
lsof -i :PORT

이 명령은 해당 포트에 바인딩된 프로세스 ID와 이름을 보여줍니다. 이것만으로도 문제가 바로 드러나는 경우가 많습니다—엉뚱한 서비스, 좀비 프로세스, 예상치 못한 소유자.

그다음엔 직접 통신을 시도해 보세요:

nc -v localhost PORT
curl -v http://localhost:PORT

수동으로 연결을 시도하면 자동화된 도구가 놓치는 것이 드러납니다. 실제 응답(또는 응답 없음), 오류 메시지, 예상과 다른 동작을 직접 확인할 수 있습니다.

로그를 확인하세요. 서비스는 초기화를 전부 마치기 전에 일찌감치 포트에 바인딩하는 경우가 많습니다. 포트가 열리고, 그 이후에 초기화가 실패합니다. 로그에 무엇이 망가졌는지 나와 있습니다.

의존성을 추적하세요. 데이터베이스 연결 문자열, 파일시스템 경로, 상위 서비스. 서비스가 성공적으로 시작된 뒤에도 의존성 하나가 실패하는 순간 무용지물이 될 수 있습니다.

모니터링의 사각지대

포트 가용성만 확인하는 모니터링은 연결성을 알려줄 뿐, 기능성은 알려주지 않습니다.

"포트 443이 열려 있는가?"는 "사용자가 로그인할 수 있는가?"와 다른 질문입니다.

계층화된 모니터링이 이 사각지대를 해소합니다:

포트 확인은 네트워크 장애, 호스트 다운, 방화벽 문제를 잡아냅니다. 빠르고, 비용이 적고, 반드시 필요하지만 이것만으론 부족합니다.

서비스 프로브는 애플리케이션이 프로토콜 요청에 올바르게 응답하는지 검증합니다. HTTP가 200을 반환하고, 데이터베이스가 쿼리를 수락하고, 캐시가 핑에 응답하는지 확인합니다.

기능 점검은 처음부터 끝까지 워크플로 전체를 테스트합니다. 사용자가 실제로 로그인할 수 있는가? 결제 흐름이 완료되는가? 이 수준에서야 여러 서비스에 걸쳐 숨어 있는 장애가 드러납니다.

중요한 시스템이라면 세 가지 모두 필요합니다. 포트 확인은 완전한 장애를 빠르게 잡아냅니다. 서비스 프로브는 애플리케이션 문제를 잡아냅니다. 기능 점검은 서비스 사이의 틈새에 숨어 있는 복잡한 장애를 잡아냅니다.

진짜 질문

포트 테스트가 답하는 것: "누군가 수신 대기 중인가?"

서비스 프로브가 답하는 것: "올바르게 응답할 수 있는가?"

기능 테스트가 답하는 것: "제 역할을 다할 수 있는가?"

현대의 분산 시스템—마이크로서비스, 복잡한 초기화, 계층화된 의존성—에서 서비스는 포트를 열어둔 채 기능만 고장나는 형태로 셀 수 없이 많은 방식으로 실패합니다. 포트는 열려 있습니다. 빈 집에 불만 켜져 있는 꼴입니다.

진정한 신뢰성은 사용자가 실제로 경험하는 것을 테스트하는 데서 옵니다. 실제 요청을 보내고, 실제 응답을 검증하고, 중요한 워크플로를 테스트하세요.

"포트 443이 열려 있음"과 "사용자가 결제를 완료할 수 있음"의 차이가 바로 연결성 모니터링과 기능성 모니터링의 차이입니다.

포트 및 서비스 상태에 관한 자주 묻는 질문

서비스가 충돌한 후에도 포트가 열려 있는 이유는 무엇인가요?

프로세스가 충돌하면 여러 가지 일이 생길 수 있습니다. 충돌이 갑작스러운 경우(세그폴트, kill -9), 커널이 소켓을 정리하고 연결된 클라이언트에 RST를 전송합니다. 하지만 프로세스가 자식 프로세스를 포크했거나 다른 프로세스가 파일 디스크립터를 상속받은 경우, 수신 소켓이 살아남을 수 있습니다. 소켓은 남아 있지만 아무것도 연결을 처리하지 않는 짧은 시간이 있을 수도 있습니다. 전송 계층은 애플리케이션과 독립적으로 동작합니다—애플리케이션 로직이 사라진 것을 알지도 신경 쓰지도 않습니다.

포트에서 올바른 서비스가 수신 대기 중인지 어떻게 확인하나요?

ss -tlnp 또는 lsof -i :PORT로 해당 포트에 바인딩된 프로세스 이름과 ID를 확인하세요. 예상한 프로세스가 맞는지 검토하세요. 직접 연결해서 응답을 확인하는 방법도 있습니다—HTTP 서버는 HTTP 헤더를 반환하고, 데이터베이스는 고유한 프로토콜 핸드셰이크를 가집니다. 잘못된 서비스라면 동작 자체가 다를 것입니다.

소켓 활성화란 무엇이고, 왜 혼란을 일으키나요?

소켓 활성화를 사용하면 init 시스템(systemd 등)이 실제 서비스를 시작하기 전에 먼저 포트에서 대기할 수 있습니다. 연결이 도착하면 init 시스템이 서비스를 기동하고 연결을 넘겨줍니다. 부팅 속도가 빨라지고 온디맨드 서비스가 가능해지지만, 서비스 프로세스가 없거나 시작에 실패한 상황에서도 포트가 열려 연결을 받아들이는 구간이 생깁니다. 클라이언트 입장에서는 서비스가 실행되지 않고 있어도 포트가 열려 있는 것처럼 보입니다.

모니터링에서 포트 확인을 없애야 할까요?

아닙니다. 포트 확인은 네트워크 수준 장애를 빠르게 잡아내는 데 여전히 유용합니다. 빠르고, 비용이 적고, 완전한 장애를 감지합니다. 다만 포트 확인만으로는 충분하지 않습니다. 모니터링을 계층화하세요: 연결성을 위한 포트 확인, 애플리케이션 상태를 위한 서비스 프로브, 종단 간 검증을 위한 기능 테스트. 각 계층은 다른 계층이 놓치는 장애 유형을 잡아냅니다.

출처

이 페이지가 도움이 되었나요?

😔
🤨
😃