개요

이 가이드는 사전 구축된 Docker 이미지를 사용하여 Kubernetes(DOKS) 및 관리형 서비스로 DigitalOcean에 CaseBender를 배포하는 과정을 안내합니다.

사전 요구 사항

  1. DigitalOcean 계정
  2. doctl CLI 설치
  3. kubectl 설치
  4. Docker 설치

1단계: 초기 설정

doctl 설치 및 구성

# Homebrew 사용
brew install doctl

# API 토큰으로 인증

doctl auth init

# Container Registry용 Docker 구성

doctl registry login

2단계: Kubernetes 클러스터 생성

# DOKS 클러스터 생성
doctl kubernetes cluster create casebender \
  --region nyc1 \
  --size s-2vcpu-4gb \
  --count 3 \
  --version latest

# kubeconfig 가져오기
doctl kubernetes cluster kubeconfig save casebender

3단계: 관리형 서비스 설정

객체 스토리지용 Spaces 생성

# Spaces 버킷 생성
doctl spaces create casebender-storage \
  --region nyc3

# Spaces 액세스 키 생성
doctl spaces access-key create

# 참고: 액세스 키와 시크릿 키를 안전하게 저장하세요
# 애플리케이션 구성에 필요합니다

관리형 PostgreSQL 생성

# 데이터베이스 클러스터 생성
doctl databases create \
  --engine pg \
  --name casebender-db \
  --region nyc1 \
  --size db-s-2vcpu-4gb \
  --version 14 \
  --num-nodes 1

# 데이터베이스 생성
doctl databases db create casebender-db casebender

# 연결 세부 정보 가져오기
doctl databases connection casebender-db --format ConnectionString

관리형 Redis 생성

# Redis 클러스터 생성
doctl databases create \
  --engine redis \
  --name casebender-redis \
  --region nyc1 \
  --size db-s-1vcpu-2gb \
  --version 7

# 연결 세부 정보 가져오기
doctl databases connection casebender-redis --format ConnectionString

4단계: 컨테이너 레지스트리 구성

# 컨테이너 레지스트리 생성
doctl registry create casebender-registry

# 레지스트리 엔드포인트 가져오기
REGISTRY_ENDPOINT=$(doctl registry get-endpoint)

# CaseBender 이미지 가져오기
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest

# 레지스트리용 이미지 태그 지정
docker tag casebender/casebender:latest registry.digitalocean.com/casebender-registry/app:latest
docker tag casebender/workflow-processor:latest registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker tag casebender/misp-processor:latest registry.digitalocean.com/casebender-registry/misp-processor:latest

# 이미지 푸시
docker push registry.digitalocean.com/casebender-registry/app:latest
docker push registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker push registry.digitalocean.com/casebender-registry/misp-processor:latest

# Kubernetes 클러스터에 레지스트리 추가
doctl kubernetes cluster registry add casebender

5단계: Kubernetes에 배포

네임스페이스 생성

kubectl create namespace casebender

시크릿 생성

# 데이터베이스 및 Redis용 시크릿 생성
kubectl create secret generic db-credentials \
  --namespace casebender \
  --from-literal=postgres-url="postgresql://doadmin:password@casebender-db-do-user-1234567-0.b.db.ondigitalocean.com:25060/casebender?sslmode=require" \
  --from-literal=redis-url="rediss://default:password@casebender-redis-do-user-1234567-0.b.db.ondigitalocean.com:25061"

# 애플리케이션용 시크릿 생성
kubectl create secret generic app-secrets \
  --namespace casebender \
  --from-literal=auth-secret="your-auth-secret" \
  --from-literal=auth-salt="your-auth-salt"

애플리케이션 배포

deployment.yaml 생성:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: casebender-app
  namespace: casebender
spec:
  replicas: 2
  selector:
    matchLabels:
      app: casebender-app
  template:
    metadata:
      labels:
        app: casebender-app
    spec:
      containers:
        - name: app
          image: registry.digitalocean.com/casebender-registry/app:latest
          ports:
            - containerPort: 3000
          env:
            - name: AUTH_SECRET
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: auth-secret
            - name: AUTH_SALT
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: auth-salt
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: workflow-processor
  namespace: casebender
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workflow-processor
  template:
    metadata:
      labels:
        app: workflow-processor
    spec:
      containers:
        - name: processor
          image: registry.digitalocean.com/casebender-registry/workflow-processor:latest
          env:
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: misp-processor
  namespace: casebender
spec:
  replicas: 1
  selector:
    matchLabels:
      app: misp-processor
  template:
    metadata:
      labels:
        app: misp-processor
    spec:
      containers:
        - name: processor
          image: registry.digitalocean.com/casebender-registry/misp-processor:latest
          env:
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url

배포 적용:

kubectl apply -f deployment.yaml

서비스 생성

service.yaml 생성:

apiVersion: v1
kind: Service
metadata:
  name: casebender-app
  namespace: casebender
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 3000
  selector:
    app: casebender-app

서비스 적용:

kubectl apply -f service.yaml

7단계: 인그레스 설정

NGINX 인그레스 컨트롤러 설치

# Helm 리포지토리 추가
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# NGINX 인그레스 컨트롤러 설치
helm install nginx-ingress ingress-nginx/ingress-nginx \
  --namespace casebender \
  --set controller.publishService.enabled=true

인그레스 구성

ingress.yaml 생성:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: casebender-ingress
  namespace: casebender
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - your-domain.com
      secretName: casebender-tls
  rules:
    - host: your-domain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: casebender-app
                port:
                  number: 80

인그레스 적용:

kubectl apply -f ingress.yaml

8단계: cert-manager로 SSL 설정

# cert-manager 설치
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml

# ClusterIssuer 생성
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@domain.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

모니터링 및 유지 관리

모니터링 설정

# 메트릭 서버 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Prometheus 및 Grafana 배포
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace

수평 Pod 자동 확장 구성

hpa.yaml 생성:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: casebender-app-hpa
  namespace: casebender
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: casebender-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80

HPA 적용:

kubectl apply -f hpa.yaml

백업 및 재해 복구

데이터베이스 백업

DigitalOcean 관리형 데이터베이스는 자동으로 백업을 처리합니다. 또한 다음을 수행할 수 있습니다:

# 수동 백업 생성
doctl databases backup casebender-db

데이터베이스 장애 조치 구성

# 자동 장애 조치 활성화
doctl databases replica casebender-db create \
  --region sfo2

보안 모범 사례

  1. DigitalOcean Cloud Firewall 활성화
  2. 프라이빗 네트워킹 사용
  3. 네트워크 정책 구현
  4. 정기적인 보안 업데이트
  5. 감사 로깅 활성화

비용 최적화

  1. 적절한 노드 크기 사용
  2. 자동 확장 구현
  3. 블록 스토리지 현명하게 사용
  4. 리소스 사용량 모니터링
  5. 예약 드롭릿 고려

다음 단계

  • CI/CD 파이프라인 설정
  • 모니터링 경고 구성
  • 로깅 솔루션 구현
  • 보안 조치 검토