# 제로 다운타임 배포를 위한 최소한의 HTTP 프록시, Kamal Proxy

> Clean Markdown view of GeekNews topic #16880. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16880](https://news.hada.io/topic?id=16880)
- GeekNews Markdown: [https://news.hada.io/topic/16880.md](https://news.hada.io/topic/16880.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-09-22T11:33:28+09:00
- Updated: 2024-09-22T11:33:28+09:00
- Original source: [github.com/basecamp](https://github.com/basecamp/kamal-proxy)
- Points: 3
- Comments: 1

## Topic Body

### 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 등이 있음

## Comments



### Comment 29102

- Author: neo
- Created: 2024-09-22T11:33:29+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41608350) 
- '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) 증후군임
