Helm으로 Kubernetes에 배포하기
BostonIvy Helm 차트에는 서버(API, MCP, CalDAV, 백그라운드 작업), 같은 주소에서 제공되는 BostonIvy Web, 그리고 빠르게 시작할 수 있는 내장 PostgreSQL이 들어 있습니다. 서버를 릴리스할 때마다 새 차트가 oci://ghcr.io/ivylabsapp/charts/bostonivy에 게시됩니다.
시작하기 전에
- Kubernetes 클러스터,
kubectl, 그리고 OCI 레지스트리에서 차트를 설치할 수 있는 Helm 3.8 이상. - 인그레스 컨트롤러(예시에서는 ingress-nginx)와 이를 가리키는 도메인 이름. 없어도 체험은 할 수 있습니다. 인그레스 없이 체험하기를 참고하세요.
read:packages범위가 있는 GitHub 토큰. 이미지와 차트는 GitHub Container Registry의 비공개 패키지입니다.
설치
네임스페이스와 비공개 이미지를 받기 위한 pull 시크릿을 만듭니다.
kubectl create namespace bostonivy kubectl -n bostonivy create secret docker-registry ghcr \ --docker-server=ghcr.io --docker-username=<GitHub 사용자 이름> --docker-password=<read:packages 권한이 있는 토큰>차트를 받을 수 있도록 Helm을 레지스트리에 로그인시킵니다.
echo "$GITHUB_TOKEN" | helm registry login ghcr.io -u <GitHub 사용자 이름> --password-stdin설정을 파일(예:
values.yaml)에 적습니다.url은 필수이며 메일 속 링크, 공유 링크, OAuth와 OIDC 콜백에 쓰입니다.url: https://tasks.example.com imagePullSecrets: - name: ghcr ingress: enabled: true className: nginx annotations: # 실시간 업데이트는 /api/v1/realtime의 장시간 WebSocket이며, 업로드는 최대 64 MiB nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/proxy-body-size: 64m tls: - secretName: bostonivy-tls hosts: [tasks.example.com]bostonivy-tls는 도메인의 인증서입니다. 직접 만든 TLS 시크릿이나 cert-manager가 만들어 주는 것을 씁니다.설치합니다.
helm install ivy oci://ghcr.io/ivylabsapp/charts/bostonivy --version 0.7.0 -n bostonivy -f values.yaml이 페이지의 예시는 릴리스 이름을
ivy로 하므로 리소스 이름은ivy-bostonivy-…가 됩니다. bostonivy-os를 체크아웃했다면deploy/helm/bostonivy에서 설치할 수도 있습니다.
첫 관리자 만들기
설치가 끝나면 Helm도 이 단계를 보여 줍니다. 비밀번호는 화면에 표시되지 않고 입력됩니다.
printf 'Password: '; read -rs PW; echo
printf '%s\n' "$PW" | kubectl -n bostonivy exec -i deploy/ivy-bostonivy-server -- bostonivy admin create-user <사용자 이름> <이메일> --admin
unset PW
서버 시크릿 백업하기
서버 시크릿과 내장 데이터베이스 비밀번호는 설치할 때 생성되고, 업그레이드할 때마다 유지되며, 시크릿 ivy-bostonivy-secrets에 저장됩니다. Helm은 제거할 때도 이 시크릿을 지우지 않습니다. 모든 서명 키와 암호화 키는 서버 시크릿에서 파생됩니다. 잃어버리면 모두 다시 로그인해야 하고, 저장된 TOTP와 webhook 시크릿도 더 이상 읽을 수 없습니다. 지금 안전한 곳에 복사해 두세요.
kubectl -n bostonivy get secret ivy-bostonivy-secrets -o jsonpath='{.data.auth-secret}' | base64 -d
직접 정한 시크릿을 쓰려면 auth.secret을 설정하거나, 직접 관리하는 시크릿의 auth-secret 키에 넣고 auth.existingSecret을 설정합니다.
인그레스 없이 체험하기
ingress.enabled는 끈 채로 auth.cookieSecure=false를 설정하고, 웹 서비스를 내 컴퓨터로 포워딩합니다.
kubectl -n bostonivy port-forward svc/ivy-bostonivy-web 8080:80
그리고 http://localhost:8080 을 엽니다. HTTPS로 서비스하게 되면 auth.cookieSecure를 다시 true로 바꾸세요.
설정 값
| 값 | 기본값 | 하는 일 |
|---|---|---|
url |
필수 | 사용자가 BostonIvy에 접속하는 주소. 링크, OAuth, OIDC 콜백에 쓰입니다 |
imagePullSecrets |
[] |
비공개 이미지를 받기 위한 pull 시크릿 |
auth.secret, auth.existingSecret |
자동 생성 | 서버 시크릿. 직접 지정하거나 직접 만든 시크릿(키 auth-secret)에서 가져옵니다 |
auth.cookieSecure |
true |
HTTPS 뒤에서는 켜 두세요. 일반 http에서 체험할 때만 끕니다 |
database.url, database.existingSecret |
내장 | 외부 PostgreSQL 16 이상. 비워 두면 내장 데이터베이스를 씁니다 |
postgresql.enabled |
true |
클러스터 안의 PostgreSQL 하나. 체험이나 소규모 구성용 |
mail.smtpUrl, mail.from |
비어 있음 | 예: smtp://user:password@host:587 또는 log. 비워 두면 메일을 보내지 않습니다 |
config |
비어 있음 | TOML로 쓰는 추가 서버 설정. [[auth.oidc]] 로그인 제공자 등 |
server.env, server.envFrom |
[] |
그 밖의 BOSTONIVY_<섹션>__<키> 설정 |
server.replicas |
1 |
2개 이상이면 S3 스토리지와 worker.separate가 필요합니다 |
worker.separate, worker.replicas |
false, 1 |
백그라운드 작업(메일, webhook, 알림, 유지 관리)을 별도 Pod에서 실행합니다 |
persistence.* |
10Gi, ReadWriteOnce | 로컬 스토리지를 쓸 때의 첨부 파일과 아바타 |
web.image.tag |
0.2.0 |
제공할 BostonIvy Web 릴리스 |
ingress.* |
꺼짐 | 호스트는 기본적으로 url의 호스트입니다. 실시간 업데이트를 위해 긴 WebSocket 읽기를 허용하세요 |
데이터베이스
내장 PostgreSQL은 Pod 하나뿐이라 체험이나 소규모 구성에 알맞습니다. 운영 환경에서는 관리형 데이터베이스나 오퍼레이터를 쓰고, BostonIvy가 그쪽을 바라보게 하세요.
postgresql:
enabled: false
database:
url: postgres://bostonivy:<비밀번호>@db.example.com:5432/bostonivy
주소를 직접 만든 시크릿에 넣고 database.existingSecret을 설정해도 됩니다. BostonIvy에는 PostgreSQL 16 이상이 필요합니다.
메일, 로그인, 그 밖의 설정
메일:
mail.smtpUrl과mail.from.log로 두면 메일을 서버 로그에 기록하므로 체험할 때 편리합니다.TOML 서버 설정:
config에는 TOML을 넣을 수 있습니다. 예를 들어 로그인 제공자:config: | [[auth.oidc]] id = "google" # 나머지 항목은 bostonivy.example.toml 참고그 밖의 설정:
server.env에BOSTONIVY_<섹션>__<키>형식의 변수를 넣습니다. 전체 설정은 bostonivy-os의bostonivy.example.toml에 있습니다.
확장하기
로컬에 저장하는 파일을 빼면 서버 자체는 상태를 갖지 않습니다. 레플리카를 여러 개 두려면:
server:
replicas: 3
env:
- name: BOSTONIVY_STORAGE__KIND
value: s3
# 그리고 bostonivy.example.toml의 [storage]에 있는 버킷 설정
worker:
separate: true
persistence:
enabled: false
- 파일은 Pod 하나에만 마운트할 수 있는 볼륨 대신 S3 호환 스토리지에 저장합니다.
worker.separate는 백그라운드 작업을 별도 Pod로 옮기므로, 작업이 서버 레플리카마다가 아니라 한 번만 실행됩니다.- 레플리카끼리 요청 제한 카운터를 공유하려면
server.env에BOSTONIVY_REDIS__URL을 설정하세요. - 실시간 업데이트, 세션 폐기, 플러그인은 PostgreSQL을 통해 레플리카 사이에 동기화되므로 다른 구성 요소는 필요 없습니다.
업그레이드와 백업
새 릴리스의 차트로 업그레이드합니다.
helm upgrade ivy oci://ghcr.io/ivylabsapp/charts/bostonivy --version <새 버전> -n bostonivy -f values.yaml
서버 Pod가 차례로 교체되고, 새 버전이 시작할 때 데이터베이스를 마이그레이션합니다. 마이그레이션은 추가만 하고 삭제하지 않으므로 백업과 함께라면 되돌릴 수 있습니다.
백업할 것은 세 가지입니다.
데이터베이스. 내장 PostgreSQL을 쓸 때:
kubectl -n bostonivy exec ivy-bostonivy-postgresql-0 -- pg_dump -U bostonivy bostonivy > backup.sql첨부 파일과 아바타: 파일 볼륨 또는 버킷.
서버 시크릿:
auth-secret(서버 시크릿 백업하기 참고).