Search

OpenFaaS의 함수는 HTTP 요청을 어떻게 처리할까?

서버리스(Serverless) 플랫폼인 OpenFaaS를 사용하다가 한 가지 궁금한 점이 생겼습니다.
“내가 작성한 간단한 스크립트나 함수 코드는 어떻게 사용자의 HTTP 요청을 받고 이를 처리하여 다시 결과값을 내보낼 수 있는거지?”
공식 문서 및 GitHub 등을 통해 Watchdog 라는 핵심 컴포넌트가 이를 수행하고 있다는 것을 알게 되었습니다.

Watchdog란?

Watchdog는 OpenFaaS에서 함수 인스턴스(Pod) 내부에 포함된 경량 HTTP 서버로서, 외부 요청을 함수 코드로 연결하는 중간 인터페이스 역할을 합니다.
Watchdog의 주된 역할은:
1.
HTTP 요청 수신: OpenFaaS Gateway로부터 들어오는 모든 HTTP 요청을 받습니다.
2.
사용자 함수 코드 실행: 수신한 요청 데이터를 함수 코드로 전달하고 실행시킵니다.
3.
HTTP 응답 반환: 함수 코드의 실행 결과를 다시 HTTP 응답으로 포장하여 Gateway로 돌려보냅니다.
이 과정은 두 가지 대표적인 방식으로 이뤄집니다. 바로 Classic 모드와 HTTP 모드 입니다.

Classic Watchdog (Serializing Mode)

유닉스의 “모든 것은 파일(프로세스)이다”라는 철학이 담긴 방식입니다. 각 HTTP 요청마다 완전히 격리된 별개의 프로세스를 생성(Fork)하여 처리합니다.

동작 흐름

1.
요청 대기: Watchdog 프로세스는 Pod 내부의 8080 포트에서 Gateway로부터 들어올 HTTP 요청을 대기합니다.
2.
프로세스 복제 및 실행 (fork & exec): 요청이 들어오면, Watchdog은 fork() 시스템 콜을 호출해 자기 자신을 복제한 자식 프로세스를 생성합니다. 그리고 즉시 exec()를 통해 이 자식 프로세스의 메모리 공간을 작성한 함수 코드로 덮어씌워 함수를 실행키십니다.
a.
fork(): 나와 똑같은 프로세스를 하나 더 만들어
b.
exec(): 새로 만든 프로세스는 이제 함수 코드를 실행해
3.
데이터 전달 (stdin): 수신한 HTTP 요청의 Body 데이터를 자식 프로세스의 표준 입력(Standard Input, stdin)으로 전달(piping)합니다. 함수 코드 입장에서는 마치 터미널에서 입력을 받는 것과 동일합니다.
4.
결과 반환 (stdout): 함수 코드는 stdin으로 받은 데이터를 처리한 후, 그 결과를 표준 출력(Standard Output, stdout)으로 내보냅니다.
5.
응답 생성 및 전달: 부모 프로세스(Watchdog)는 자식 프로세스가 종료될 때까지 기다린 후, stdout 결과를 모아 HTTP 200 OK 응답과 함께 Gateway로 보냅니다. 만약 프로세스가 비정상 종료(Exit Code ≠ 0)하면 HTTP 500 에러를 반환합니다.
이 방식은 각 요청이 완벽히 격리된다는 장점이 있지만, 요청마다 프로세스를 생성/파괴하는 오버헤드가 있어 처리량이 많은 서비스에는 불리할 수 있습니다.

HTTP Watchdog (of-watchdog in HTTP Mode)

Classic Watchdog의 성능 한계를 극복하기 위해 등장한 방식입니다. 요청마다 프로세스를 만드는 대신, 함수 코드가 자체적으로 웹 서버(Ex. Python Flask, Node.js Express)를 내장한 Long-running process로 동작합니다.

동작 흐름

1.
사전 실행 (Warm Process): Pod가 시작될 때, 함수 코드는 내부 웹 서버를 실행한 상태로 대기합니다. (예: 8080 포트는 Watchdog, 내부는 8081 등)
2.
요청 프록시 (Proxy): Watchdog(8080)이 요청을 받으면, 이를 그대로 함수 내부의 웹 서버(upstream_url)로 전달(Reverse Proxy)합니다.
3.
자체 처리 및 응답: 함수 코드는 내장된 웹 프레임워크를 통해 직접 HTTP 요청을 파싱하고 비즈니스 로직을 처리한 후, HTTP 응답을 생성합니다.
4.
응답 역-프록시 (Reverse Proxy): 함수가 생성한 응답은 다시 Watchdog을 거쳐 Gateway로 전달됩니다.
이 방식은 프로세스 생성 오버헤드가 없어 응답 속도가 훨씬 빠르고 동시성 처리에 유리합니다. 데이터베이스 연결(Connection Pool) 등을 재사용할 수 있어 현대적인 서버리스 아키텍처의 표준으로 자리 잡았습니다.
“50대의 추교현이 20대의 추교현에게 감사할 수 있도록 하루하루 최선을 다해 살고 있습니다.”
The End.