Files
vexplor/docs/KUBERNETES_DEPLOYMENT_GUIDE.md
Johngreen 47ac3dcaf1 Add Kubernetes deployment and CI/CD workflow
Introduce Kubernetes manifests for backend, frontend, ingress, storage, and namespace setup under k8s/. Add Gitea Actions workflow for automated build and deployment to Kubernetes. Provide deployment and cluster setup guides in docs/ and project root. Update .gitignore to exclude Kubernetes secret files.
2025-12-22 15:33:24 +09:00

11 KiB

vexplor 쿠버네티스 자동 배포 가이드

개요

이 문서는 vexplor 프로젝트를 Gitea Actions를 통해 쿠버네티스 클러스터에 자동 배포하는 방법을 설명합니다.

작성일: 2024년 12월 22일


아키텍처

┌─────────────────────────────────────────────────────────────────┐
│                        Gitea Repository                          │
│                    g.wace.me/chpark/vexplor                      │
└─────────────────────┬───────────────────────────────────────────┘
                      │ push to main
                      ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Gitea Actions Runner                        │
│  1. Checkout code                                                │
│  2. Build Docker images (frontend, backend)                      │
│  3. Push to Harbor Registry                                      │
│  4. Deploy to Kubernetes                                         │
└─────────────────────┬───────────────────────────────────────────┘
                      │
          ┌──────────┴──────────┐
          ▼                     ▼
┌──────────────────┐   ┌──────────────────┐
│  Harbor Registry │   │ Kubernetes (K8s) │
│  harbor.wace.me  │   │  112.168.212.142 │
└──────────────────┘   └──────────────────┘
                               │
              ┌────────────────┼────────────────┐
              ▼                ▼                ▼
       ┌──────────┐     ┌──────────┐     ┌──────────┐
       │ Frontend │     │ Backend  │     │ Ingress  │
       │  :3000   │     │  :3001   │     │ Nginx    │
       └──────────┘     └──────────┘     └──────────┘
              │                │                │
              └────────────────┴────────────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │   External Access   │
                    │ v1.vexplor.com      │
                    │ api.vexplor.com     │
                    └─────────────────────┘

사전 요구사항

1. 쿠버네티스 클러스터

# 서버 정보
IP: 112.168.212.142
SSH: ssh -p 22 wace@112.168.212.142
K8s 버전: v1.28.15

2. Harbor 레지스트리 접근 권한

Harbor에 vexplor 프로젝트가 생성되어 있어야 합니다.

3. Gitea Repository Secrets

Gitea 저장소에 다음 Secrets를 설정해야 합니다:

Secret 이름 설명
HARBOR_USERNAME Harbor 사용자명
HARBOR_PASSWORD Harbor 비밀번호
KUBECONFIG base64 인코딩된 Kubernetes config

초기 설정

1단계: 쿠버네티스 클러스터 접속

ssh -p 22 wace@112.168.212.142

2단계: Nginx Ingress Controller 설치

# Nginx Ingress Controller 설치 (baremetal용)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.5/deploy/static/provider/baremetal/deploy.yaml

# 설치 확인
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

3단계: Local Path Provisioner 설치 (PVC용)

# Local Path Provisioner 설치
kubectl apply -f k8s/local-path-provisioner.yaml

# 설치 확인
kubectl get pods -n local-path-storage
kubectl get storageclass

4단계: Cert-Manager 설치 (SSL 인증서용)

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

# 설치 확인
kubectl get pods -n cert-manager

# ClusterIssuer 생성 (Let's Encrypt)
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: admin@vexplor.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

5단계: vexplor Secret 생성

# Secret 템플릿을 복사하여 실제 값으로 수정
cp k8s/vexplor-secret.yaml.template k8s/vexplor-secret.yaml

# 값 수정 후 적용
kubectl apply -f k8s/vexplor-secret.yaml

6단계: Gitea Secrets 설정

  1. Gitea 저장소로 이동: https://g.wace.me/chpark/vexplor
  2. Settings > Secrets > Actions 메뉴로 이동
  3. 다음 Secrets 추가:

HARBOR_USERNAME

Harbor 로그인 사용자명

HARBOR_PASSWORD

Harbor 로그인 비밀번호

KUBECONFIG

# 쿠버네티스 서버에서 실행
cat ~/.kube/config | base64 -w 0

출력된 값을 KUBECONFIG secret으로 등록


배포 트리거

자동 배포 (Push)

