GN⁺: 제로 다운타임 배포를 위한 최소한의 HTTP 프록시, Kamal Proxy
(github.com/basecamp)Kamal Proxy - 최소한의 HTTP 프록시로 무중단 배포를 지원
기능
- Kamal Proxy는 HTTP 프록시로, 무중단 배포를 쉽게 조율할 수 있도록 설계됨
- Kamal Proxy 뒤에서 웹 애플리케이션을 실행하면, 진행 중인 트래픽을 중단하지 않고 변경 사항을 배포할 수 있음
- 애플리케이션의 특별한 협력 없이도 작동 가능함
- Kamal의 일부로 설계되었지만, 독립적으로 또는 다른 배포 도구와 함께 사용할 수 있음
간단한 개요
- 프록시 인스턴스를 실행하려면
kamal-proxy run
명령어를 사용함 - 설정 파일은 없지만, 기본값이 애플리케이션에 맞지 않으면 옵션을 지정할 수 있음
- 예를 들어, 기본 포트 80이 아닌 다른 포트에서 프록시를 실행하려면:
kamal-proxy run --http-port 8080
- 전체 옵션 목록을 보려면
kamal-proxy help run
을 실행함
트래픽 라우팅
- 프록시를 통해 웹 애플리케이션으로 트래픽을 라우팅하려면 애플리케이션 인스턴스를 프록시에
deploy
함 - 인스턴스를 배포하면 프록시에서 사용할 수 있게 되며, 이전에 사용하던 인스턴스를 대체함
- 인스턴스를 지정할 때
hostname:port
형식을 사용함 - 예를 들어:
kamal-proxy deploy service1 --target web-1:3000
- 프록시는
web-1:3000
을service1
서비스 이름으로 등록하고, HTTP 상태 검사를 즉시 시작함 - 인스턴스가 일정 시간 내에 정상 상태가 되지 않으면
deploy
명령어는 배포를 중단하고 비정상 종료 코드를 반환함 - 각 배포는 이전에 배포된 인스턴스의 모든 트래픽을 인계받음
- 새로운 인스턴스가 정상 상태가 되면 모든 새로운 트래픽을 해당 인스턴스로 라우팅함
-
deploy
명령어는 이전 인스턴스에서 트래픽이 완전히 소진될 때까지 기다림 - 따라서
deploy
가 성공적으로 반환되면 이전 인스턴스를 제거해도 진행 중인 요청이 중단되지 않음 - 새로운 인스턴스가 정상 상태가 될 때까지 트래픽이 라우팅되지 않으며, 이전 인스턴스에서 트래픽이 완전히 소진된 후 제거되므로 무중단 배포가 가능함
호스트 기반 라우팅
- 호스트 기반 라우팅을 통해 동일한 서버에서 여러 애플리케이션을 실행할 수 있음
- 인스턴스를 배포할 때 트래픽을 제공할 호스트를 지정할 수 있음
- 예를 들어:
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com
- 이렇게 배포된 인스턴스는 지정된 호스트에 대해서만 트래픽을 받음
- 각 호스트에 대해 고유한 인스턴스를 배포하여 동일한 서버에서 포트 충돌 없이 여러 애플리케이션을 실행할 수 있음
- 특정 호스트는 한 번에 하나의 서비스만 라우팅할 수 있음
- 예를 들어:
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com
후kamal-proxy deploy service2 --target web-2:3000 --host app1.example.com
을 실행하면 오류가 발생함 -
kamal-proxy remove service1
후kamal-proxy deploy service2 --target web-2:3000 --host app1.example.com
을 실행하면 성공함
자동 TLS
- Kamal Proxy는 애플리케이션을 위한 TLS 인증서를 자동으로 획득하고 갱신할 수 있음
- 인스턴스를 배포할 때
--tls
플래그를 추가하여 활성화할 수 있음 - 예를 들어:
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com --tls
환경 변수로 run
옵션 지정
- Docker 컨테이너에서 실행할 때와 같은 환경에서는 환경 변수를 사용하여
run
옵션을 지정하는 것이 편리할 수 있음 - 예를 들어, HTTP 포트를 설정하려면:
kamal-proxy run --http-port 8080
또는HTTP_PORT=8080 kamal-proxy run
- 환경 변수가 다른 것과 충돌할 경우,
KAMAL_PROXY_
접두사를 붙여 구분할 수 있음 - 예를 들어:
KAMAL_PROXY_HTTP_PORT=8080 kamal-proxy run
빌드
- Go 환경이 설정되어 있다면 로컬에서 Kamal Proxy를 빌드할 수 있음:
make
- 또는 Docker 컨테이너로 빌드할 수 있음:
make docker
시도해보기
- 예제 폴더에서 Docker Compose 설정을 확인하여 프록시 명령어를 시도해볼 수 있음
GN⁺의 정리
- Kamal Proxy는 무중단 배포를 지원하는 최소한의 HTTP 프록시로, 애플리케이션의 특별한 협력 없이도 작동함
- 호스트 기반 라우팅과 자동 TLS 기능을 제공하여 여러 애플리케이션을 동일한 서버에서 실행할 수 있음
- 환경 변수로
run
옵션을 지정할 수 있어 Docker와 같은 환경에서 유용함 - 무중단 배포를 위해 트래픽을 새로운 인스턴스로 라우팅하고, 이전 인스턴스에서 트래픽이 완전히 소진될 때까지 기다림
- 비슷한 기능을 제공하는 프로젝트로는 NGINX, HAProxy 등이 있음
Hacker News 의견
-
'deploy' 용어 사용이 혼란스러움
- 'bind', 'intercept', 'proxy' 같은 용어가 더 적절할 것 같음
-
무중단 배포를 위해 전체 시스템을 구축하는 것은 과도함
- Unix 소켓을 지원하는 앱+웹 프록시로도 무중단 배포 가능
-
Kamal 프록시는 Docker Swarm의 문제를 해결하기 위해 존재함
- Cloud 66에서는 Caddy와 Traefik을 사용했음
-
Kamal이 Swarm을 선택한 이유가 궁금함
- 단순함 때문일 수도 있음
- 복잡성은 숨길 수 없고, 결국 자체 프록시를 만들게 됨
-
Kamal 프록시를 사용해보지 않았지만, 지원 문제로 인해 회의적임
- WebSockets, SSE, HTTP/3, 다양한 압축 및 암호화 지원 필요
-
HAProxy가 쉽게 할 수 있는 일 같음
- hitless reload 기능이 있음
-
'트래픽 일시 중지' 패턴을 구현하는지 궁금함
- 몇 초 동안 트래픽을 일시 중지하여 인프라 변경을 수행할 수 있음
-
무중단 배포(ZDD)가 어떻게 작동하는지 궁금함
- 두 버전의 앱이 동시에 실행되고, 새로운 트래픽이 새로운 버전으로 라우팅됨
- DB 마이그레이션 문제는 어떻게 처리되는지 궁금함
-
Kamal 2가 auto-SSL을 지원하고, 한 서버에서 여러 앱을 쉽게 실행할 수 있게 할 것임
-
사용 방법이 이해되지 않음
- 예제에 따르면 'web' 서비스의 4개의 복제본을 시작함
- 무중단 배포를 위해 새로운 타겟에 배포해야 함
-
docker compose up --build --force-recreate web
명령어가 모든 것을 무효화함 - 명확한 지침이 필요함
-
타임아웃을 설정할 수 있는 방법이 있는지 궁금함
-
NIH (Not Invented Here) 증후군임