# Tasteby OKE 배포 가이드 ## 아키텍처 ``` Internet │ ▼ OCI Load Balancer (Nginx Ingress가 자동 생성) │ ├─ / → frontend Service (Next.js :3001) ├─ /api/ → backend Service (Spring Boot :8000) │ ├─ cert-manager (Let's Encrypt 인증서 자동 발급/갱신) └─ Redis (in-cluster 캐시 :6379) ``` ## 인프라 정보 | 항목 | 값 | |------|-----| | 클러스터 | tasteby-cluster | | 리전 | ap-seoul-1 (Seoul) | | 노드 | ARM64 × 2대 (2 CPU / 8GB 각) | | K8s 버전 | v1.34.2 | | OCI 프로필 | JOUNGMINKOAWS | | OCIR | icn.ocir.io/idyhsdamac8c/tasteby | | 도메인 | www.tasteby.net (Namecheap DNS) | | SSL | Let's Encrypt (cert-manager + HTTP-01) | ## 파일 구조 ``` tasteby/ ├── backend-java/Dockerfile ├── frontend/Dockerfile ├── k8s/ │ ├── namespace.yaml │ ├── configmap.yaml │ ├── secrets.yaml.template ← 실제 secrets.yaml은 .gitignore │ ├── redis-deployment.yaml │ ├── backend-deployment.yaml │ ├── frontend-deployment.yaml │ ├── ingress.yaml │ └── cert-manager/ │ └── cluster-issuer.yaml └── deploy.sh ``` ## 리소스 배분 | 파드 | replicas | CPU req/lim | 메모리 req/lim | |------|----------|-------------|----------------| | backend (Java) | 1 | 500m / 1 | 768Mi / 1536Mi | | frontend (Next.js) | 1 | 200m / 500m | 256Mi / 512Mi | | redis | 1 | 100m / 200m | 128Mi / 256Mi | | ingress-controller | 1 | 100m / 200m | 128Mi / 256Mi | | cert-manager (×3) | 1씩 | 50m / 100m | 64Mi / 128Mi | | **합계** | | **~1.2 CPU** | **~1.6GB** | 전체 클러스터: 4 CPU / 16GB → 여유 충분 --- ## 1단계: 사전 준비 ### 1.1 kubectl 설정 ```bash # OKE kubeconfig 가져오기 oci ce cluster create-kubeconfig \ --cluster-id ocid1.cluster.oc1.ap-seoul-1.aaaaaaaaoqgd2sh6754m5zrwfqaxwrtlqon3dxtdwbbc2dvzbcbou3pf75rq \ --profile JOUNGMINKOAWS \ --region ap-seoul-1 \ --token-version 2.0.0 \ --kube-endpoint PUBLIC_ENDPOINT # ~/.kube/config의 user args에 --profile JOUNGMINKOAWS 추가 필요 # 확인 kubectl get nodes ``` ### 1.2 Helm 설치 (없으면) ```bash brew install helm ``` --- ## 2단계: 인프라 설치 (1회성) ### 2.1 Nginx Ingress Controller ```bash helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx --create-namespace \ --set controller.service.type=LoadBalancer \ --set controller.service.annotations."oci\.oraclecloud\.com/load-balancer-type"=nlb ``` 설치 후 External IP 확인: ```bash kubectl get svc -n ingress-nginx ingress-nginx-controller -w # EXTERNAL-IP가 나오면 Namecheap에서 A 레코드 업데이트 # www.tasteby.net → # tasteby.net → ``` ### 2.2 cert-manager ```bash helm repo add jetstack https://charts.jetstack.io helm repo update helm install cert-manager jetstack/cert-manager \ --namespace cert-manager --create-namespace \ --set crds.enabled=true ``` ### 2.3 ClusterIssuer 생성 ```bash kubectl apply -f k8s/cert-manager/cluster-issuer.yaml ``` --- ## 3단계: 네임스페이스 및 시크릿 생성 (1회성) ### 3.1 네임스페이스 ```bash kubectl apply -f k8s/namespace.yaml ``` ### 3.2 OCIR 이미지 Pull Secret ```bash # OCI Auth Token 필요 (콘솔 > User Settings > Auth Tokens에서 생성) kubectl create secret docker-registry ocir-secret \ --docker-server=icn.ocir.io \ --docker-username="idyhsdamac8c/" \ --docker-password="" \ --docker-email="" \ -n tasteby ``` ### 3.3 앱 시크릿 ```bash # secrets.yaml.template을 복사하여 실제 값 입력 cp k8s/secrets.yaml.template k8s/secrets.yaml # 편집 후 kubectl apply -f k8s/secrets.yaml ``` ### 3.4 Oracle Wallet Secret ```bash # Wallet 디렉토리의 파일들을 Secret으로 생성 kubectl create secret generic oracle-wallet \ --from-file=cwallet.sso=/cwallet.sso \ --from-file=tnsnames.ora=/tnsnames.ora \ --from-file=sqlnet.ora=/sqlnet.ora \ --from-file=keystore.jks=/keystore.jks \ --from-file=truststore.jks=/truststore.jks \ --from-file=ojdbc.properties=/ojdbc.properties \ -n tasteby ``` ### 3.5 OCI Config Secret ```bash # OCI API key config 파일과 PEM 키를 Secret으로 생성 # config 파일은 K8s용으로 수정 필요 (key_file 경로를 /root/.oci/oci_api_key.pem으로) kubectl create secret generic oci-config \ --from-file=config= \ --from-file=oci_api_key.pem= \ -n tasteby ``` **참고**: OCI config 파일에서 `key_file` 경로를 컨테이너 내부 마운트 경로로 수정: ```ini [DEFAULT] user=ocid1.user.oc1..xxx fingerprint=xx:xx:xx key_file=/root/.oci/oci_api_key.pem tenancy=ocid1.tenancy.oc1..xxx region=ap-seoul-1 ``` ### 3.6 ConfigMap 적용 ```bash kubectl apply -f k8s/configmap.yaml ``` --- ## 4단계: 앱 배포 ### 4.1 기본 리소스 배포 ```bash kubectl apply -f k8s/redis-deployment.yaml kubectl apply -f k8s/backend-deployment.yaml kubectl apply -f k8s/frontend-deployment.yaml kubectl apply -f k8s/ingress.yaml ``` ### 4.2 OCIR 로그인 (이미지 푸시용) ```bash docker login icn.ocir.io \ -u "idyhsdamac8c/" \ -p "" ``` ### 4.3 이미지 빌드 & 배포 ```bash # 전체 배포 ./deploy.sh "초기 배포" # 백엔드만 배포 ./deploy.sh --backend-only "API 버그 수정" # 프론트엔드만 배포 ./deploy.sh --frontend-only "UI 개선" # 드라이런 (실제 실행 안 함) ./deploy.sh --dry-run "테스트" ``` --- ## 5단계: DNS 설정 Namecheap에서 A 레코드 변경: | Type | Host | Value | TTL | |------|------|-------|-----| | A | @ | `` | Automatic | | A | www | `` | Automatic | DNS 전파 후 cert-manager가 자동으로 Let's Encrypt 인증서를 발급합니다. --- ## 운영 명령어 ### 상태 확인 ```bash # 파드 상태 kubectl get pods -n tasteby # 로그 확인 kubectl logs -f deployment/backend -n tasteby kubectl logs -f deployment/frontend -n tasteby # 인증서 상태 kubectl get certificate -n tasteby kubectl describe certificate tasteby-tls -n tasteby ``` ### 롤백 ```bash # 이전 버전으로 롤백 kubectl rollout undo deployment/backend -n tasteby kubectl rollout undo deployment/frontend -n tasteby # 특정 리비전으로 롤백 kubectl rollout history deployment/backend -n tasteby kubectl rollout undo deployment/backend --to-revision=2 -n tasteby ``` ### 시크릿 업데이트 ```bash # secrets.yaml 수정 후 kubectl apply -f k8s/secrets.yaml # 파드 재시작 (시크릿 변경 반영) kubectl rollout restart deployment/backend -n tasteby ``` ### 스케일링 ```bash # 백엔드 2개로 확장 kubectl scale deployment/backend --replicas=2 -n tasteby ``` --- ## 배포 태그 규칙 - 형식: `v0.1.X` (patch 버전 자동 증가) - `deploy.sh`가 빌드 → 푸시 → K8s 업데이트 → git tag 생성 → 태그 푸시까지 자동 처리 - 태그 메시지에 배포 대상(backend/frontend)과 이미지 태그 포함 ```bash # 태그 목록 확인 git tag -l 'v*' --sort=-v:refname # 특정 태그의 배포 내역 확인 git tag -n20 v0.1.5 ``` --- ## 트러블슈팅 ### 이미지 Pull 실패 ```bash kubectl describe pod -n tasteby # Events에서 ImagePullBackOff 확인 → ocir-secret 점검 ``` ### DB 연결 실패 ```bash kubectl exec -it deployment/backend -n tasteby -- env | grep ORACLE # Oracle Wallet 마운트 확인 kubectl exec -it deployment/backend -n tasteby -- ls /etc/oracle/wallet/ ``` ### 인증서 발급 안 됨 ```bash kubectl get challenges -n tasteby kubectl describe challenge -n tasteby # DNS A 레코드가 LB IP로 설정되었는지, 80 포트가 열려있는지 확인 ``` ### OCI GenAI 연결 실패 ```bash kubectl exec -it deployment/backend -n tasteby -- cat /root/.oci/config # key_file 경로가 /root/.oci/oci_api_key.pem 인지 확인 ```