From b150c0a2759c9862a9279f857b9a33e335f5ffc2 Mon Sep 17 00:00:00 2001 From: ChangHyun Park Date: Tue, 8 Jul 2025 00:16:24 +0900 Subject: [PATCH 1/3] deploy : deploy eks logs and debug --- .github/workflows/deploy-debug.yml | 93 +++++++++++++++++++++++++++++ .github/workflows/deploy.yml | 95 +++++++++++++++++++++++++++++- 2 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/deploy-debug.yml diff --git a/.github/workflows/deploy-debug.yml b/.github/workflows/deploy-debug.yml new file mode 100644 index 0000000..6b8dcab --- /dev/null +++ b/.github/workflows/deploy-debug.yml @@ -0,0 +1,93 @@ +name: Deploy with Debug Logs + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + # 기존 배포 단계들... + + - name: Deploy to Kubernetes + run: | + kubectl apply -f k8s/ + + - name: Wait for deployment with timeout + run: | + echo "Waiting for deployment rollout..." + kubectl rollout status deployment/nestjs-app --timeout=300s || echo "Deployment timeout reached" + + - name: Debug - Check deployment status + if: always() + run: | + echo "=== Deployment Status ===" + kubectl get deployments -o wide + + echo "=== ReplicaSet Status ===" + kubectl get rs -o wide + + echo "=== Pod Status ===" + kubectl get pods -o wide + + - name: Debug - Describe deployment + if: always() + run: | + echo "=== Deployment Description ===" + kubectl describe deployment nestjs-app + + - name: Debug - Pod logs + if: always() + run: | + echo "=== Pod Logs ===" + # 모든 nestjs-app 관련 pod의 로그 출력 + for pod in $(kubectl get pods -l app=nestjs-app -o jsonpath='{.items[*].metadata.name}'); do + echo "--- Logs for pod: $pod ---" + kubectl logs $pod --previous=false || echo "No logs available for $pod" + echo "--- Previous logs for pod: $pod ---" + kubectl logs $pod --previous=true || echo "No previous logs available for $pod" + done + + - name: Debug - Events + if: always() + run: | + echo "=== Recent Events ===" + kubectl get events --sort-by='.lastTimestamp' | tail -20 + + - name: Debug - Node resources + if: always() + run: | + echo "=== Node Resources ===" + kubectl top nodes || echo "Metrics server not available" + kubectl describe nodes | grep -A 5 "Allocated resources" || echo "Node resource info not available" + + - name: Debug - Service and Ingress status + if: always() + run: | + echo "=== Service Status ===" + kubectl get svc -o wide + + echo "=== Ingress Status ===" + kubectl get ingress -o wide + + echo "=== HPA Status ===" + kubectl get hpa -o wide + + - name: Debug - Image pull status + if: always() + run: | + echo "=== Checking image pull issues ===" + kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[*].state}{"\n"}{end}' | grep -i "image" || echo "No image pull issues found" + + - name: Cleanup on failure + if: failure() + run: | + echo "=== Cleaning up failed deployment ===" + kubectl delete deployment nestjs-app --ignore-not-found=true + kubectl delete pods -l app=nestjs-app --ignore-not-found=true diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 286cc4d..e2d8b08 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -133,8 +133,99 @@ jobs: kubectl apply -f k8s/hpa.yaml kubectl apply -f k8s/ingress.yaml - # Check deployment status - kubectl rollout status deployment/nestjs-app -n nestjs-app + # Check deployment status with real-time monitoring + echo "🚀 Starting deployment rollout monitoring..." + + # Start rollout status check in background + kubectl rollout status deployment/nestjs-app -n nestjs-app --timeout=600s & + ROLLOUT_PID=$! + + # Monitor pods and logs in real-time + echo "📊 Monitoring deployment progress..." + for i in {1..60}; do + echo "--- Check #$i ($(date)) ---" + + echo "Pod Status:" + kubectl get pods -n nestjs-app -l app=nestjs-app -o wide + + echo "ReplicaSet Status:" + kubectl get rs -n nestjs-app -l app=nestjs-app -o wide + + echo "Recent Events:" + kubectl get events -n nestjs-app --field-selector involvedObject.kind=Pod --sort-by='.lastTimestamp' | tail -5 + + # Get logs from any running pods + PODS=$(kubectl get pods -n nestjs-app -l app=nestjs-app -o jsonpath='{.items[*].metadata.name}') + if [ ! -z "$PODS" ]; then + echo "Current Pod Logs:" + for pod in $PODS; do + echo "--- Logs from $pod ---" + kubectl logs $pod -n nestjs-app --tail=10 --since=30s 2>/dev/null || echo "No logs available yet" + done + fi + + # Check if rollout is still running + if ! kill -0 $ROLLOUT_PID 2>/dev/null; then + echo "✅ Rollout completed!" + break + fi + + echo "⏳ Waiting 10 seconds before next check..." + sleep 10 + done + + # Wait for rollout to complete + wait $ROLLOUT_PID + + - name: Debug Deployment Issues + if: failure() + run: | + echo "🔍 ===== 배포 실패 디버깅 =====" + + echo "📊 Deployment 상세 정보:" + kubectl describe deployment nestjs-app -n nestjs-app + + echo "" + echo "📊 ReplicaSet 상태:" + kubectl describe rs -n nestjs-app -l app=nestjs-app + + echo "" + echo "🚨 실패한 Pod 상세 정보:" + kubectl get pods -n nestjs-app -l app=nestjs-app -o wide + + # 각 Pod의 상세 정보와 로그 출력 + PODS=$(kubectl get pods -n nestjs-app -l app=nestjs-app -o jsonpath='{.items[*].metadata.name}') + for pod in $PODS; do + echo "" + echo "--- Pod: $pod 상세 정보 ---" + kubectl describe pod $pod -n nestjs-app + + echo "" + echo "--- Pod: $pod 현재 로그 ---" + kubectl logs $pod -n nestjs-app --tail=50 || echo "현재 로그 없음" + + echo "" + echo "--- Pod: $pod 이전 로그 ---" + kubectl logs $pod -n nestjs-app --previous --tail=50 || echo "이전 로그 없음" + done + + echo "" + echo "🔍 최근 이벤트 (상세):" + kubectl get events -n nestjs-app --sort-by='.lastTimestamp' | tail -20 + + echo "" + echo "🔍 클러스터 리소스 상태:" + kubectl top nodes || echo "메트릭 서버 사용 불가" + kubectl describe nodes | grep -A 10 "Allocated resources" || echo "노드 리소스 정보 없음" + + echo "" + echo "🔍 네임스페이스 리소스:" + kubectl get all -n nestjs-app + + echo "" + echo "🔍 Secret 및 ConfigMap 상태:" + kubectl get secrets -n nestjs-app + kubectl get configmaps -n nestjs-app - name: Post-Deployment Verification run: | From d1e59be1a7d9ad87c22e8bf3b277eeca1567aa25 Mon Sep 17 00:00:00 2001 From: ChangHyun Park Date: Tue, 8 Jul 2025 00:23:18 +0900 Subject: [PATCH 2/3] Delete .github/workflows/deploy-debug.yml --- .github/workflows/deploy-debug.yml | 93 ------------------------------ 1 file changed, 93 deletions(-) delete mode 100644 .github/workflows/deploy-debug.yml diff --git a/.github/workflows/deploy-debug.yml b/.github/workflows/deploy-debug.yml deleted file mode 100644 index 6b8dcab..0000000 --- a/.github/workflows/deploy-debug.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Deploy with Debug Logs - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - # 기존 배포 단계들... - - - name: Deploy to Kubernetes - run: | - kubectl apply -f k8s/ - - - name: Wait for deployment with timeout - run: | - echo "Waiting for deployment rollout..." - kubectl rollout status deployment/nestjs-app --timeout=300s || echo "Deployment timeout reached" - - - name: Debug - Check deployment status - if: always() - run: | - echo "=== Deployment Status ===" - kubectl get deployments -o wide - - echo "=== ReplicaSet Status ===" - kubectl get rs -o wide - - echo "=== Pod Status ===" - kubectl get pods -o wide - - - name: Debug - Describe deployment - if: always() - run: | - echo "=== Deployment Description ===" - kubectl describe deployment nestjs-app - - - name: Debug - Pod logs - if: always() - run: | - echo "=== Pod Logs ===" - # 모든 nestjs-app 관련 pod의 로그 출력 - for pod in $(kubectl get pods -l app=nestjs-app -o jsonpath='{.items[*].metadata.name}'); do - echo "--- Logs for pod: $pod ---" - kubectl logs $pod --previous=false || echo "No logs available for $pod" - echo "--- Previous logs for pod: $pod ---" - kubectl logs $pod --previous=true || echo "No previous logs available for $pod" - done - - - name: Debug - Events - if: always() - run: | - echo "=== Recent Events ===" - kubectl get events --sort-by='.lastTimestamp' | tail -20 - - - name: Debug - Node resources - if: always() - run: | - echo "=== Node Resources ===" - kubectl top nodes || echo "Metrics server not available" - kubectl describe nodes | grep -A 5 "Allocated resources" || echo "Node resource info not available" - - - name: Debug - Service and Ingress status - if: always() - run: | - echo "=== Service Status ===" - kubectl get svc -o wide - - echo "=== Ingress Status ===" - kubectl get ingress -o wide - - echo "=== HPA Status ===" - kubectl get hpa -o wide - - - name: Debug - Image pull status - if: always() - run: | - echo "=== Checking image pull issues ===" - kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[*].state}{"\n"}{end}' | grep -i "image" || echo "No image pull issues found" - - - name: Cleanup on failure - if: failure() - run: | - echo "=== Cleaning up failed deployment ===" - kubectl delete deployment nestjs-app --ignore-not-found=true - kubectl delete pods -l app=nestjs-app --ignore-not-found=true From 7de4bd3a0a3c124bd94abdb30026d977aed50bc1 Mon Sep 17 00:00:00 2001 From: ChangHyun Park Date: Tue, 8 Jul 2025 00:30:07 +0900 Subject: [PATCH 3/3] deploy : Update deploy.yml --- .github/workflows/deploy.yml | 91 +++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e2d8b08..2be91c8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,11 +19,12 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-2 - - - name: Get current IAM user + + - name: Verify AWS Configuration run: | + echo "🔍 AWS 설정 확인..." aws sts get-caller-identity - echo "위 결과의 'Arn' 값을 EKS 액세스 항목에 입력하세요" + aws eks describe-cluster --name nestjs-cluster --region ap-northeast-2 --query 'cluster.status' - name: Install eksctl run: | @@ -39,35 +40,49 @@ jobs: sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl kubectl version --client + - name: Update kubeconfig and verify connection + run: | + echo "🔧 EKS kubeconfig 설정..." + aws eks update-kubeconfig --region ap-northeast-2 --name nestjs-cluster + + echo "🔍 클러스터 연결 테스트..." + kubectl cluster-info + kubectl get nodes -o wide + + echo "🔍 현재 context 확인..." + kubectl config current-context + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 + - name: Verify ECR Repository + run: | + echo "🔍 ECR 리포지토리 확인..." + aws ecr describe-repositories --repository-names nestjs-app --region ap-northeast-2 || { + echo "❌ ECR 리포지토리가 존재하지 않습니다. 생성합니다..." + aws ecr create-repository --repository-name nestjs-app --region ap-northeast-2 + } + - name: Build, tag, and push image to Amazon ECR env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: nestjs-app IMAGE_TAG: ${{ github.sha }} run: | + echo "🏗️ Docker 이미지 빌드 및 푸시..." docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest - - - name: Update kubeconfig - run: | - # EKS 클러스터 kubeconfig 설정 - aws eks update-kubeconfig --region ap-northeast-2 --name nestjs-cluster - # 연결 테스트 - kubectl cluster-info - kubectl get nodes + echo "✅ 이미지 푸시 완료: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - name: Install AWS Load Balancer Controller (if not exists) run: | - # Check if AWS Load Balancer Controller exists + echo "🔍 AWS Load Balancer Controller 확인..." if ! kubectl get deployment -n kube-system aws-load-balancer-controller > /dev/null 2>&1; then - echo "Installing AWS Load Balancer Controller..." + echo "📦 AWS Load Balancer Controller 설치 중..." # Download IAM policy curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.2/docs/install/iam_policy.json @@ -75,7 +90,7 @@ jobs: # Create IAM policy (ignore if exists) aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ - --policy-document file://iam_policy.json || true + --policy-document file://iam_policy.json || echo "IAM 정책이 이미 존재합니다" # Create service account with eksctl eksctl create iamserviceaccount \ @@ -85,7 +100,7 @@ jobs: --role-name AmazonEKSLoadBalancerControllerRole \ --attach-policy-arn=arn:aws:iam::863518449560:policy/AWSLoadBalancerControllerIAMPolicy \ --approve \ - --region=ap-northeast-2 || true + --region=ap-northeast-2 || echo "서비스 계정이 이미 존재합니다" # Install cert-manager kubectl apply \ @@ -93,7 +108,7 @@ jobs: -f https://github.com/jetstack/cert-manager/releases/download/v1.13.0/cert-manager.yaml # Wait for cert-manager - echo "Waiting for cert-manager to be ready..." + echo "⏳ cert-manager 준비 대기 중..." kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=cert-manager -n cert-manager --timeout=300s # Download and apply AWS Load Balancer Controller @@ -102,10 +117,10 @@ jobs: kubectl apply -f v2_7_2_full.yaml # Wait for controller to be ready - echo "Waiting for AWS Load Balancer Controller to be ready..." + echo "⏳ AWS Load Balancer Controller 준비 대기 중..." kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=aws-load-balancer-controller -n kube-system --timeout=300s else - echo "AWS Load Balancer Controller already exists" + echo "✅ AWS Load Balancer Controller가 이미 설치되어 있습니다" fi - name: Deploy to EKS @@ -114,10 +129,14 @@ jobs: ECR_REPOSITORY: nestjs-app IMAGE_TAG: ${{ github.sha }} run: | + echo "🚀 EKS 배포 시작..." + # Create namespace + echo "📁 네임스페이스 생성..." kubectl apply -f k8s/namespace.yaml # Create or update secrets + echo "🔐 시크릿 생성/업데이트..." kubectl create secret generic app-secrets \ --from-literal=database-url="${{ secrets.DATABASE_URL }}" \ --from-literal=redis-url="${{ secrets.REDIS_URL }}" \ @@ -125,53 +144,58 @@ jobs: --dry-run=client -o yaml | kubectl apply -f - # Update deployment image + echo "🔄 배포 이미지 업데이트..." sed -i "s|863518449560.dkr.ecr.ap-northeast-2.amazonaws.com/nestjs-app:latest|$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG|g" k8s/deployment.yaml # Deploy application + echo "📦 애플리케이션 배포..." kubectl apply -f k8s/deployment.yaml kubectl apply -f k8s/service.yaml kubectl apply -f k8s/hpa.yaml kubectl apply -f k8s/ingress.yaml - # Check deployment status with real-time monitoring - echo "🚀 Starting deployment rollout monitoring..." + echo "✅ 리소스 배포 완료" + + - name: Monitor Deployment Progress + run: | + echo "🔍 배포 진행 상황 모니터링..." # Start rollout status check in background kubectl rollout status deployment/nestjs-app -n nestjs-app --timeout=600s & ROLLOUT_PID=$! # Monitor pods and logs in real-time - echo "📊 Monitoring deployment progress..." - for i in {1..60}; do - echo "--- Check #$i ($(date)) ---" + echo "📊 실시간 모니터링 시작..." + for i in {1..30}; do + echo "--- 체크 #$i ($(date '+%H:%M:%S')) ---" - echo "Pod Status:" + echo "Pod 상태:" kubectl get pods -n nestjs-app -l app=nestjs-app -o wide - echo "ReplicaSet Status:" + echo "ReplicaSet 상태:" kubectl get rs -n nestjs-app -l app=nestjs-app -o wide - echo "Recent Events:" - kubectl get events -n nestjs-app --field-selector involvedObject.kind=Pod --sort-by='.lastTimestamp' | tail -5 + echo "최근 이벤트:" + kubectl get events -n nestjs-app --field-selector involvedObject.kind=Pod --sort-by='.lastTimestamp' | tail -3 # Get logs from any running pods PODS=$(kubectl get pods -n nestjs-app -l app=nestjs-app -o jsonpath='{.items[*].metadata.name}') if [ ! -z "$PODS" ]; then - echo "Current Pod Logs:" + echo "현재 Pod 로그:" for pod in $PODS; do - echo "--- Logs from $pod ---" - kubectl logs $pod -n nestjs-app --tail=10 --since=30s 2>/dev/null || echo "No logs available yet" + echo "--- $pod 로그 ---" + kubectl logs $pod -n nestjs-app --tail=5 --since=30s 2>/dev/null || echo "로그 없음" done fi # Check if rollout is still running if ! kill -0 $ROLLOUT_PID 2>/dev/null; then - echo "✅ Rollout completed!" + echo "✅ 롤아웃 완료!" break fi - echo "⏳ Waiting 10 seconds before next check..." - sleep 10 + echo "⏳ 20초 후 다시 확인..." + sleep 20 done # Wait for rollout to complete @@ -228,6 +252,7 @@ jobs: kubectl get configmaps -n nestjs-app - name: Post-Deployment Verification + if: success() run: | echo "🚀 ===== 배포 완료 확인 ====="