다음 경로의 파일이 변경되어 main 브랜치에 push되면 자동으로 배포됩니다:

  • backend-node/**
  • frontend/**
  • docker/**
  • k8s/**
  • .gitea/workflows/deploy.yml

수동 배포

  1. Gitea 저장소 > Actions 탭으로 이동
  2. "Deploy vexplor" 워크플로우 선택
  3. "Run workflow" 버튼 클릭

파일 구조

vexplor/
├── .gitea/
│   └── workflows/
│       └── deploy.yml          # Gitea Actions 워크플로우
├── docker/
│   └── deploy/
│       ├── backend.Dockerfile  # 백엔드 배포용 Dockerfile
│       └── frontend.Dockerfile # 프론트엔드 배포용 Dockerfile
├── k8s/
│   ├── namespace.yaml                # 네임스페이스 정의
│   ├── vexplor-config.yaml          # ConfigMap
│   ├── vexplor-secret.yaml.template # Secret 템플릿
│   ├── vexplor-backend-deployment.yaml   # 백엔드 Deployment/Service/PVC
│   ├── vexplor-frontend-deployment.yaml  # 프론트엔드 Deployment/Service
│   ├── vexplor-ingress.yaml              # Ingress 설정
│   ├── local-path-provisioner.yaml       # 스토리지 프로비저너
│   └── ingress-nginx.yaml                # Ingress 컨트롤러 패치
└── docs/
    └── KUBERNETES_DEPLOYMENT_GUIDE.md    # 이 문서

운영 명령어

상태 확인

# 전체 리소스 확인
kubectl get all -n vexplor

# Pod 상태 확인
kubectl get pods -n vexplor -o wide

# 로그 확인
kubectl logs -f deployment/vexplor-backend -n vexplor
kubectl logs -f deployment/vexplor-frontend -n vexplor

# Pod 상세 정보
kubectl describe pod <pod-name> -n vexplor

수동 배포/롤백

# 이미지 업데이트
kubectl set image deployment/vexplor-backend \
  vexplor-backend=harbor.wace.me/vexplor/vexplor-backend:v20241222-120000-abc1234 \
  -n vexplor

# 롤아웃 상태 확인
kubectl rollout status deployment/vexplor-backend -n vexplor

# 롤백
kubectl rollout undo deployment/vexplor-backend -n vexplor
kubectl rollout undo deployment/vexplor-frontend -n vexplor

# 히스토리 확인
kubectl rollout history deployment/vexplor-backend -n vexplor

스케일링

# 레플리카 수 조정
kubectl scale deployment/vexplor-backend --replicas=3 -n vexplor
kubectl scale deployment/vexplor-frontend --replicas=3 -n vexplor

Pod 재시작

# Deployment 재시작 (롤링 업데이트)
kubectl rollout restart deployment/vexplor-backend -n vexplor
kubectl rollout restart deployment/vexplor-frontend -n vexplor

문제 해결

Pod이 Pending 상태일 때

# Pod 이벤트 확인
kubectl describe pod <pod-name> -n vexplor

# 노드 리소스 확인
kubectl describe node
kubectl top nodes

ImagePullBackOff 오류

# Harbor Secret 확인
kubectl get secret harbor-registry -n vexplor -o yaml

# Secret 재생성
kubectl delete secret harbor-registry -n vexplor
kubectl create secret docker-registry harbor-registry \
  --docker-server=192.168.1.100:5001 \
  --docker-username=<username> \
  --docker-password=<password> \
  -n vexplor

Ingress가 작동하지 않을 때

# Ingress 상태 확인
kubectl get ingress -n vexplor
kubectl describe ingress vexplor-ingress -n vexplor

# Ingress Controller 로그
kubectl logs -f deployment/ingress-nginx-controller -n ingress-nginx

SSL 인증서 문제

# Certificate 상태 확인
kubectl get certificate -n vexplor
kubectl describe certificate vexplor-tls -n vexplor

# Cert-Manager 로그
kubectl logs -f deployment/cert-manager -n cert-manager

네트워크 설정

방화벽 포트 개방

쿠버네티스 서버에서 다음 포트가 개방되어야 합니다:

포트 용도
30080 HTTP (Ingress NodePort)
30443 HTTPS (Ingress NodePort)
6443 Kubernetes API

DNS 설정

다음 도메인이 쿠버네티스 서버 IP를 가리키도록 설정:

  • v1.vexplor.com → 112.168.212.142
  • api.vexplor.com → 112.168.212.142

환경 변수

Backend 환경 변수

변수 설명 소스
NODE_ENV 환경 (production) ConfigMap
PORT 서버 포트 (3001) ConfigMap
DATABASE_URL PostgreSQL 연결 문자열 Secret
JWT_SECRET JWT 서명 키 Secret
JWT_EXPIRES_IN JWT 만료 시간 ConfigMap
CORS_ORIGIN CORS 허용 도메인 ConfigMap

Frontend 환경 변수

변수 설명 소스
NODE_ENV 환경 (production) ConfigMap
NEXT_PUBLIC_API_URL 클라이언트 API URL ConfigMap
SERVER_API_URL SSR용 내부 API URL Deployment

참고 자료