diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index e307079e..ec48126e 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -8,7 +8,7 @@ # 필수 Secrets (Repository Settings > Secrets): # - HARBOR_USERNAME: Harbor 사용자명 # - HARBOR_PASSWORD: Harbor 비밀번호 -# - KUBECONFIG: base64로 인코딩된 Kubernetes config +# - K8S_SSH_KEY: base64로 인코딩된 SSH 비밀키 (쿠버네티스 서버 접속용) # # Application Secrets: # - k8s/vexplor-secret.yaml 파일에서 관리 @@ -31,10 +31,15 @@ on: env: GITEA_DOMAIN: g.wace.me HARBOR_REGISTRY: localhost:5001 - HARBOR_REGISTRY_K8S: 192.168.1.100:5001 + HARBOR_REGISTRY_K8S: harbor.wace.me HARBOR_REGISTRY_EXTERNAL: harbor.wace.me HARBOR_PROJECT: speefox_vexplor K8S_NAMESPACE: vexplor + + # 쿠버네티스 서버 SSH 접속 정보 + K8S_SSH_HOST: 112.168.212.142 + K8S_SSH_PORT: 22 + K8S_SSH_USER: wace # Frontend 빌드 환경 변수 NEXT_PUBLIC_API_URL: "https://api.vexplor.com/api" @@ -74,12 +79,7 @@ jobs: run: | echo "필수 도구 설치 중..." apt-get update -qq - apt-get install -y git curl ca-certificates gnupg - - # kubectl 설치 - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" - chmod +x kubectl - mv kubectl /usr/local/bin/ + apt-get install -y git curl ca-certificates gnupg openssh-client # Docker 클라이언트 설치 install -m 0755 -d /etc/apt/keyrings @@ -94,7 +94,7 @@ jobs: echo "설치 완료:" git --version - kubectl version --client + ssh -V docker --version export DOCKER_HOST=unix:///var/run/docker.sock @@ -180,100 +180,121 @@ jobs: docker push ${FRONTEND_FULL_IMAGE}:latest echo "Frontend 푸시 완료" - # Kubernetes 설정 - - name: Setup Kubernetes config + # SSH 키 설정 (쿠버네티스 서버 접속용) + - name: Setup SSH Key env: - KUBECONFIG_CONTENT: ${{ secrets.KUBECONFIG }} + SSH_KEY_CONTENT: ${{ secrets.K8S_SSH_KEY }} run: | - echo "Kubernetes 설정..." + echo "SSH 키 설정..." - if [ -z "${KUBECONFIG_CONTENT}" ]; then - echo "KUBECONFIG secret이 설정되지 않았습니다!" + if [ -z "${SSH_KEY_CONTENT}" ]; then + echo "K8S_SSH_KEY secret이 설정되지 않았습니다!" exit 1 fi - mkdir -p ~/.kube - echo "${KUBECONFIG_CONTENT}" | base64 -d > ~/.kube/config - chmod 600 ~/.kube/config + mkdir -p ~/.ssh + echo "${SSH_KEY_CONTENT}" | base64 -d > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa - if [ ! -s ~/.kube/config ]; then - echo "kubeconfig 파일이 비어있습니다" - exit 1 - fi + # known_hosts에 쿠버네티스 서버 추가 + ssh-keyscan -p ${K8S_SSH_PORT} ${K8S_SSH_HOST} >> ~/.ssh/known_hosts 2>/dev/null - echo "kubeconfig 파일 생성 완료" - kubectl cluster-info > /dev/null 2>&1 && echo "Kubernetes 클러스터 연결 성공" + # SSH 연결 테스트 + echo "SSH 연결 테스트..." + ssh -o StrictHostKeyChecking=no -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "echo 'SSH 연결 성공'" + echo "SSH 키 설정 완료" - # Kubernetes 배포 - - name: Deploy to Kubernetes + # k8s 매니페스트 파일을 쿠버네티스 서버로 전송 + - name: Transfer k8s manifests run: | - echo "Kubernetes 배포 시작..." - + echo "k8s 매니페스트 파일 전송..." cd /workspace/source - # 네임스페이스 생성 (없을 때만) + # 쿠버네티스 서버에 디렉토리 생성 + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "mkdir -p ~/vexplor-deploy/k8s" + + # k8s 파일 전송 + scp -P ${K8S_SSH_PORT} -r k8s/* ${K8S_SSH_USER}@${K8S_SSH_HOST}:~/vexplor-deploy/k8s/ + + echo "매니페스트 파일 전송 완료" + + # Kubernetes 배포 (SSH를 통해 원격 실행) + - name: Deploy to Kubernetes + env: + HARBOR_USER: ${{ secrets.HARBOR_USERNAME }} + HARBOR_PASS: ${{ secrets.HARBOR_PASSWORD }} + run: | + echo "Kubernetes 배포 시작 (SSH 원격 실행)..." + + # SSH를 통해 쿠버네티스 서버에서 kubectl 명령 실행 + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << 'DEPLOY_SCRIPT' + set -e + cd ~/vexplor-deploy + echo "네임스페이스 확인..." kubectl apply -f k8s/namespace.yaml - # ConfigMap 적용 echo "ConfigMap 적용..." - kubectl apply -f k8s/vexplor-config.yaml -n ${K8S_NAMESPACE} + kubectl apply -f k8s/vexplor-config.yaml -n vexplor # Secret 적용 (존재하는 경우에만) if [ -f k8s/vexplor-secret.yaml ]; then echo "Secret 적용..." - kubectl apply -f k8s/vexplor-secret.yaml -n ${K8S_NAMESPACE} + kubectl apply -f k8s/vexplor-secret.yaml -n vexplor fi - # Harbor Registry Secret 생성 (없을 때만) + echo "네임스페이스 및 ConfigMap 적용 완료" + DEPLOY_SCRIPT + + # Harbor Registry Secret 생성 (별도로 처리 - 환경변수 사용) echo "Harbor Registry Secret 확인..." - if ! kubectl get secret harbor-registry -n ${K8S_NAMESPACE} > /dev/null 2>&1; then - echo "Harbor Registry Secret 생성 중..." - kubectl create secret docker-registry harbor-registry \ - --docker-server=${HARBOR_REGISTRY_K8S} \ - --docker-username=${{ secrets.HARBOR_USERNAME }} \ - --docker-password=${{ secrets.HARBOR_PASSWORD }} \ - -n ${K8S_NAMESPACE} - echo "Harbor Registry Secret 생성 완료" - else - echo "Harbor Registry Secret 이미 존재" - fi + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl get secret harbor-registry -n vexplor" > /dev/null 2>&1 || \ + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl create secret docker-registry harbor-registry \ + --docker-server=${HARBOR_REGISTRY_K8S} \ + --docker-username=${HARBOR_USER} \ + --docker-password='${HARBOR_PASS}' \ + -n vexplor" + echo "Harbor Registry Secret 확인 완료" # Backend 배포 echo "Backend 배포..." - kubectl apply -f k8s/vexplor-backend-deployment.yaml -n ${K8S_NAMESPACE} + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << BACKEND_DEPLOY + set -e + cd ~/vexplor-deploy + kubectl apply -f k8s/vexplor-backend-deployment.yaml -n vexplor - if kubectl get deployment ${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} > /dev/null 2>&1; then - echo "Backend 이미지 업데이트..." - kubectl set image deployment/${BACKEND_DEPLOYMENT_NAME} \ - ${BACKEND_CONTAINER_NAME}=${BACKEND_FULL_IMAGE_K8S}:latest \ - -n ${K8S_NAMESPACE} - kubectl rollout restart deployment/${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} - fi + echo "Backend 이미지 업데이트..." + kubectl set image deployment/${BACKEND_DEPLOYMENT_NAME} \ + ${BACKEND_CONTAINER_NAME}=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${BACKEND_IMAGE_NAME}:latest \ + -n vexplor || true + kubectl rollout restart deployment/${BACKEND_DEPLOYMENT_NAME} -n vexplor echo "Backend Rolling Update 진행 중..." - kubectl rollout status deployment/${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} --timeout=5m + kubectl rollout status deployment/${BACKEND_DEPLOYMENT_NAME} -n vexplor --timeout=5m echo "Backend 배포 완료" + BACKEND_DEPLOY # Frontend 배포 echo "Frontend 배포..." - kubectl apply -f k8s/vexplor-frontend-deployment.yaml -n ${K8S_NAMESPACE} + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << FRONTEND_DEPLOY + set -e + cd ~/vexplor-deploy + kubectl apply -f k8s/vexplor-frontend-deployment.yaml -n vexplor - if kubectl get deployment ${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} > /dev/null 2>&1; then - echo "Frontend 이미지 업데이트..." - kubectl set image deployment/${FRONTEND_DEPLOYMENT_NAME} \ - ${FRONTEND_CONTAINER_NAME}=${FRONTEND_FULL_IMAGE_K8S}:latest \ - -n ${K8S_NAMESPACE} - kubectl rollout restart deployment/${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} - fi + echo "Frontend 이미지 업데이트..." + kubectl set image deployment/${FRONTEND_DEPLOYMENT_NAME} \ + ${FRONTEND_CONTAINER_NAME}=${HARBOR_REGISTRY_K8S}/${HARBOR_PROJECT}/${FRONTEND_IMAGE_NAME}:latest \ + -n vexplor || true + kubectl rollout restart deployment/${FRONTEND_DEPLOYMENT_NAME} -n vexplor echo "Frontend Rolling Update 진행 중..." - kubectl rollout status deployment/${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} --timeout=5m + kubectl rollout status deployment/${FRONTEND_DEPLOYMENT_NAME} -n vexplor --timeout=5m echo "Frontend 배포 완료" + FRONTEND_DEPLOY # Ingress 배포 echo "Ingress 배포..." - kubectl apply -f k8s/vexplor-ingress.yaml -n ${K8S_NAMESPACE} + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "cd ~/vexplor-deploy && kubectl apply -f k8s/vexplor-ingress.yaml -n vexplor" echo "전체 배포 완료!" @@ -281,22 +302,24 @@ jobs: - name: Verify deployment run: | echo "배포 검증..." + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} << 'VERIFY_SCRIPT' echo "" echo "Backend 상태:" - kubectl get deployment ${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} - kubectl get pods -l app=${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} + kubectl get deployment vexplor-backend -n vexplor + kubectl get pods -l app=vexplor-backend -n vexplor echo "" echo "Frontend 상태:" - kubectl get deployment ${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} - kubectl get pods -l app=${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} + kubectl get deployment vexplor-frontend -n vexplor + kubectl get pods -l app=vexplor-frontend -n vexplor echo "" echo "Services:" - kubectl get svc -n ${K8S_NAMESPACE} + kubectl get svc -n vexplor echo "" echo "Ingress:" - kubectl get ingress -n ${K8S_NAMESPACE} + kubectl get ingress -n vexplor echo "" echo "검증 완료" + VERIFY_SCRIPT # 배포 요약 - name: Deployment summary @@ -315,8 +338,8 @@ jobs: if: failure() run: | echo "배포 실패! 이전 버전으로 롤백..." - kubectl rollout undo deployment/${BACKEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} || true - kubectl rollout undo deployment/${FRONTEND_DEPLOYMENT_NAME} -n ${K8S_NAMESPACE} || true + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl rollout undo deployment/vexplor-backend -n vexplor" || true + ssh -p ${K8S_SSH_PORT} ${K8S_SSH_USER}@${K8S_SSH_HOST} "kubectl rollout undo deployment/vexplor-frontend -n vexplor" || true # Harbor 로그아웃 - name: Logout from Harbor